<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Networking on Sidequesting</title><link>https://example.com/categories/networking/</link><description>Recent content in Networking on Sidequesting</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>©2026</copyright><lastBuildDate>Sat, 21 Mar 2026 18:02:36 +0900</lastBuildDate><atom:link href="https://example.com/categories/networking/index.xml" rel="self" type="application/rss+xml"/><item><title>Agentic Workflow as of October 2026</title><link>https://example.com/posts/agentic/workflows/rev1/</link><pubDate>Sun, 18 Oct 2026 11:32:06 -0400</pubDate><guid>https://example.com/posts/agentic/workflows/rev1/</guid><description>&lt;h1 id="tldr"&gt;tl;dr:&lt;/h1&gt;
&lt;p&gt;This post describes my first current very rough approach to agentic development.
This approach is heavy on docs, folder structure, and copious tools and scripts for verification feedback.&lt;/p&gt;
&lt;p&gt;My current approach is codified by the &lt;a href="https://github.com/0xNF/wtstandardrepo"target="_blank" rel="noopener noreferrer"&gt;Winetech Standard Repo&lt;/a&gt;, which is a barebones skeleton of the structure and built-in agent ready documentation to get started on a new project.&lt;/p&gt;
&lt;h2 id="actual-take-aways"&gt;Actual Take-Aways&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Use ADRs&lt;/li&gt;
&lt;li&gt;Prune memories, AGENTS.md, and other context-filling documents regularly&lt;/li&gt;
&lt;li&gt;Provide a space to put observations found during their tasks so don&amp;rsquo;t get distracted and information doesn&amp;rsquo;t get lost&lt;/li&gt;
&lt;li&gt;Keep as much inside the repo as possible, to provide agents with the context on demand that they need&lt;/li&gt;
&lt;li&gt;Provide tools and scripts that can give negative feedback to the agents so they can quickly course-correct on their own&lt;/li&gt;
&lt;li&gt;Give them a runtime of your application to test against in a live setting. Static analysis is not enough.&lt;/li&gt;
&lt;/ul&gt;
&lt;details class="toc" open&gt;&lt;summary&gt;Table of Contents&lt;/summary&gt;&lt;nav id="TableOfContents"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#tldr"&gt;tl;dr:&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#actual-take-aways"&gt;Actual Take-Aways&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#prerequisites"&gt;Prerequisites&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#models"&gt;Models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#harnesses"&gt;Harnesses&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#subscriptions"&gt;Subscriptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#project-ownership"&gt;Project Ownership&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#folder-structure"&gt;Folder Structure&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#adr"&gt;&lt;code&gt;adr/&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#investigations"&gt;&lt;code&gt;investigations/&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#tickets"&gt;&lt;code&gt;tickets/&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#backlogmd"&gt;&lt;code&gt;backlog.md&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#verification-and-feedback"&gt;Verification and Feedback&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#repo-tools"&gt;Repo Tools&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#agentsmd-and-memories"&gt;AGENTS.md and Memories&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#agentsmd"&gt;AGENTS.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#memories"&gt;Memories&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#skills"&gt;Skills&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#pruning-files-when-they-get-too-big-or-outdated"&gt;Pruning files when they get too big or outdated&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#working-with-the-agents"&gt;Working with the Agents&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#prompting-style"&gt;Prompting Style&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#corrections"&gt;Corrections&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#lean-into-their-biases-and-expectations-for-tools-and-docs"&gt;Lean into their biases and expectations for tools and docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#hooks-and-notifications"&gt;Hooks and notifications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#parallelization"&gt;Parallelization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#some-usage-patterns"&gt;Some Usage Patterns&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#wrap-up"&gt;&amp;ldquo;Wrap up&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#handoff-documents"&gt;Handoff Documents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#rewrite-to-be-forward-looking"&gt;Rewrite To Be Forward Looking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#team-a-vs-team-b"&gt;Team A vs Team B&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#recent-worked-examples"&gt;Recent Worked Examples&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#reducing-token-spend-on-backtracking-during-failed-test-runs"&gt;Reducing Token Spend on Backtracking during Failed Test Runs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#test-suite-optimization"&gt;Test Suite Optimization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#automation-and-accessibility"&gt;Automation and Accessibility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#migrating-a-failing-robotics-sample-from-gazebo-to-mujoco"&gt;Migrating a Failing Robotics Sample From Gazebo to MuJoCo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/nav&gt;&lt;/details&gt;
&lt;h1 id="prerequisites"&gt;Prerequisites&lt;/h1&gt;
&lt;p&gt;People get different results from the different workflows, tools, models and harnesses they use, so I&amp;rsquo;d like to set out what my particular set up looks like at the outset, so you can adjust your own expectations.&lt;/p&gt;
&lt;h2 id="models"&gt;Models&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Big Models
&lt;ul&gt;
&lt;li&gt;(Primary) Claude Opus 5.5 (xhigh)&lt;/li&gt;
&lt;li&gt;(Secondary) GPT Sol 6.1 (xhigh)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Fast
&lt;ul&gt;
&lt;li&gt;(Primary) Claude Sonnet 5.5 (medium)&lt;/li&gt;
&lt;li&gt;(Secondary) GPT Terra 6.1 (medium)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have previously experimented with Mistral, and have only heard good things but not yet tried DeepSeek, GLM, or Kimi.&lt;/p&gt;
&lt;h2 id="harnesses"&gt;Harnesses&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Claude Code&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/can1357/oh-my-pi"target="_blank" rel="noopener noreferrer"&gt;OhMyPi&lt;/a&gt; (omp).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Be aware that I live 90% of the time in VSCode, so I also use the the &lt;a href="https://marketplace.visualstudio.com/items?itemName=anthropic.claude-code"target="_blank" rel="noopener noreferrer"&gt;Claude Code Visual Studio Extenstion&lt;/a&gt; which I like because I can have rich markdown and code editing support side by side with the LLM output, like this:&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/img/agentic/workflows/rev1/vscode_claudecode_1.png"
alt="VS Code&amp;rsquo;s integration side by side with Claude Code"/&gt;&lt;/p&gt;
&lt;p&gt;However, I also like &lt;em&gt;omp&lt;/em&gt; because it has Language Server support built in, so it can do really efficient and thorough symbol renames, etc.&lt;/p&gt;
&lt;p&gt;Because Anthropic doesn&amp;rsquo;t permit using their Max subscriptions in other harnesses, &lt;em&gt;omp&lt;/em&gt; only get used when I need to use OpenAI&amp;rsquo;s models.&lt;/p&gt;
&lt;h2 id="subscriptions"&gt;Subscriptions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Anthropic Teams Max Subscription&lt;/li&gt;
&lt;li&gt;OpenAI GPT pay-as-you-go pricing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because of this set up, I prefer Claude because my usage is much less restricted. However, due to Anthropic&amp;rsquo;s removal of some &amp;ldquo;bonus tokens&amp;rdquo; they&amp;rsquo;ve been giving out for a while, I am now routinely getting rate limited around Thursday, so it&amp;rsquo;s become common for me to end my week in &lt;em&gt;omp&lt;/em&gt; with GPT Sol.&lt;/p&gt;
&lt;h2 id="project-ownership"&gt;Project Ownership&lt;/h2&gt;
&lt;p&gt;I largely possess autonomous control over how I approach my repositories, so I can structure them however I choose. The descriptions below may not be feasible in your own setups, due to team size, code review requirements, managerial processes, etc. But maybe some of the things herein can still be useful.&lt;/p&gt;
&lt;h1 id="folder-structure"&gt;Folder Structure&lt;/h1&gt;
&lt;p&gt;LLMs love to have context, and to have on-demand access to even more context, so I have a folder structure with some initial files that supports their access patterns, and it has been working for me so far.&lt;/p&gt;
&lt;p&gt;I won&amp;rsquo;t explain it in full here, but you should check out my &lt;a href="https://github.com/0xNF/wtstandardrepo"target="_blank" rel="noopener noreferrer"&gt;Winetech Standard Repo&lt;/a&gt;, which lays out much of how I&amp;rsquo;ve started to structure my repositories these days.&lt;/p&gt;
&lt;p&gt;In brief, it takes the following shape:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── docs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   ├── repo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   ├── adr
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   │   └── 0000-adr-format.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   ├── investigations
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   │   └── README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   ├── misc
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   │   ├── architecture.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   │   ├── debugging.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   │   ├── history.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   │   └── README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   ├── plans
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   │   ├── inprogress
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   │   ├── README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   │   └── unimplemented
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   │   └── backlog.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   └── workflows
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   └── README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   ├── tickets
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   │   └── README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   └── vendored
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   └── README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── repotools
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├── public
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │   ├── go
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │   ├── python
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │   └── rust
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └── README.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each folder gets a README.md explaining its purpose, and what it&amp;rsquo;s subfolders are for. For example, here is the main &lt;code&gt;docs/README.md&lt;/code&gt; file, abbreviated for including in this post:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# Docs
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;The front door to a project&amp;#39;s documentation. It says what lives where and points to the separate rules file and the scripts README.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Vendored documentation is available in &lt;span class="sb"&gt;`vendored/`&lt;/span&gt;, so that agents don&amp;#39;t have to go to the Web to learn about the details of their dependencies.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Main documents
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Standalone reference documents, listed in a table: a map of the system as it is, a symptom-first debugging index, a history of what was removed and why, rules for code that must survive a special compile step, a design and style guide, and an end-user guide that may lag the code.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Workflows
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Step-by-step procedures, one file per recurring task. They cover building and testing, running and driving the app, reading logs, releasing, and querying a local backend. They also cover guides for risky kinds of change and one page per automated check script.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Architecture decision records
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;A numbered log of significant choices currently in force, each with its context, alternatives and consequences. Records are edited, replaced or deleted, never marked &amp;#34;superseded&amp;#34;. Reversed designs go in the history document.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Plans
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Work in flight, written when work starts and deleted when it ends. One standing backlog collects problems noticed in passing, so they get recorded rather than fixed unprompted.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Investigations
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;One folder per problem whose cause is still unknown. It holds the symptom, dated observations, open and ruled-out causes, and next steps. It is deleted in the same commit as the fix.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Tickets
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Defects and requests for code owned by other teams, filed one per file by owning component. Each ticket carries a priority (High, Medium or Low), a category, a validity note and verification evidence, and checks must not damage shared test environments.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each header is important in its own right, but I want to note that I have gotten a disproportionate amount of value from the following items in particular:&lt;/p&gt;
&lt;h2 id="adr"&gt;&lt;code&gt;adr/&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;I took this from a Hacker News post a few months ago, and although I&amp;rsquo;m using the traipsings of Architecture Decision Records, I am using my own, perhaps cursed, flavor of them. I have dropped the &lt;code&gt;status&lt;/code&gt; portion, because in my world, they&amp;rsquo;re always &lt;code&gt;accepted&lt;/code&gt;, and my standing rule is that they are always edited-in-place, never obsoleted. If an ADR exists in the repo, it is an active document.&lt;/p&gt;
&lt;p&gt;I use them to record bite-sized facts about the repo in question. Here are a sample of ADRs in a few projects I am working with right now:&lt;/p&gt;
&lt;p&gt;These are from a C# desktop application:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;0002 — Layered MVVM application architecture
0005 — Use NotifyingObject for change notification
0024 — A message is a copyable dialog or a toast, and every message is kept
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is an AWS deployment:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;0001 — OpenTofu for Infrastructure Provisioning
0008 — Layered Internal PKI: Offline Root + Online step-ca Intermediate + Short-Lived Auto-Renewed Certs
0012 — OpenVPN, IPv6-Only Split-Tunnel, Certificate-Only, tls-crypt-v2 Hardened
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and it goes on like this. You can reference my standard &lt;a href="https://github.com/0xNF/wtstandardrepo/blob/master/docs/repo/adr/0000-adr-format.md"target="_blank" rel="noopener noreferrer"&gt;ADR baseline document&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Because these ADRs are routinely referenced by the models, I endeavor to keep irrelevant information, like history, out of them. History is still important to maintain, so it goes into its own dedicated &lt;code&gt;history.md&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;The models really do reference ADRs all the time, and its been such a superpower that keeps them on track and consistent. It also catches inconsistencies in my requests, where the models will tell me that my own decision contradicts ADR #XYZ, which is a good moment for me to reflect on what I really want from a given session.&lt;/p&gt;
&lt;p&gt;ADRs are not considered static &amp;ndash; I edit them in place, and occasionally delete, reorganize, or adjust them as needed.&lt;/p&gt;
&lt;h2 id="investigations"&gt;&lt;code&gt;investigations/&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Sometimes a problem is found during a session, like an intermittent crash. It is helpful to provide the agent a place to put repeated observations of an issue along with a summary of the issue in the investigations README file. Once enough observations have been logged, it becomes its own dedicated session and can be used as the starting point for a full-on investigation. The benefit of doing it this way is that the agent won&amp;rsquo;t get distracted during a session, can recognize known failures, and eventually can work on this one problem full-time.&lt;/p&gt;
&lt;p&gt;here are some example ongoing investigations I have open in one of my desktop applications:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─── action-editor-hangs-on-load-and-selection
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├─── studio-fails-fast-returning-to-actions-list
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└─── studio-process-outlives-its-window
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; README.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And a brief excerpt of what one such README looks like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# Studio&amp;#39;s process can outlive its window and hold the layout
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gs"&gt;**Status: open.**&lt;/span&gt; Seven sightings of a stuck exit or windowless process between 2026-10-03 and 2026-10-18, and four timed closes on 2026-10-07 that did not reproduce it. The cause is not known. The leading candidate is a clipboard flush at exit, and it has not been tested. A fifth sighting, on 2026-10-09, was a start that failed and never exited, which has a known cause of its own.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## The symptom
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;A Studio the user has closed stays alive with no window anyone knows of and one thread left, waiting in the kernel (state Wait, reason UserRequest). While it lives it holds the layout: refreshing it fails on &lt;span class="sb"&gt;`gs.dll`&lt;/span&gt; (robocopy exit 10), and &lt;span class="sb"&gt;`Add-AppxPackage -Register`&lt;/span&gt; fails with &lt;span class="sb"&gt;`0x80073D02`&lt;/span&gt;. Nothing on screen says why.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Observations
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| Sighting | Started | Remote Desktop | Copy before close | Threads, handles, memory | Exit code | Dump |
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| -------- | ---------------------------- | -------------- | ----------------- | ------------------------ | --------- | ---- |
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;| 1 | 2026-10-03, how not recorded | not recorded | not recorded | 1, 918, 237 MB | not read | none |
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### Sighting 1 -- 2026-10-03: alive eight minutes after its close
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;A Studio the user closed stayed alive for more than eight minutes.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Candidates
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### Ruled out
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[...]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;### Open
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[...]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="tickets"&gt;&lt;code&gt;tickets/&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Tickets are where defects, feature requests, and larger behavioral changes go. I have outstanding instructions for agents to create tickets for items they&amp;rsquo;ve found during their sessions into this folder. The subfolder structure is less defined, but I currently have them organized by owner. For example, big items that are found in &lt;em&gt;this repository&lt;/em&gt; are placed into &lt;code&gt;$projectName/&lt;/code&gt;, while defects found in, for example, the backend repo thats owned by another team, goes in &lt;code&gt;dependencyName/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── desktop_app/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   ├── camera-reset-keeps-selected-profile.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   └── maintenance-max-log-days-drifts-on-disk.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── upstream_dep1/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│   └── trigger-condition-schema-disagrees-with-the-hub.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── README.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The structure of my tickets here are also fluid, but I&amp;rsquo;m currently using this format for a ticket:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Reset leaves one setting in place
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Assessment
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **Priority:** Medium
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **Category:** Correctness
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **Validity:** Confirmed
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **Assessed:** &amp;lt;date&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **Basis:** Reset promises the default state but keeps a manually chosen setting, so a bad choice can&amp;#39;t be undone by resetting. Picking &amp;#34;Auto&amp;#34; explicitly still works as a workaround.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; **Verification:** Confirmed by reading the source: the reset path applies defaults to every field except this one, and the code that reads the setting still honors any stored value. The API docs describe reset as a full restore with no exceptions. Not reproduced live, since no test device was in the required state.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;what the upstream system does:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Reset restores most fields to their defaults but skips one. A device pinned
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; to a manual setting comes back from a reset still pinned, while every other
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; field in the response is a default.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;what we need:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Reset should clear that setting too, so the result matches a fresh
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; registration. If that isn&amp;#39;t wanted, the docs should say it&amp;#39;s deliberately
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; excluded.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;impact:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; A device pinned to a setting that no longer exists can&amp;#39;t be recovered by
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; resetting it. It keeps failing, and the reset control reports success
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; without touching the field that matters.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;evidence:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; The default-setting function covers six fields and omits this one. It&amp;#39;s
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; called from the reset handler. Other device types have no equivalent
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; setting, so only this type is affected.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;workaround on our side:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; None. The UI redraws from the reset response, so it shows the setting that
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; survived instead of hiding it. Users can still select Auto and save, which
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; does clear it.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;once fixed, on our side:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Nothing. The UI already renders whatever the response carries, so it will
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; show Auto on its own.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The categories I&amp;rsquo;m using belong to the set of&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[Usability, Security, Correctness, Misc, Feature]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Occasionally I will request the agents go through each filed ticket and re-assess whether it&amp;rsquo;s still true or not.
The purpose of this ticket structure is that it outlines clearly why this is an issue, and what this current repo is doing to work around it.&lt;/p&gt;
&lt;h2 id="backlogmd"&gt;&lt;code&gt;backlog.md&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;One item I&amp;rsquo;ve gotten a disproportionate amount of value from is the backlog.md file, which is the scratch space I provide to agents for them to put down small bugs, discrepencies, or things that need adjustment. This is similar to tickets, and indeed, until I decided that the tickets folder should also include the repo itself, is where feature requests and large changes went into. But after separating the two, this file is still very useful.&lt;/p&gt;
&lt;p&gt;When an agent is working, it will often encounter problems. Depending on the agent, it may get distracted trying to solve them, or it may just forget about the issue by the end of the session. To make sure that this information isn&amp;rsquo;t lost, they have standing orders to note any such defects into the backlog.md file immediately, and then to continue the main assigned work. This keeps them on task, and ensures that I have a decent accounting of bugs in my code.&lt;/p&gt;
&lt;p&gt;Not everything they put in is necessary, so it is worthwhile to manually prune the file from time to time, but by and large, the defects that Claude and GPT find have been worth addressing.&lt;/p&gt;
&lt;p&gt;The format of my backlog file is like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# Code cleanup backlog
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Things found while working on something else: dead code, latent defects, and behaviour that looks wrong but was left alone because fixing it was outside the change at hand. Nothing here is blocking. Each entry is a decision for the user, not a task already agreed.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gs"&gt;**Add to this file rather than fixing in passing.**&lt;/span&gt; When a change turns up an unrelated problem - an unreachable class, a notification that reaches nobody, a leak, a binding that has never worked - write it down here and carry on with the change you were making. Say what it is, where it is, what it costs to leave, and what fixing it would change. If you do fix one, delete it from this file.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# Methodology
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; Consider breaking tasks into sub-tasks
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; You have a dev deployment of the application on this box and permission to use and modify it;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;-&lt;/span&gt; [...]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# Backlog
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Release dependencies report unresolved trim and AOT analysis warnings
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;The 2026-10-16 x64 &lt;span class="sb"&gt;`just build aot`&lt;/span&gt; run succeeds but reports IL2104 for &lt;span class="sb"&gt;`WinUI.TableView`&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sb"&gt;`Common.Logging`&lt;/span&gt;, &lt;span class="sb"&gt;`Microsoft.Data.SqlClient`&lt;/span&gt;, &lt;span class="sb"&gt;`Microsoft.Data.SqlClient.Internal.Logging`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;and &lt;span class="sb"&gt;`System.Configuration.ConfigurationManager`&lt;/span&gt;, and IL3053 for &lt;span class="sb"&gt;`Microsoft.Data.SqlClient`&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ILC also says &lt;span class="sb"&gt;`Makaretu.Dns.LinuxHelper.ReuseAddresss(Socket)`&lt;/span&gt; always throws because
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sb"&gt;`Tmds.LibC`&lt;/span&gt; cannot be loaded. No runtime failure was observed from these diagnostics; leaving
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;them unresolved makes the Release build&amp;#39;s analysis inconclusive for those dependency paths.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Triage would inspect the detailed ILC diagnostics, determine which paths the Windows client
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;can reach, and update or root the affected dependencies rather than suppressing the summaries.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[...]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;ve found that the agents are exceptional at filling in this file, and on later dedicated passes, are equally exceptional at churning through it.&lt;/p&gt;
&lt;p&gt;Many ADR discrepancies, usability problems, and bad bugs have been found this way, all without the agent getting distracted.&lt;/p&gt;
&lt;h1 id="verification-and-feedback"&gt;Verification and Feedback&lt;/h1&gt;
&lt;p&gt;Agents work really well when they can correct their own assumptions in real-time. They react very well to negative feedback when they try something, such as compile-time failures or other errors that show them they had something incorrect.&lt;/p&gt;
&lt;p&gt;You should encourage this by building and supplying tools that the agent can call. This can be as simple as supplying the language server for it to see diagnostic information in, or as complex as a custom constellation of scripts that do work in advance. For instance, in a desktop application, I have a series of scripts that check for banned APIs, or that certain structures aren&amp;rsquo;t used:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── check-serialization-contracts.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── check-source-rules.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── check-tooltips.ps1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── check-window-ownership.ps1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Among many others. The tools provide output like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="m"&gt;2&lt;/span&gt; failed:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Invalid API: src/models/ModelA.cs:76
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;{&lt;/span&gt;Binding&lt;span class="o"&gt;}&lt;/span&gt; instead of &lt;span class="o"&gt;{&lt;/span&gt;x:Bind&lt;span class="o"&gt;}&lt;/span&gt;: src/views/LogView.xaml:862
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;which tell the model where one of its assumptions went wrong, and what it needs to correct before continuing.&lt;/p&gt;
&lt;h2 id="repo-tools"&gt;Repo Tools&lt;/h2&gt;
&lt;p&gt;In addition to tools that provide feedback, it&amp;rsquo;s also useful to supply tools that give functionality that the agents keep writing for themselves.
For instance, I noticed that the agents kept ad-hoc writing scripts to uninstall and reinstall an application, so instead of letting it waste tokens, and each time doing it slightly differnetly, I gave it a script that does it, consistently, every time. Now it knows to call &lt;code&gt;install_newest.ps1&lt;/code&gt; and it will wait for it to finish before continuing.&lt;/p&gt;
&lt;p&gt;It pays to pay attention to what the agents are doing, to work alongside them.&lt;/p&gt;
&lt;h1 id="agentsmd-and-memories"&gt;AGENTS.md and Memories&lt;/h1&gt;
&lt;p&gt;A good AGENTS.md (née CLAUDE.md) file is mandatory for giving agents the initial overview and philosophy of your repository. Everyone knows this, so i won&amp;rsquo;t spend much time on it here.&lt;/p&gt;
&lt;h2 id="agentsmd"&gt;AGENTS.md&lt;/h2&gt;
&lt;p&gt;In my case, my AGENTS.md contains things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a brief overview of what this repo hopes to accomplish&lt;/li&gt;
&lt;li&gt;The toolchain used for building and deployment, with references to &lt;code&gt;building.md&lt;/code&gt; for details&lt;/li&gt;
&lt;li&gt;The style guidelines with references to &lt;code&gt;style.md&lt;/code&gt; and &lt;code&gt;adr/&lt;/code&gt; for details&lt;/li&gt;
&lt;li&gt;The instructions for code backlog, ticketing, and investigations, with references to the appropriate README.md files&lt;/li&gt;
&lt;li&gt;Other tools available on this dev box, like whether Python, ffmpeg, curl, imagemagick, etc are available&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="memories"&gt;Memories&lt;/h2&gt;
&lt;p&gt;The purpose of memories, as distinct from AGENTS.md or specific repo tooling is that it is meant to represent things that are not globally applicable.&lt;/p&gt;
&lt;p&gt;Agents will often collect memories on their own, but sometimes its useful when you see persistent errors being made to encourage them to create memories under your guidance. Since I do a lot of work on Windows, and Agents have a not-unreasonable expectation that they&amp;rsquo;re in UNIX-land, I have make sure they have memories that relate to setting BOMs, and that the editors they often use eat backslashes and need different escaping rules.&lt;/p&gt;
&lt;p&gt;I also use memories to give agents standing permission to do code commits, to make changes to the running development system, where to find temporary data, and what other nearby relevant repositories and documents are located that may be useful for the agent to be aware of.&lt;/p&gt;
&lt;p&gt;These things are not global, and not applicable to other developers on this repository, so it&amp;rsquo;s not appropriate to put them into the repo-permanent AGENTS.md.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A side note: It &lt;em&gt;is&lt;/em&gt; permissible to make tooling around these specific assumptions by using the &lt;code&gt;repotools/$username/&lt;/code&gt; folders, which is where developer specific tooling should go. There is no expectation that tools under your own folder are useful, or indeed even run, under any other user. Repo-wide tools should graduate into the &lt;code&gt;repotools/public/&lt;/code&gt; folder.&lt;/p&gt;
&lt;p&gt;This is why I think there&amp;rsquo;s a large synergy to be had with the repo tools folder in an agentic setting.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="skills"&gt;Skills&lt;/h2&gt;
&lt;p&gt;I have not generally found skills to be very useful. I have nothing in particular to write here on the subject.&lt;/p&gt;
&lt;h2 id="pruning-files-when-they-get-too-big-or-outdated"&gt;Pruning files when they get too big or outdated&lt;/h2&gt;
&lt;p&gt;Token budgets are not unlimited, and context size must be managed. To that end, one must on occasion revisiting the files you are asking the agents to work with on every request.&lt;/p&gt;
&lt;p&gt;AGENTS.md should be kept under &lt;code&gt;10,000&lt;/code&gt; tokens, and even that is pushing it. Remember that this is sent on every request. It is worth looking at what needs to be understood all the time, versus what only needs to be understood some of the time, versus what doesnt need to be understood at all.&lt;/p&gt;
&lt;p&gt;If assumptions are outdated or have conflicting instructions, delete them. If things only apply some of the time, extract those sections to their own ADR or Workflow documents, and then put a reference in instead.&lt;/p&gt;
&lt;p&gt;As simple as it can get, but no simpler.&lt;/p&gt;
&lt;p&gt;The same rules apply for your memory files, which can be found under &lt;code&gt;~/.claude/projects/$project/memory&lt;/code&gt;, or other similar harness-dependent locations.&lt;/p&gt;
&lt;p&gt;Condense, Extract, Delete.&lt;/p&gt;
&lt;h1 id="working-with-the-agents"&gt;Working with the Agents&lt;/h1&gt;
&lt;p&gt;(LLM, Harness) pairs have their own runtime quirks and should be worked with the way a craftsman knows how to work with a power-drill that whirls in one direction faster than the other, a hammer that isn&amp;rsquo;t perfectly flat and thus has slight directional preference, or a car that has a very delicate accelerator. The quirks are worth learning and using to your advantage. Don&amp;rsquo;t fight the agents, work with them.&lt;/p&gt;
&lt;h2 id="prompting-style"&gt;Prompting Style&lt;/h2&gt;
&lt;p&gt;Because I have what I consider to be fairly well crafted initial documents and on-demand context available for the agents, I don&amp;rsquo;t put too much effort into my prompts, which are concise and minimal.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Read this $document, and address the issues&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Fix the bugs described by the cleanup&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Continue working on this plan file&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Except in rare circumstances, I don&amp;rsquo;t write any additional context, because I&amp;rsquo;ve already given the context in the AGENTS.md, ADRs, and plan files.&lt;/p&gt;
&lt;p&gt;Sometimes I have questions that require a more thorough examination before we can continue:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Examine the feasibility of adding the following feature to this application, and consider how many dependencies it would require to accomplish&lt;/li&gt;
&lt;li&gt;We are currently doing $X in our application, but I want to move to $Y instead, write a plan file for this process&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have found it productive to speak in mechanical, precise terminology. I do not abridge my requests, use shorthand slang, or speak casually with the agents. I do my best to give them accurate and clear phrases to work with. It helps to orient their initial manifolds when you say things like &amp;ldquo;Consider ahead-of-time compilation issues&amp;rdquo;, or &amp;ldquo;profile this slowdown and find whether a different algorithm should be used for this subroutine&amp;rdquo;, instead of &amp;ldquo;why is it slow&amp;rdquo; or &amp;ldquo;u should find the bug&amp;rdquo;. LLMs are often reflections of the tone and skill of the user prompt, and if you are sloppy in your input you will find it is sloppy in its&amp;rsquo; output.&lt;/p&gt;
&lt;h2 id="corrections"&gt;Corrections&lt;/h2&gt;
&lt;p&gt;Sometimes the Agents are confident in their assertion that some things cannot be done. It may be the case that you know better than they do - in those situations it is important to supply them with relevant documentation, at which point they will happily change course and begin working.&lt;/p&gt;
&lt;p&gt;Remember that they have cut-off dates for their training, so they will only recall information up to that point. Any change in status of something that happened after that date needs to be supplied to them.&lt;/p&gt;
&lt;h2 id="lean-into-their-biases-and-expectations-for-tools-and-docs"&gt;Lean into their biases and expectations for tools and docs&lt;/h2&gt;
&lt;p&gt;Like said above, LLMs have quirks, biases and expectations, If you watch them long enough you&amp;rsquo;ll pick up this fact because you&amp;rsquo;ll see them say things like &amp;ldquo;That API doesn&amp;rsquo;t exist, I&amp;rsquo;ll try a different one&amp;rdquo;, or &amp;ldquo;Turns out ffmpeg isn&amp;rsquo;t found on this machine, so I&amp;rsquo;ll write a small script in python instead&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;These are opportunities to do two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make your token usage more efficient&lt;/li&gt;
&lt;li&gt;Make your tools better&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Every time they backtrack on a choice is tokens that you&amp;rsquo;re spending, time you&amp;rsquo;re wasting, and context you&amp;rsquo;re eating up. Not all situations are equal, but on balance, you should consider adding what they&amp;rsquo;re expecting to your tools and your environment. They will be more competent in their tasks when they have what they want without the fuss of trying to work around it. They are also trained on those aspects, so they&amp;rsquo;ll be good at using them.&lt;/p&gt;
&lt;p&gt;Additionally, especially when it comes to API surfaces, misaligned expectations are a solid indicator that your API design is lacking in crucial ways. If your agent is making these mistakes, other people&amp;rsquo;s agents are also making the same mistake. And human users may also be under same misapprehension. It is worth considering deeply whether the design the agents expected is actually a better design &amp;ndash; very often, it is.&lt;/p&gt;
&lt;h3 id="a-brief-methodology"&gt;A brief methodology&lt;/h3&gt;
&lt;p&gt;I recently went through my Claude session transcripts of the past month with another agent (GPT-Luna-6.1 via &lt;em&gt;omp&lt;/em&gt; because I was at my weekly Claude token limit at that time) with the instructions to:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Read these session transcripts and find instances where the agent got confused, backtracked, realized a tool or program was missing, or used an API with an incorrect shape&amp;rdquo;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The results were a useful set of places to start working some immediate remediation candidates. I was able to update a handful of checker scripts in the repo, and also file some tickets against a sister repository for improvements this way. Here are some samples of what that scan turned up, and the resolution I opted for.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;-&lt;/span&gt; Expected: ffmpeg to be installed to change the encoding a screenshot
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;-&lt;/span&gt; Actual: not installed, wrote a python script to adjust the encoding by hand.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;Resolution: install ffmpeg
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;-&lt;/span&gt; Expected: The same test date could be reused across pages.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;-&lt;/span&gt; Actual: The user clarified that Data Viewer needed September to get real data.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;Resolution: Add a script that seeds test data before certain diagnostic runs
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;-&lt;/span&gt; Expected: gsdrive can resize windows and click any named UI control.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;-&lt;/span&gt; Actual: It had no resize verb, resized by using pointer and click APIs manually.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;&amp;gt; &lt;/span&gt;&lt;span class="ge"&gt;Resolution: Added a `resize` verb to the automation tooling
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="hooks-and-notifications"&gt;Hooks and notifications&lt;/h2&gt;
&lt;p&gt;Agent harnesses have started to support &lt;a href="https://code.claude.com/docs/en/hooks"target="_blank" rel="noopener noreferrer"&gt;Hooks&lt;/a&gt;, which are a standard concept, just applied to this new tech.
Because I do most of my work in a Windows VM through a Linux host, and a lot of these tasks are long running, I am often delayed in returning to a session to assess output or answer questions. To address that problem, I built a &lt;a href="https://github.com/0xNF/vm_llm_notify"target="_blank" rel="noopener noreferrer"&gt;KDE taskbar widget&lt;/a&gt; that receives hooks from Claude Code. The taskbar widget lights up whenever an inner VM session is waiting for my assessment:&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://github.com/0xNF/vm_llm_notify/raw/master/llm_notify.gif"
alt="KDE taskbar app that lights up when Claude requires attention"/&gt;&lt;/p&gt;
&lt;h2 id="parallelization"&gt;Parallelization&lt;/h2&gt;
&lt;p&gt;Sometimes I want to get multiple things done in one repo, and don&amp;rsquo;t want to wait for a single agent to churn through the tasks sequentially.
If I have a set of tasks that I think are decent candidates for doing in parallel, as in, they touch different files and wont step on each other&amp;rsquo;s work, I open multiple panes of Claude Code and set them to their tasks. The first thing I writ in these prompts is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You are working in parallel with other agents in the same checkout of this git repo. Coordinate with each other as you work.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I don&amp;rsquo;t know about other harnesses, but for Claude Code, this works very well. The agents will then Post and Receive messages to each other, sharing their file lists, seeing who has the next build pipeline and if they can piggyback off it, taking turns driving the application test suites, and generally doing a good job together. In extreme cases the agents will often decide to make a new git worktree and rebase their changes onto the main delegate branch.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve found that I only have the mental capacity to kepe track about 4 agents at once, after that I begin to lose the ability to keep accurate tabs on their motion, and risk each agent going a bit off the rails.&lt;/p&gt;
&lt;h1 id="some-usage-patterns"&gt;Some Usage Patterns&lt;/h1&gt;
&lt;p&gt;Here are some patterns of interaction I have and employ with this generation of agents.&lt;/p&gt;
&lt;h2 id="wrap-up"&gt;&amp;ldquo;Wrap up&amp;rdquo;&lt;/h2&gt;
&lt;p&gt;This seems to be a keyword that the frontier models are highly trained on. &amp;ldquo;Wrap up&amp;rdquo; means to them that they should finish their work in a good stopping place, and relinquish their turn. Eager agents that normally consume work items will pause, tidy up their solution, run one final test suite, and then leave the turn for the user. This is very useful in combination with the next item, the handoff document.&lt;/p&gt;
&lt;h2 id="handoff-documents"&gt;Handoff Documents&lt;/h2&gt;
&lt;p&gt;When context starts getting too packed, especially on long-running tasks that require sustained attention, I ask the agent to wrap up and produce a handoff document.&lt;/p&gt;
&lt;p&gt;Handoff documents were a concept pioneered by the local agent harness crowd like the Pi harness, and has started to see adoption in other harnesses.&lt;/p&gt;
&lt;p&gt;The idea is that the this agent will stop working, and a new, fresh agent will pick up the work. We don&amp;rsquo;t want to start with the main plan file, which has too much context, and has an unclear current-position. The handoff document exists in tandem with the plan file and represents the current state of the implementation, plus what a new agent needs to to know to immediately pick up the work where it was left off.&lt;/p&gt;
&lt;p&gt;n conjunction with the &lt;code&gt;plans/&lt;/code&gt; folder from the above folder structure, a simple, sequential use of agents will produce a raw &lt;code&gt;handoff.md&lt;/code&gt; file in the &lt;code&gt;plan/&lt;/code&gt; directory, and a complicated plan will get its own dedicated folder with its own handoff document.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;handoff.md&lt;/code&gt; is a very temporary file, and is either constantly being rewritten depending on how extensive and token-intensive the task is, or just straight up deleted when no longer needed.&lt;/p&gt;
&lt;p&gt;This goes hand-in-hand with the next item, &amp;ldquo;rewrite to be forward looking&amp;rdquo;.&lt;/p&gt;
&lt;h2 id="rewrite-to-be-forward-looking"&gt;Rewrite To Be Forward Looking&lt;/h2&gt;
&lt;p&gt;Plan files and Handoff files often get polluted, as time goes on, with historical state of the repository and the plan being implemented. Lots of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;(Done) Some Requisite Feature A&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(Done) Some Requisite Feature B&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Previously we had bugs in Set A, but I fixed it for and Set B is now unblocked&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[,,,]&lt;/p&gt;
&lt;p&gt;and similar things. This is a quirk of the LLMs that may useful to them in the moment, but for new agents picking up work, is entirely unnecessary. At some point in becomes the prudent choice to tell the agent to&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;rewrite this document to be forward looking&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;ldquo;forward looking&amp;rdquo; is a keyword taken from my observations of Opus. It often uses that phrase when it deletes old content, so I adopted it into my vocabulary to better trigger the behavior I&amp;rsquo;m looking for.&lt;/p&gt;
&lt;p&gt;At the end of one of these requests, we get documents that are pruned of old detail, and only contain the necessary bits that are yet to be implemented. The agents are also smart enough to retain the items that are historical but highly relevant, like traps in the API or gaps in the machines expectations.&lt;/p&gt;
&lt;p&gt;Of course, you can always give these documents a manual once-over with your own eyes to see if they left any details in that should be stricken.&lt;/p&gt;
&lt;h2 id="team-a-vs-team-b"&gt;Team A vs Team B&lt;/h2&gt;
&lt;p&gt;I have dominion over a number of repositories that are interlinked at various levels to each other, and I often have VSCode windows up and agents working on those repos simultaneously. Sometimes, features co-develop across repositories and require two agents across repos to work in tandem.&lt;/p&gt;
&lt;p&gt;When this happens, I have Agent A in Repo 1 (1.A) work on some core feature, then ask for an Implementation Document for Agent B in Repo 2 (2.B).
Then, I take that document, and give it directly to 2.B. Sometimes it becomes emergent that the feature set or details of the core project are missing something. To prevent 2.B from creating weird workarounds or producing a sub-standard end result, I ask 2.B for a document outlining its requests for the Repo 1 Team, which it will write me, and then I can hand that document back to 1.A, which will address the issues, and the process repeats.&lt;/p&gt;
&lt;p&gt;This is a great way to get a really polished feature across two repositories simultaneously. The agents are indirectly asking each other questions, refining their assumptions, and creating features, fixing bugs, or polishing the experience.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t combine the agents into one singular one because at the context sizes I am working with, it&amp;rsquo;s a lot easier and consistent to have each Repo Agent manage its own repo context. They can communicate to each other through me, and I can arbitrate their requests. Because ultimately, I am the consumer and the judge of their work product.&lt;/p&gt;
&lt;p&gt;I find this &amp;ldquo;Team A vs Team B&amp;rdquo; document passing to be really productive.&lt;/p&gt;
&lt;h1 id="recent-worked-examples"&gt;Recent Worked Examples&lt;/h1&gt;
&lt;p&gt;I&amp;rsquo;ll describe some things I&amp;rsquo;ve had the agents do recently, beyond just the standard &amp;ldquo;implement this feature&amp;rdquo; and &amp;lsquo;fix this bug&amp;quot; requests.&lt;/p&gt;
&lt;h2 id="reducing-token-spend-on-backtracking-during-failed-test-runs"&gt;Reducing Token Spend on Backtracking during Failed Test Runs&lt;/h2&gt;
&lt;p&gt;A Desktop GUI C# application has a dedicated test suite project. It&amp;rsquo;s regular output contained all the successes and failures, but the failures were printed at the top of the output, and the agents have a habit of using &lt;code&gt;sed&lt;/code&gt;, &lt;code&gt;trim&lt;/code&gt;, and select-last in powershell, resulting in the test failures not being visible to the agent. What often happened is that it saw a generic failure (exit code 1), then re-ran the test suite with a new command just to get the failing test.&lt;/p&gt;
&lt;p&gt;The resolution was to reduce stdout noise and print detailed test failure output only, so the agents have visibility into the only part of the test suite that matters: whether a ran succeeded, and if not, which ones failed. As before, this saves tokens, context, and time.&lt;/p&gt;
&lt;h2 id="test-suite-optimization"&gt;Test Suite Optimization&lt;/h2&gt;
&lt;p&gt;A perfect mix of three things that make LLM use optimal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A clear goal
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;Bring the execution time of this test suite down to under 10 seconds&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A way to measure
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;time&lt;/code&gt; on the test suite executable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Knobs to change
&lt;ul&gt;
&lt;li&gt;The test suite source code&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With these three items an LLM can really go into perfect overdrive to improve an outcome.&lt;/p&gt;
&lt;p&gt;In this specific case, I was able to work with the LLM to iteratively reduce a naively built C#/XAML test suite from 5 minutes per run, all the way down to 10 seconds. The steps in between were 1 minute, 30 seconds, 16 seconds, then 8 seconds.&lt;/p&gt;
&lt;p&gt;The agent itself did a doggedly good job, but it was a tandem effort because I had to suggest parallelization and thread usage, eliminating old tests, and restructuring the project in ways that made it more amenable to testing.&lt;/p&gt;
&lt;h2 id="automation-and-accessibility"&gt;Automation and Accessibility&lt;/h2&gt;
&lt;p&gt;WinUI3, Microsoft&amp;rsquo;s modern desktop framework, supports &lt;a href="https://learn.microsoft.com/en-us/dotnet/framework/ui-automation/ui-automation-properties-overview"target="_blank" rel="noopener noreferrer"&gt;Automation Properties&lt;/a&gt;, which, if you are familiar with puppeteer or playwright, permits API control of the program. In the agentic era, a program that an agent can use, is a program that an agent can improve.&lt;/p&gt;
&lt;p&gt;The first problem was getting this application to have automation properties in the first place. The solution of course was to supply the relevant documentation and then set the agents on their first task:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Add automation properties this application&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Once that was done, an ADR was created saying that &amp;ldquo;all UI elements must have automation properties&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;And finally, with it all in place, all future bug fix or feature implementation sessions can now be driven start to finish with the Agent all on its own, since it now has access to every part of the application.&lt;/p&gt;
&lt;p&gt;With vision capable models like the large frontier ones, an agent is now much more powerful and can make quite delicate judgements and assess its own work much more accurately, because now it can also drive the application on its own as well.&lt;/p&gt;
&lt;h2 id="migrating-a-failing-robotics-sample-from-gazebo-to-mujoco"&gt;Migrating a Failing Robotics Sample From Gazebo to MuJoCo&lt;/h2&gt;
&lt;p&gt;A book I am following for robotics was built with the simulation program Gazebo, so all the examples in it are assuming and utilizing that program. However, Gazebo is widely understood to be bad, unreliable, have issues starting up, often misses messages passed between program nodes, and is generally a pain. This matches my experience. Some elder robotics I have spoken to, when hearing of my woes, told me that I should spend my time in other simulators like Isaac or MuJoCo. So I had Opus take all the book&amp;rsquo;s example and move them into MuJoCo automatically.&lt;/p&gt;
&lt;p&gt;It took about a week 12-hour days of time for Opus to churn through all the issues, but in the end, I had a proper simulator environment that had no runtime issues at all, and was very stable.&lt;/p&gt;</description></item><item><title>Addressing and Naming</title><link>https://example.com/network/home/home3_addressing/</link><pubDate>Sun, 05 Apr 2026 14:59:46 +0900</pubDate><guid>https://example.com/network/home/home3_addressing/</guid><description>&lt;h2 id="naming"&gt;Naming&lt;/h2&gt;
&lt;p&gt;Everything on the network gets a specific hostname, which follows a template. The naming template you choose for your own network is likely to be different based on your own desires, but here&amp;rsquo;s the one I&amp;rsquo;ve chosen:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$TwoLetterSiteCode-$RoleTemplate-$instanceNumberOrUnit&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="two-letter-site-code"&gt;Two Letter Site Code&lt;/h3&gt;
&lt;p&gt;The two-letter-site-code is an abbreviation for sites that I have, or am likely to have, devices or vms located at. For devices, this is straight forward since they must physically exist somehwere. For VMs its trickier, because they could float around from place to place. For now, I&amp;rsquo;ve simply decided that VMs have a site code equal to their hypervisor host, but it&amp;rsquo;s open to modification in the future. E.g., &amp;rsquo;s &lt;code&gt;ln&lt;/code&gt; for &lt;code&gt;London&lt;/code&gt;, &lt;code&gt;se&lt;/code&gt; for &lt;code&gt;Seattle&lt;/code&gt;, etc.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Physical&lt;/em&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;2-letter ascii code&lt;/th&gt;
&lt;th&gt;Location&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ln&lt;/td&gt;
&lt;td&gt;London&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;se&lt;/td&gt;
&lt;td&gt;Seattle&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Additionally, we define two sets of pseudo-locations:&lt;/p&gt;
&lt;p&gt;Virtual is used when something we own is hosted on a cloud provider like AWS or Digital Ocean:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Virtual&lt;/em&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;2-letter ascii code&lt;/th&gt;
&lt;th&gt;Location&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;do&lt;/td&gt;
&lt;td&gt;Digitial Ocean&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;as&lt;/td&gt;
&lt;td&gt;AWS&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;And finally, &amp;ldquo;Special&amp;rdquo;, which is used for special case items, denotes with a &lt;code&gt;z&lt;/code&gt; prefix.
&lt;em&gt;Special&lt;/em&gt;_&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;2-letter ascii code&lt;/th&gt;
&lt;th&gt;Location&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;zz&lt;/td&gt;
&lt;td&gt;Floating, of indetermine location&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;za&lt;/td&gt;
&lt;td&gt;Network-Wide: We need a prefix to make a name match, but there&amp;rsquo;s only &lt;em&gt;ever&lt;/em&gt; one of a thing. Those things get za.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;These codes are self-describing as long as you have the intution for how the abbreviations were constructed. It is recommended to keep a lookup table detailing these codes somewhere.&lt;/p&gt;
&lt;h3 id="role-template"&gt;Role Template&lt;/h3&gt;
&lt;p&gt;The Role Template is a sub-template of the naming scheme, and is used to store information such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;the main role&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;its staging environment&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;its group count within that environment&lt;/p&gt;
&lt;p&gt;Its of the form: &lt;code&gt;$role.$env.$groupCount&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;role&lt;/code&gt; is an abbreviated string of things like.
For example here is a highly abbriged list of roles I am using:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;fw&lt;/td&gt;
&lt;td&gt;Firewall&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sw&lt;/td&gt;
&lt;td&gt;Switch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hv&lt;/td&gt;
&lt;td&gt;Hypervisor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;srv&lt;/td&gt;
&lt;td&gt;Generic Server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;web&lt;/td&gt;
&lt;td&gt;Generic Web Server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ca&lt;/td&gt;
&lt;td&gt;Certificate Authority&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ap&lt;/td&gt;
&lt;td&gt;Access Point&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;zz&lt;/td&gt;
&lt;td&gt;Other&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Once again, the &lt;code&gt;z&lt;/code&gt; prefix is used to indiciate special things that don&amp;rsquo;t otherwise fit.&lt;/p&gt;
&lt;p&gt;This list is not exhaustive, and contains more specialized role names for specific web services being run, e,g.:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;hue&lt;/td&gt;
&lt;td&gt;Philips Hue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;appletv&lt;/td&gt;
&lt;td&gt;Apple TV&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;homeasistant&lt;/td&gt;
&lt;td&gt;Home Assistant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;obsidian&lt;/td&gt;
&lt;td&gt;Obsidian Notes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;etc.&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;env&lt;/code&gt; is a 1-letter code indicating its environment:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;p&lt;/td&gt;
&lt;td&gt;production&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;d&lt;/td&gt;
&lt;td&gt;development&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;s&lt;/td&gt;
&lt;td&gt;staging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;t&lt;/td&gt;
&lt;td&gt;testing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Your network may have more or different codes for other purposes.&lt;/p&gt;
&lt;p&gt;In my scheme, if no env code is found, it is implicitly of code &lt;code&gt;p&lt;/code&gt; for &lt;code&gt;production&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;groupCount&lt;/code&gt; is which group this item belongs in. For instance, two different dev teams may have the same VM running for their own purposes. In which case, Team A gets &lt;code&gt;srv.d.1&lt;/code&gt; and Team B gets &lt;code&gt;srv.d.2&lt;/code&gt; for their individual purposes.&lt;/p&gt;
&lt;p&gt;If no group count is found, it is implicitly in group &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="instance-number--unit"&gt;Instance Number / Unit&lt;/h3&gt;
&lt;p&gt;All items get a defualt &lt;code&gt;-1&lt;/code&gt; as the final portion of their hostname. A number greater than one indicates that the entre preceeding {Site-Code, RoleTemplate} has a second instance. For example, a -2 on a firewall could be a failover, -3 or -4 could be for load balancers.&lt;/p&gt;
&lt;p&gt;However, it&amp;rsquo;s also possible to use colors: &lt;code&gt;-green&lt;/code&gt; or &lt;code&gt;-blue&lt;/code&gt;, which are used to inidicate co-equal items where no one unit is of greater implicit importance than the other. For example,
&amp;ldquo;firewall-green&amp;rdquo; and &amp;ldquo;firewall-blue&amp;rdquo; are equivalent, and used in a prod/staging &lt;a href="https://en.wikipedia.org/wiki/Flip-flop_%28electronics%29"target="_blank" rel="noopener noreferrer"&gt;flip-flop gate&lt;/a&gt; where one is active currently, but may be backgrounded for the other at any point in time. These items can either be always co-equal, or take turns being the primary, but as far naming and setting up the hosts themselves, there is nothing intrinsict at setup time that would imply numeric naming. These items get the -color scheme.&lt;/p&gt;
&lt;h3 id="example"&gt;Example&lt;/h3&gt;
&lt;p&gt;A fully built example hostname would be something like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ln-fw-green&lt;/code&gt;, meaning: &amp;ldquo;green&amp;rdquo; Firewall 1, located in the London office, the primary/standby status of which would be be queries spearately&lt;/li&gt;
&lt;li&gt;&lt;code&gt;se-ap-3&lt;/code&gt;, meaning: the third Access Point in the Seattle office&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mn-web.d.3-7&lt;/code&gt; meaning: Montreal office; Dev Webserver third grouping, instance 7&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mn-web.d.3-8&lt;/code&gt; meaning: Montreal office, Dev websever third grouping, instance 8.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mn-web.d.4.7&lt;/code&gt; meaning: Montreal office, Dev Weberverr, fourth grouping, instance 7&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Typically, the unit number would be dependant on the grouping. Otherwise it should be taken that they are independent.&lt;/p&gt;
&lt;h3 id="16-characters"&gt;16 characters&lt;/h3&gt;
&lt;p&gt;Windows Domains havea 16-character limit for hostnames. We &lt;em&gt;generally&lt;/em&gt; try to restrict ourselves to the same limit, but we also break this from time to time. If you intend to manage windows domains, or intend to manage things from Active Directory, you should take care to make things fit into 16 characters, or at least be sure that the items that will be inclued in AD to be under that limit.u&lt;/p&gt;
&lt;h2 id="static-assignments"&gt;Static Assignments&lt;/h2&gt;
&lt;p&gt;For the most part, everything that gets a hostname also gets a static IP assignment. One way of thinking about what gets a static IP is that clients make do with DHCP but servers get a static IP. Anything that needs to be accessed by other things gets an IP. Your phone doesn&amp;rsquo;t need to be accessed except by you, and by physically operating it.&lt;/p&gt;
&lt;p&gt;My switch needs to be located often, so it needs a static IP.&lt;/p&gt;
&lt;p&gt;In our setup, we do not use DHCP reservations. You are free to use them, but we will just be using ip assignemnts on the devices themselves.&lt;/p&gt;
&lt;p&gt;For example, our firewall will be given the following static IP: &lt;code&gt;172.30.0.1&lt;/code&gt;, and our main switching hub will be given &lt;code&gt;172.30.0.2&lt;/code&gt;. This list will include not just other infrastructure like our hypervisor, but also overlay things like Hue Bridges, or VMs serving important apps on our network. File storage? &lt;code&gt;10.96.16.35&lt;/code&gt;. Mail server? &lt;code&gt;10.96.16.27&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Phones, desktops, etc can just rely on getting a dynamic IP from the DHCP server, since they are not expected to be accessible except by phsyical operators.&lt;/p&gt;
&lt;h3 id="ula"&gt;ULA&lt;/h3&gt;
&lt;p&gt;Although the network will be primarily IPv4, it will also be created with an eye towards IPv6. One such IPv6-thing is the concept of a &lt;a href="https://en.wikipedia.org/wiki/Unique_local_address"target="_blank" rel="noopener noreferrer"&gt;Unique Local Adddress (ULA)&lt;/a&gt;, which is a specially derived IPv6 address with certain properties.&lt;/p&gt;
&lt;p&gt;The exact reasons for why ULAs are interesting is beyond the scope of this post, but among other things, it means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If in the future. networks merge together, there will be a statistically-zero chance of collision&lt;/li&gt;
&lt;li&gt;We can encode a lot of data into the ULA that make the addresses self-describing in certain capacities&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using this &lt;a href="https://iotools.cloud/tool/ipv6-ula-generator/"target="_blank" rel="noopener noreferrer"&gt;IO Tool&amp;rsquo;s generator webapp&lt;/a&gt;, we can create some initial ULA templates for use. For my purposes, I used the main MAC addresses of my firewall&amp;rsquo;s built-in NIC for my underlay, and the MAC address of the SFP+ 520 card for the overlay, which mirrors the intended data that each card is expected to carry.&lt;/p&gt;
&lt;h1 id="todo-ula-encoding"&gt;TODO ULA Encoding&lt;/h1&gt;</description></item><item><title>Fixing missing, undefined, or incorrect validity periods for XCA issued certificates</title><link>https://example.com/network/certs/xca_template_validity_period/</link><pubDate>Sat, 21 Mar 2026 18:02:36 +0900</pubDate><guid>https://example.com/network/certs/xca_template_validity_period/</guid><description>&lt;p&gt;Check your template applications.&lt;/p&gt;
&lt;h2 id="shot"&gt;Shot&lt;/h2&gt;
&lt;p&gt;Recently while trying to issue some certificates from &lt;a href="https://hohnstaedt.de/xca/"target="_blank" rel="noopener noreferrer"&gt;XCA&lt;/a&gt;, I struggled with getting XCA to issue certifivates with a defind expiry datetime. No matter what I did to set the dates manually, the validity period expires at was always &amp;ldquo;undefined&amp;rdquo; aka &amp;ldquo;forever&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/static/certs/undefined_expiry.png"
alt="expiry undefined"/&gt;&lt;/p&gt;
&lt;h2 id="chaser"&gt;Chaser&lt;/h2&gt;
&lt;p&gt;Turns out the the reaosn is because I was applying an XCA template that specifically checked &lt;code&gt;[x] No Defindd Expiry Time&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/static/certs/no_well_defind_expiry.png"
alt="no well defined expiry time"/&gt;&lt;/p&gt;
&lt;p&gt;The application of such a template overrides the expiry time of certificates, evem you specifically uncheck the option, and even if you specifically set an expiry time.&lt;/p&gt;
&lt;p&gt;The UI won&amp;rsquo;t reflect this. The Certificate creation dialogs will tell you that you set an expiry time properly, but then you go and check the values of the created certificate and notice that the expiry date remains undefined.&lt;/p&gt;
&lt;p&gt;So, double check your templates.&lt;/p&gt;</description></item><item><title>Home Networking 2 - Architecture</title><link>https://example.com/network/home/home2_architecture/</link><pubDate>Sun, 15 Mar 2026 15:33:01 +0900</pubDate><guid>https://example.com/network/home/home2_architecture/</guid><description>&lt;h1 id="physical-and-logical-architecture"&gt;Physical and Logical Architecture&lt;/h1&gt;
&lt;p&gt;This post continues from &lt;a href="https://example.com/network/home/home1"&gt;Home Networking 1&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id="brief-vlan-legend"&gt;Brief VLAN legend&lt;/h1&gt;
&lt;p&gt;The vlans we&amp;rsquo;re using for now are established like so:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;untagged&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;Infrastructure management panels&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;900&lt;/td&gt;
&lt;td&gt;Inbound ISP traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1016&lt;/td&gt;
&lt;td&gt;Trusted network&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1032&lt;/td&gt;
&lt;td&gt;Guest network&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id="logical-layout"&gt;Logical Layout&lt;/h1&gt;
&lt;p&gt;Recall from earlier we mentioned &lt;a href="https://en.wikipedia.org/wiki/Router_on_a_stick"target="_blank" rel="noopener noreferrer"&gt;Router On a Stick&lt;/a&gt;, implemented thusly:&lt;/p&gt;
&lt;pre class="mermaid"&gt;
---
title: Logical VLAN connections
---
graph LR;
sfp((ISP/WAN));
switch;
ap(access point);
hypervisor;
firewall;
sfp--&amp;gt;|vlan/900|switch;
subgraph vlan/all;
switch&amp;lt;--&amp;gt;|vlan100,vlan/all|firewall;
end
subgraph vlan/other;
switch&amp;lt;--&amp;gt;|vlan100,vlanall|hypervisor
end
subgraph WiFi Networks;
ap&amp;lt;--&amp;gt;|vlan/1016,
vlan/1032,
vlan/100
|switch
end
&lt;/pre&gt;
&lt;p&gt;ISP modem goes into the switch, which in turn goes to the firewall. The ISP modem is an SFP unit, so it goes into one of the switches SFP+ slots. From there, a different switch-inserted SFP+ module connects to an SFP+ module on the firewall, over 10GB optical cables.
The optical cables we&amp;rsquo;re using are &amp;ldquo;LC UPC Duplex&amp;rdquo;, meaning there&amp;rsquo;s one dedicated line for outgoing, and one dedicated line for incoming. Things can, in theory, go very fast on the internal network.&lt;/p&gt;
&lt;p&gt;Once network packets pass through the firewall, they go back out into the switch to their destination vlan device.&lt;/p&gt;
&lt;p&gt;ISP packets come in on a port marked for vlan 900. This is a standard marking for ISP / inbound-WAN traffic. Once it gets to the firewall, it will be sent back through the switch with whatever vlan is appropriate, defined by rules we will discuss later.&lt;/p&gt;
&lt;h1 id="physical-layout"&gt;Physical Layout&lt;/h1&gt;
&lt;p&gt;Because our vlans are traveling over a physical switch with physical ports, we can&amp;rsquo;t just define the vlans in the opnsense firewall, we also have to define them on the switch.&lt;/p&gt;
&lt;p&gt;On our 24 Ethernet / 4 SFP port switch, we have roughly the following layout:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ports 1-12 (&lt;code&gt;1/1 - 1/12&lt;/code&gt; in FS switch parlance) (ethrenet) - &lt;code&gt;untagged*&lt;/code&gt;, meaning that anything plugged into them is capable of being routed anywhere. This is done for management purposes, therefore anything plugged into this set of items should be for device and infrastructure management.
&lt;ul&gt;
&lt;li&gt;* &amp;ldquo;Untagged&amp;rdquo; in a vlan-aware system implies &lt;code&gt;vlan/1&lt;/code&gt;. Don&amp;rsquo;t ask me why.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Port 1 (1/1) - dedicated to the Managemnet interface of the Firewall. This provides us with direct access to the OPNSense control panel / CLI.&lt;/li&gt;
&lt;li&gt;Port 24 (reserved) - for future expansion, this is marked as being a Trunk (aka, capable of carrying multiple vlans) carrying other, yet to be defined vlans, which is meant to be connected to a yet-to-be-installed second switch. This is meant to allow us to drop in another switch onto th network if we run out of ports on our current one.&lt;/li&gt;
&lt;li&gt;Port 25 (SFP+/fiber) - the actual switch&amp;lt;-&amp;gt;firewall traffic. This port is makred as being a trunk for every for every single vlan (EXCEPT vlan/100 management traffic) we define on the network. This is necessary because we want &lt;em&gt;all&lt;/em&gt; traffic to flow through the firewall.&lt;/li&gt;
&lt;li&gt;Port 28 (SFP+/fiber) (&lt;code&gt;1/28&lt;/code&gt;) - &lt;code&gt;vlan900&lt;/code&gt; for ISP traffic, and is where the ISP&amp;rsquo;s SFP+ WAN modem unit is plugged into.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Or, in table form:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;th&gt;VLAN&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1-12&lt;/td&gt;
&lt;td&gt;untagged&lt;/td&gt;
&lt;td&gt;For infrastructure access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;untagged&lt;/td&gt;
&lt;td&gt;Firewall management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;untagged&lt;/td&gt;
&lt;td&gt;Hypervisor management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;Access Point* traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;Trunk, all&lt;/td&gt;
&lt;td&gt;Reserved for future switch expansion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;Trunk, all&lt;/td&gt;
&lt;td&gt;Firewall traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;Trunk, all&lt;/td&gt;
&lt;td&gt;Hypervisor VM traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;900&lt;/td&gt;
&lt;td&gt;ISP WAN access&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The other ports will be filled in later&lt;/p&gt;
&lt;p&gt;*the Access Point requires some &amp;ldquo;&amp;ldquo;&amp;ldquo;flexibility&amp;rdquo;&amp;rdquo;&amp;rdquo; in our system because it only has one port, meaning we have to combine our Management and Client traffic over one port using multiple VLANs on one port. Ideally we would have had two ports, one dedicated for management, and the other for client traffic. It gets a little tricky, and we will discuss this later.&lt;/p&gt;
&lt;p&gt;The actual physical port diagram looks like this:&lt;/p&gt;
&lt;pre class="mermaid"&gt;
---
title: Physical Port Diagram
---
graph LR;
switch;
isp((ISP/WAN));
ap(access point);
hypervisor;
firewall;
switch--&amp;gt;|1|firewall;
switch--&amp;gt;|2|hypervisor;
switch--&amp;gt;|24|ap;
isp--&amp;gt;|28|switch;
switch--&amp;gt;|25|firewall;
switch--&amp;gt;|26|hypervisor;
&lt;/pre&gt;
&lt;p&gt;As you can see, the AP only having one port breaks the pattern a little bit, but we can work around it.&lt;/p&gt;
&lt;h1 id="underlayoverlay"&gt;Underlay/Overlay&lt;/h1&gt;
&lt;p&gt;The network that we&amp;rsquo;re going to set up is going to that of an Underlay Overlay network.
The &lt;code&gt;underlay&lt;/code&gt; is where the network infrastructure will reside on its own internal RFC1918 IPv4 address space. Things on this space will have free access to both other things on the underlay, and to things on the overlay. Things on this network are variably on vlan 100, or untagged. Addresses on this this network will for things like the switch, the firewall, etc.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;overlay&lt;/code&gt; network is where everything that isn&amp;rsquo;t direct network infrastructure reside, such as settop boxes, iot devices, and user accessible VMs. The address space is also an RFC1918 address space, but deliberately separate from the underlay one. This overlay network is extenseively vlan&amp;rsquo;d to achieve high separation.&lt;/p&gt;
&lt;p&gt;For our purposes, the IPs we choose will be as follows:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Network&lt;/th&gt;
&lt;th&gt;Address Space&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Underlay&lt;/td&gt;
&lt;td&gt;172.30.0.0/16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Overlay&lt;/td&gt;
&lt;td&gt;10.96.0.0/16&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;We choose a /16 CIDR so that we can make liberal use of the third ipv4 octet. Because this is going to be a relatively small network, we will end up using that third octet to denote the vlan of the network. This is not mandatory, but it has two nice side effects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The network is easily categorizable at a glance&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Networks will not have any overlap with each other in the event they need to perform cross-talk.&lt;/p&gt;
&lt;p&gt;Of course. this setup limits us to 256 addresses per vlan, but that&amp;rsquo;s fine for our purposes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Home Networking 1 - Overview</title><link>https://example.com/network/home/home1_overview/</link><pubDate>Sun, 15 Mar 2026 10:58:49 +0900</pubDate><guid>https://example.com/network/home/home1_overview/</guid><description>&lt;h1 id="setup-and-overview"&gt;Setup and Overview&lt;/h1&gt;
&lt;p&gt;With advice from an expert friend, combined with barely even novice level talent and understanding of networks, here&amp;rsquo;s how I&amp;rsquo;ve begun to set up a network that may be used for both learning at home, and some minor commerical endevaors.
One of the outstanding goals is to reduce reliance on cloud providers and proprietary solutions as much as is feasible. That process may also be a progressive one.&lt;/p&gt;
&lt;p&gt;All of this is thanks to one specific friend. I won&amp;rsquo;t name him here, but he knows who he is. As I am a cheapskate, if there&amp;rsquo;s any kind of even remotely industrial hardware here, it is from his personal stash of equipment. In addition to his hardware, all of this is due to his many years of hard-earned expertise as a professional in the field, which I am fortunate to learn from.&lt;/p&gt;
&lt;p&gt;For context, remmber that I am a software developer who has successfully avoided networking since university. I don&amp;rsquo;t know nothin&amp;rsquo; about nothin'.&lt;/p&gt;
&lt;h1 id="overview"&gt;Overview&lt;/h1&gt;
&lt;p&gt;This setup relies heavily on VLANs, hardware that supports VLANs, SFP+ modules, and other things that I have either only vaguely heard of, or have never heard of at all before this started.&lt;/p&gt;
&lt;h2 id="flow"&gt;Flow&lt;/h2&gt;
&lt;p&gt;This series of posts will vaguely follow this outline:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Overview (this post)&lt;/li&gt;
&lt;li&gt;Physical and Virtual architecture including vlans, wiring, etc&lt;/li&gt;
&lt;li&gt;Setting up the Access Point and WiFi&lt;/li&gt;
&lt;li&gt;Setting up the Switch&lt;/li&gt;
&lt;li&gt;Setting up OPNSense Firewall&lt;/li&gt;
&lt;li&gt;Setting up our Public Key Infrastructure (PKI)&lt;/li&gt;
&lt;li&gt;Setting up OpenVPN&lt;/li&gt;
&lt;li&gt;Setting up Proxmox&lt;/li&gt;
&lt;li&gt;Spinning up VMs&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="hardware"&gt;Hardware&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.hardwarezone.com.sg/pc/components/tech-news-new-lian-li-pc-q21-tiny-spacious-mini-itx-chassis"target="_blank" rel="noopener noreferrer"&gt;Lian-Li PC-Q21&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.serversupply.com/NETWORKING/NETWORK%20INTERFACE%20CARD/10%20GIGABIT/INTEL/X520-DA2_138689.htm"target="_blank" rel="noopener noreferrer"&gt;Intel X520 DA-2&lt;/a&gt; 2x SFP+ 10GB Network Adapter (aka, a NIC)&lt;/li&gt;
&lt;li&gt;Runs the firewall&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://i.dell.com/sites/content/shared-content/data-sheets/en/Documents/dell-poweredge-t420-technical-guide.pdf"target="_blank" rel="noopener noreferrer"&gt;Dell T420&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Same Intel X520 DA-2 as above&lt;/li&gt;
&lt;li&gt;Runs the hypervisor&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.fs.com/products/183384.html?attribute=127110&amp;amp;id=4791550"target="_blank" rel="noopener noreferrer"&gt;FS S3900 24T4S&lt;/a&gt; network switch&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.netgear.com/support/product/wax610"target="_blank" rel="noopener noreferrer"&gt;Netgear WAX610&lt;/a&gt; Access Point&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some questions you may have:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Why such a heavy duty switch?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Originally, I had a TP-Link switch. That, combined with the Lian-Li via one X520 NIC were supposed to be all that was needed for networking, but due to some ISP quirks related to the modem unit, the Intel branded NICs could not recognize the modem module, and a more heavy duty switch, the FS S3900, had to be brought in to handle that modem step. Aside from some general weirdness (why is the port numbering bottom-to-top? Why can&amp;rsquo;t I upload a cert directly?) because FS the compnay is itself kind of weird, the switch is working fine. But only fine. This UIs on this thing are borderline unseable.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Why an AP and not a router with OpenWRT, which surely you already had?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Astutely observed. Sadly I fried my main router, a Nighthawk R7800 (RIP to a real one), by plugging in a 48v DC power adapter by accident, so that was the end of that. Then, a backup router my friend gave me also didn&amp;rsquo;t boot, though we are uncertain if this is another 48v error, or if it wasn&amp;rsquo;t working for other reasons. In any event, I figued that as I play pretend professional-network-engineer, I may as well lean into it and get something professional. We&amp;rsquo;ll talk more about this one later, it largely works fine, with only one-and-half issues to complain about (tl;dr only 1 port, and does not yet run OpenWRT).&lt;/p&gt;
&lt;p&gt;For those in the know, this means that we ended up moving to a &lt;a href="https://en.wikipedia.org/wiki/Router_on_a_stick"target="_blank" rel="noopener noreferrer"&gt;Router On a Stick&lt;/a&gt; architecture. I don&amp;rsquo;t know enough to say whether thats good, bad, or neutral, but apparently that&amp;rsquo;s what it is.&lt;/p&gt;
&lt;h3 id="wires-and-module-knicknacks"&gt;Wires and Module knicknacks&lt;/h3&gt;
&lt;p&gt;We&amp;rsquo;re doing things with SFPs, so we also have 4x 10GB intel-compatible SFP+ optical modules, with associated &lt;a href=""&gt;LC UPC Duplex to LC UPC Duplex, Multimode (OM4)&lt;/a&gt; fiber patch cables to carry data over those modules.&lt;/p&gt;
&lt;p&gt;Plus, obviously, a ton of ethernet cables of various grades, though a move to consistent Cat6e is underway.&lt;/p&gt;
&lt;h2 id="software"&gt;Software&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://opnsense.org/"target="_blank" rel="noopener noreferrer"&gt;OPNSense&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Firewall, plus all the things that would otherwise be handled by the router including VLAN assignments, DHCP, etc&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.isc.org/kea/"target="_blank" rel="noopener noreferrer"&gt;Kea DHCP&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Bunled as part of OPNSense. Somewhat quirky, just like OPNSense, but it works.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.proxmox.com/en/"target="_blank" rel="noopener noreferrer"&gt;Proxmox&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Hypervisor, like Hyper-V for those coming from the Windows World like myself.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openvpn.net/client/"target="_blank" rel="noopener noreferrer"&gt;OpenVPN&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Why not Wireguard? Because I intend to have multiple people on the network at once and wireguard is mostly single-user.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There&amp;rsquo;s a bunch of other things that will make appearnces as appropriate, like certificate management software. OpenWRT in particular was supposed to appear here until the r7800 got zapped to death. And the switches run their own OSs which is not &lt;em&gt;ideal&lt;/em&gt;, but is basically &lt;em&gt;fine&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The above 3 things are going to do the lions share of work to establish our network, its perimeters, and its rules.&lt;/p&gt;
&lt;h1 id="keyword-jumble-of-tech-ive-had-to-become-acquainted-with"&gt;Keyword jumble of tech I&amp;rsquo;ve had to become acquainted with&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;FreeBSD
&lt;ul&gt;
&lt;li&gt;And also its cousins OpenBSD (max security) and NetBSD (max device compatability), and why not to use them&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;OPNSense
&lt;ul&gt;
&lt;li&gt;With a heathy amount of dishing on PFsense&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Proxmox&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Firewall&amp;rdquo;, as opposed to just &amp;ldquo;router&amp;rdquo;, and also not just in the sense of &amp;ldquo;blocking ports&amp;rdquo; as though on a Host machine&lt;/li&gt;
&lt;li&gt;SFP+&lt;/li&gt;
&lt;li&gt;Infiniband&lt;/li&gt;
&lt;li&gt;Optical wiring&lt;/li&gt;
&lt;li&gt;Subnets and subnet masks&lt;/li&gt;
&lt;li&gt;VLANs
&lt;ul&gt;
&lt;li&gt;including Trunks, Tagged and Untagged, 802.1Q&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Kea&lt;/li&gt;
&lt;li&gt;DHCP at more than just a surface level understanding of &amp;ldquo;its the ip address assigner protocol&amp;rdquo;
&lt;ul&gt;
&lt;li&gt;including DHCP pools&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;tcpdump beyond just &amp;ldquo;oh yeah I&amp;rsquo;ve heard of that&amp;rdquo;&lt;/li&gt;
&lt;li&gt;UDP beyond &amp;ldquo;its the thing thats not TCP&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Network Adapter&amp;rdquo; as opposed to &amp;ldquo;NIC&amp;rdquo;&lt;/li&gt;
&lt;li&gt;IPv6 at deep level
&lt;ul&gt;
&lt;li&gt;ULA schemes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RAID&lt;/li&gt;
&lt;li&gt;Drive mirroring&lt;/li&gt;
&lt;li&gt;ZFS
&lt;ul&gt;
&lt;li&gt;including zpool, datasets, and iops&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Underlay / Overlay networks&lt;/li&gt;
&lt;li&gt;PKI
&lt;ul&gt;
&lt;li&gt;including Certificate Authorities, Sub-CAs, Extended Key Usage, Subject Alternative Name, Certificate Revocation Lists, etc&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TFTP&lt;/li&gt;
&lt;li&gt;RADIUS&lt;/li&gt;
&lt;li&gt;Virtual IP (VIP)&lt;/li&gt;
&lt;li&gt;S/MIME&lt;/li&gt;
&lt;li&gt;Syslog as a format (RFC5424), as opposed to the place on unix systems where system info get dumped to&lt;/li&gt;
&lt;li&gt;EEPROM&lt;/li&gt;
&lt;li&gt;Serial Console despite being ethernet shaped is not ethernet&lt;/li&gt;
&lt;li&gt;Baud rates&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Management&amp;rdquo; with respect to device administration&lt;/li&gt;
&lt;li&gt;DynDNS&lt;/li&gt;
&lt;li&gt;LAGG&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Implementing OAuth 2.0 from the RFCs</title><link>https://example.com/posts/oauth1/</link><pubDate>Mon, 05 Jan 2026 22:58:37 +0900</pubDate><guid>https://example.com/posts/oauth1/</guid><description>&lt;h1 id="prologue"&gt;Prologue&lt;/h1&gt;
&lt;p&gt;OAuth is a common peice of web technology infrastructure that underpins many common websites.
To keep things short, its how you log into websites.&lt;/p&gt;
&lt;p&gt;But we&amp;rsquo;re here to learn more than that. First, how much detail would you like to learn? Select a skill level, and we&amp;rsquo;ll work from there.&lt;/p&gt;
&lt;p&gt;n.b., we will only be covering OAuth 2.1 here, since OAuth 2.0 is now deprecated. That means no Implicit Flow, and Authorization will use PKCE only.
Also, we&amp;rsquo;re going to be deep-diving into a bunch of RFCs, so depending on the experience level, be prepared for some technical writing.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;
&lt;h1 id="skill-level--1-just-the-summary"&gt;Skill Level -1 (just the summary)&lt;/h1&gt;
&lt;/summary&gt;
&lt;p&gt;[[Graph 1 &amp;ndash; the drawing of Login With X]]&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s when websites or apps ask you to &amp;ldquo;Log In With Google&amp;rdquo;, &amp;ldquo;Log In With Instragram&amp;rdquo;.&lt;/p&gt;
&lt;/details&gt;
&lt;details&gt;
&lt;summary&gt;
&lt;h1 id="skill-level-0-novice--just-a-random-internet-user"&gt;Skill Level 0 (novice / just a random internet user)&lt;/h1&gt;
&lt;/summary&gt;
&lt;p&gt;[[Get lots of pictures of OAuth here]]&lt;/p&gt;
&lt;div class="row-container" style="display: flex; width: 100%; height: 100%; flex-direction: column; background-color: blue; overflow: hidden;"&gt;
&lt;iframe src="https://example.com/simple_auth_1/index.html" style="flex-grow: 1; border: none; margin: 0; padding: 0;" height="500"&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;OAuth, specifically OAuth 2.1, though commonly just referred to as OAuth 2, is how things like &amp;ldquo;Log in with Google&amp;rdquo;, or &amp;ldquo;Log in with Instagram&amp;rdquo; work. You already have an account with Instagram, so it&amp;rsquo;s easier to just login with those credentials than to create a brand new login for yet another app.&lt;/p&gt;
&lt;p&gt;When you select Log In With Google, you get redirected to Google&amp;rsquo;s own log-in form. This form shows you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Who is asking for permission from you&lt;/li&gt;
&lt;li&gt;What they want to have access to / what they want to be able to do&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After considering this form, you confirm or deny the Authorization Request, and then you get redirected back to the site you were trying to log into originally. There was a bit of a bouncing from hither and tither, but it worked well and now you&amp;rsquo;re logged into the new website.&lt;/p&gt;
&lt;p&gt;This means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The website &lt;em&gt;does not know&lt;/em&gt; your Google password&lt;/li&gt;
&lt;li&gt;The website &lt;em&gt;does not store&lt;/em&gt; your Google password&lt;/li&gt;
&lt;li&gt;The website &lt;em&gt;cannot&lt;/em&gt; login as you&lt;/li&gt;
&lt;li&gt;The website &lt;em&gt;cannot&lt;/em&gt; impersonate you&lt;/li&gt;
&lt;li&gt;The website &lt;em&gt;cannot&lt;/em&gt; do whatever it wants&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whats important to know here is that when you login &lt;em&gt;with&lt;/em&gt; Google, only Google knows about your password. The website doesn&amp;rsquo;t know anything.
All it does is give the website access to specific aspects your account. What, specifically, it has access to was shown to you on the Authorization Screen.&lt;/p&gt;
&lt;p&gt;For most purposes, the only thing you need to remember is that it reduces the amount of logins you need to keep track of. Instead of creating yet another account on yet another site, you can just use your Google account.&lt;/p&gt;
&lt;/details&gt;
&lt;details&gt;
&lt;summary&gt;
&lt;h1 id="skill-level-1-developer-but-not-too-into-web-tech"&gt;Skill Level 1 (developer, but not too into web tech)&lt;/h1&gt;
&lt;/summary&gt;
&lt;p&gt;OAuth2 is how you login into one site with an account from another. It&amp;rsquo;s designed to avoid sharing actual credentials such as passwords, while still letting you access things associated with your account on one service, while using a different service. One example of this would be &lt;a href="stats.fm"&gt;stats.fm&lt;/a&gt;, an app that shows listening statistics from your Spotify account. Stats.fm is not affiliated with Spotify, but it needs access to your Spotify account to work. When you log in, it asks you to &amp;ldquo;connect your Spotify account&amp;rdquo;, which brings you to the Spotify login screen. There, you log into Spotify like normal, on Spotify&amp;rsquo;s actual spotify.com domain, and then you get redirected back to stats.fm, with the redirect operation carrying some extra information. It is with this extra information that the app now has access to knowledge related to your Spotify account.&lt;/p&gt;
&lt;p&gt;[[Animation 2 &amp;ndash; anim including return of Access Token]]&lt;/p&gt;
&lt;h3 id="access-token"&gt;Access Token&lt;/h3&gt;
&lt;p&gt;This is accomplished by the acquistion of an &lt;em&gt;Access Token&lt;/em&gt;, which is string that is sent back and forth between stats.fm, and Spotify. This string is assocated with your specific account and gives its bearer access to information associated with your Spotify account. It is functionally similar to a cookie holding login information. The contents of the string are intended to be opaque to users. The contents are not important, what matters is that the string is sent over to the server exactly as-is.&lt;/p&gt;
&lt;p&gt;Whoever bears this token has access to everything the token was given access to during the initial Authorization. Because of this property, an Access Token, and all other tokens similar to it, are known as a broad category, as &lt;em&gt;Bearer Tokens&lt;/em&gt;. We will be referring to Bearer Tokens a lot, but just remember that a Bearer Token is a category of credential, and Access Tokens are a specific type of Bearer Token.&lt;/p&gt;
&lt;p&gt;Access Tokens are typically &lt;em&gt;short-lived&lt;/em&gt;. What this means in practice is that access tokens have a lifetime of about an hour (3600 seconds, this number will appear a lot as well), after which the the token becomes invalid. Continuing to use the token will result in a lot of &lt;em&gt;403 Unauthorized&lt;/em&gt; errors.&lt;/p&gt;
&lt;h3 id="refresh-token"&gt;Refresh Token&lt;/h3&gt;
&lt;p&gt;So how do you get a new one if its expired? Does the user have to do another Authorization step? No, to get another Access Token we use something called a &lt;em&gt;Refresh Token&lt;/em&gt;. When we got our original Access Token, a handful of other data was sent to us at the same time. One such piece data we got in addition to the Access Token was another token, called the Refresh Token. A Refresh Token&amp;rsquo;s only purpose is to be given back to the main server. When we do so, the sever sends us back another Access Token, and another Refresh Token.&lt;/p&gt;
&lt;p&gt;[[Animation 3 &amp;ndash; anim including return of Access And Refresh Tokens]]&lt;/p&gt;
&lt;/details&gt;
&lt;details&gt;
&lt;summary&gt;
&lt;h1 id="skill-level-2-developer-in-charge-of-integrating-with-an-oauth-provider"&gt;Skill Level 2 (developer, in charge of integrating with an OAuth Provider)&lt;/h1&gt;
&lt;/summary&gt;
&lt;p&gt;[[Animation 4 &amp;ndash; anim including the Auth Code, return, and exchange]]&lt;/p&gt;
&lt;p&gt;OAuth 2 is a set of specifications for supplying third-party applications with first-party authorization (&amp;ldquo;authz&amp;rdquo;, or &amp;ldquo;what you are allowed to do&amp;rdquo;) information. What&amp;rsquo;s important to know is that [OAuth 2.1[(21 RFC)] is the current main spec, and that it defines the Authorization Flow with PKCE, and the Client Credentials flow. There&amp;rsquo;s also an extension to OAuth2 called OpenID Connect (OIDC) that deals with providing authentication (&amp;ldquo;authn&amp;rdquo;, or &amp;ldquo;who you are&amp;rdquo;) information. The difference between the two is often muddled.&lt;/p&gt;
&lt;p&gt;OAuth 2 uses a standard set of terminology that one should be familiar with, otherwise it becomes confusing trying to understand what is talking to who and under what circumstances.
The entities commonly seen in the spec are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Authorization Server&lt;/li&gt;
&lt;li&gt;Resource Server&lt;/li&gt;
&lt;li&gt;Resource Owner&lt;/li&gt;
&lt;li&gt;Resouce&lt;/li&gt;
&lt;li&gt;Client&lt;/li&gt;
&lt;li&gt;User&lt;/li&gt;
&lt;li&gt;User Agent&lt;/li&gt;
&lt;li&gt;Flow&lt;/li&gt;
&lt;li&gt;Token&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The spec defines treats these entities seperately, but oftentimes they can be co-located, making the distinction hard to grasp when thinking about it from the perspective of certain services you may have encountered in the wild.&lt;/p&gt;
&lt;h3 id="working-definitions"&gt;Working Definitions&lt;/h3&gt;
&lt;p&gt;You can find the true definitions in the spec, but let&amp;rsquo;s outline them here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Authorization Server&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;This is the authority with whom you are trying offer &amp;ldquo;Log In With&amp;rdquo; capability with.&lt;/li&gt;
&lt;li&gt;This is Spotify, Instagram, Google, etc, where the users actual account lies&lt;/li&gt;
&lt;li&gt;Specifically, this is their &lt;code&gt;accounts.xyz.com&lt;/code&gt; doman, as opposed to their generaic &lt;code&gt;xyz.com&lt;/code&gt; domain.&lt;/li&gt;
&lt;li&gt;From the perspective of OAuth, the Authorization Servers &lt;em&gt;only&lt;/em&gt; responsibility is providing access to user account checks.&lt;/li&gt;
&lt;li&gt;Authorization Servers hold all the Resource Owners&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Resource Server&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;This is the server where &amp;ldquo;resources&amp;rdquo; are.&lt;/li&gt;
&lt;li&gt;Typically, this is the &lt;code&gt;api.xyz.com&lt;/code&gt; domain or the &lt;code&gt;xyz.com/api/&lt;/code&gt; endpoint.&lt;/li&gt;
&lt;li&gt;The resouce server does not Authorize,&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Resource&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;A resource is anything that your integrating application might be interested in
&lt;ul&gt;
&lt;li&gt;Liked Songs&lt;/li&gt;
&lt;li&gt;Friends List&lt;/li&gt;
&lt;li&gt;Calendar Events&lt;/li&gt;
&lt;li&gt;Product Reviews,&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Resource Owner&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;This a term describing &lt;em&gt;whose&lt;/em&gt; things you&amp;rsquo;re interested in&lt;/li&gt;
&lt;li&gt;&lt;em&gt;whose&lt;/em&gt; Liked Songs?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;whose&lt;/em&gt; Friends List?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;whose&lt;/em&gt; Calendar Events?&lt;/li&gt;
&lt;li&gt;From the perspctive of OAuth, the Resouce Owner is the literal user account on the Authorization Server. As a matter of philosophy, that means that a &amp;ldquo;User&amp;rdquo; and a &amp;ldquo;Resource Owner&amp;rdquo; are the same abstract entity, represented at different concrete steps of the process.&lt;/li&gt;
&lt;li&gt;A Resource Owner necessarily has an account on the Authorization Server&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;User&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The person trying to login, the person actually phsyically performing the button clicks to initiate the varius Flows&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;User Agent&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The user&amp;rsquo;s Browser, or the Web View used to phsyically handle the Authoriztion process&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flow&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Flows are a little more abstract, but they represent the various different types of back-and-forth to obtain Tokens&lt;/li&gt;
&lt;li&gt;the two major flows are &lt;em&gt;Client Credentials&lt;/em&gt;, and &lt;em&gt;Authorization&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;n.b, 1: Authorization used to be called &amp;ldquo;Authorization&amp;rdquo;, and then an extension known as &amp;ldquo;Authorization with PKCE&amp;rdquo; was introduced, and then that got absorped into the main spec, so now it&amp;rsquo;s just back to &amp;ldquo;Authorization&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;n.b, 2: There used to be something called the &amp;ldquo;Implicit Flow&amp;rdquo;. This is now deleted, and servers that continue to support it are out of compliance with the current specification.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Token&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;A string that can be used to access the API servers on behalf of a user.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Client&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;A specific application that has bene registered with the Authorization Server, and is permitted to receive and use Tokens.&lt;/li&gt;
&lt;li&gt;From the perspective of you, a developer integrating with an OAuth Server, this is is &lt;em&gt;your&lt;/em&gt; application, that you have registered with the OAuth Server.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For reference, here is how the OAuth Spec depicts the main Flow&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; +--------+ +---------------+
| |--(1)- Authorization Request -&amp;gt;| Resource |
| | | Owner |
| |&amp;lt;-(2)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(3)-- Authorization Grant --&amp;gt;| Authorization |
| Client | | Server |
| |&amp;lt;-(4)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(5)----- Access Token ------&amp;gt;| Resource |
| | | Server |
| |&amp;lt;-(6)--- Protected Resource ---| |
+--------+ +---------------+
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As comparison, here&amp;rsquo;s how Spotify depicts the same process:&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="spotify_oauth_authflow.png"
alt="Spotify&amp;rsquo;s Auth Flow Chart"/&gt;&lt;/p&gt;
&lt;p&gt;These graphs are as simple as it can be, but that doesn&amp;rsquo;t make it necessarily &lt;em&gt;simple&lt;/em&gt;.&lt;/p&gt;
&lt;/details&gt;
&lt;h1 id="the-oauth-dance"&gt;The OAuth Dance&lt;/h1&gt;
&lt;p&gt;The OAuth Authorization Flow is like a three-person dance between the user, your Client, and the Authorization Server.&lt;/p&gt;
&lt;p&gt;You have to craft an &lt;em&gt;Authorization Request&lt;/em&gt; with specific parameters, then send both the user and that crafted request to the Authorization Server. At this step, your Client must wait while the two other parties dance on their own for a bit.&lt;/p&gt;
&lt;p&gt;The Authorization Server uses that request to ask the user if they acquiesce to the request. If so, the Authorization Server gives your Client an &lt;em&gt;Authorization Code&lt;/em&gt;, and then your Client is back in the dance.&lt;/p&gt;
&lt;p&gt;The User is now retired from the dance completely, and its just your Client and Authorization Server now.&lt;/p&gt;
&lt;p&gt;Using the &lt;em&gt;Authorization Code&lt;/em&gt;, your Client hands the Authorization Server the same &lt;em&gt;Authorization Code&lt;/em&gt; it just received, and in return the Authorization Server hands your Client back an &lt;em&gt;Access Token&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;At this point, the three-way dance concludes. The final result of the dance is the Acess Token, which you can now use to dance with the Resource Server, separately.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;p&gt;The dance is hard to understand in the abstract, and it&amp;rsquo;s much easier to understand in motion. To that effect, you can see the dance happen with real information here:&lt;/p&gt;</description></item><item><title>Programming Language Features I'd Like Most Languages To Have</title><link>https://example.com/posts/misc/plfeatures/</link><pubDate>Tue, 10 Jan 2023 12:19:34 +0900</pubDate><guid>https://example.com/posts/misc/plfeatures/</guid><description>&lt;p&gt;Here are some things I am dissappointed to leave behind when I switch back and forth between languages that dont have certain features.&lt;/p&gt;
&lt;h1 id="if-expressions"&gt;If Expressions&lt;/h1&gt;
&lt;h2 id="found-in-rust-probably-other-functional-languages"&gt;Found in: Rust; probably other functional languages&lt;/h2&gt;
&lt;h2 id="irritatingly-missing-from-everything"&gt;Irritatingly missing from: Everything&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-Rust" data-lang="Rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="fm"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{x}&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 6
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What I have to do instead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;{x}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="ternary"&gt;Ternary&lt;/h1&gt;
&lt;h2 id="found-in-everywhere-except-go"&gt;Found In: Everywhere except Go&lt;/h2&gt;
&lt;p&gt;Ternaries are like If Expressions but less powerful&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What I have to do intead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="for-else-blocks"&gt;For-Else Blocks&lt;/h1&gt;
&lt;h2 id="found-in-python"&gt;Found in: Python&lt;/h2&gt;
&lt;h2 id="irritatingly-missing-from-everything-1"&gt;Irritatingly Missing From: Everything&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;for_else&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;loop at &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Arr was empty&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;for_else&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt; &lt;span class="c1"&gt;# &amp;#34;Arr was empty&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What I have to do instead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cs" data-lang="cs"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;for_else&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Arr was empty&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;Loop at {idx}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="result-types"&gt;Result Types&lt;/h1&gt;
&lt;h2 id="found-in-rust-haskell-any-of-the-ocaml-derived-languages"&gt;Found in: Rust; Haskell; any of the OCaml derived languages&lt;/h2&gt;
&lt;h2 id="irritatingly-missing-from-everything-2"&gt;Irritatingly Missing From: Everything&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-Rust" data-lang="Rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;r&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;: &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-&amp;gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 5
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r_f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// None
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What I have to do instead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int?&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;r_t&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;r_f&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="built-in-tuples"&gt;Built-in Tuples&lt;/h1&gt;
&lt;h2 id="found-in-c-rust-python-most-functional-languages"&gt;Found In: C#; Rust; Python; Most functional languages&lt;/h2&gt;
&lt;h2 id="irritatingly-missing-from-older-c"&gt;Irritatingly Missing From: Older C#&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cs" data-lang="cs"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tup&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Item1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#34;1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Item2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#34;a&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What I have to do instead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tup&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Tuple2&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;s&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or even worse, define my own custom tuple type:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Tup2&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;T1&lt;/span&gt; &lt;span class="n"&gt;Item1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;T2&lt;/span&gt; &lt;span class="n"&gt;Item2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tup&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Tup2&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;s&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="destructuing"&gt;Destructuing&lt;/h1&gt;
&lt;h2 id="found-in-c-python-rust-javascript-most-functional-languages"&gt;Found In C#; Python; Rust; JavaScript; Most functional languages&lt;/h2&gt;
&lt;h2 id="irritatingly-missing-from-older-c-1"&gt;Irritatingly Missing From: Older C#&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cs" data-lang="cs"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;s&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;t_num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;t_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;t_num: {t_num}; t_str: {t_str}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#34;t_num: 5; t_str: s&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What I have to do instead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Tuple2&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Tuple2&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;s&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tup&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;t_num&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Item1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;t_str&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Item2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="negative-array-indexes"&gt;Negative Array Indexes&lt;/h1&gt;
&lt;h2 id="found-in-python-rust-kind-of"&gt;Found In: Python; Rust (kind of)&lt;/h2&gt;
&lt;h2 id="not-found-in-everywhere-else"&gt;Not Found In: Everywhere else&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;c&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;c&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What I have to do intead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(){&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;a&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;b&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;c&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;{arr[idx]}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#34;c&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="trailing-commas-for-all-list-like-structures"&gt;Trailing Commas for all list-like structures&lt;/h1&gt;
&lt;h2 id="found-in-python-go-rust-c-lists-only"&gt;Found In: Python; Go; Rust; C# (lists only)&lt;/h2&gt;
&lt;h2 id="not-found-in-c-func-parameters-json"&gt;Not Found In: C# (func parameters); JSON&lt;/h2&gt;
&lt;p&gt;C# has this for literal lists:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cs" data-lang="cs"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;lst&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;While Go also has it for function parameter lists:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;param_a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;param_b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What I have to do instead: Meticulously prune commas and re-order elements whenever the list structure changes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;lst&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="numeral-separators"&gt;Numeral Separators&lt;/h1&gt;
&lt;h2 id="found-in-c-go-javascript"&gt;Found In: C#; Go; JavaScript;&lt;/h2&gt;
&lt;h2 id="not-found-in-dart"&gt;Not Found In: Dart;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cs" data-lang="cs"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1_500_000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;{i}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1500000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="byte-literals"&gt;Byte Literals&lt;/h1&gt;
&lt;h2 id="found-in-c-go-javascript-1"&gt;Found In: C#; Go; JavaScript;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cs" data-lang="cs"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0xFF&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;{i}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 255&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="typed-range-literals"&gt;Typed Range Literals&lt;/h1&gt;
&lt;h2 id="found-in-ada"&gt;Found In: ADA&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve never used these because they dont exist in any language except ADA, but I really wish they were more common.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ADA" data-lang="ADA"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;with&lt;/span&gt; &lt;span class="nn"&gt;Ada.Text_IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;Ada.Text_IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;procedure&lt;/span&gt; &lt;span class="nf"&gt;Learn&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;subtype&lt;/span&gt; &lt;span class="kt"&gt;Alphabet&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;Character&lt;/span&gt; &lt;span class="kr"&gt;range&lt;/span&gt; &lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;A&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;Z&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Put_Line&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Learning Ada from &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;Alphabet&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;First&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; to &amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;Alphabet&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;Last&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="nf"&gt;Learn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="default-function-parameters"&gt;Default Function Parameters&lt;/h1&gt;
&lt;h2 id="found-in-c-javascript-python-most-languages-tbh"&gt;Found In: C#; JavaScript; Python; Most languages tbh&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{i} and {a}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#34;0 and abc&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#34;5 and abc&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;xyz&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#34;10 and xyz&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What I have to do instead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cs" data-lang="cs"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;abc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="function-overloading"&gt;Function Overloading&lt;/h1&gt;
&lt;h2 id="notably-missing-from-dart"&gt;Notably missing from: Dart&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cs" data-lang="cs"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;int&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SomeStruct&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;retrun&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Struct&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SomeStruct&lt;/span&gt; &lt;span class="n"&gt;ss&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SomeStruct&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SomeStruct&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="n"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// [&amp;#34;int&amp;#34;, &amp;#34;string&amp;#34;, &amp;#34;Struct&amp;#34;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What I have to do instead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dart" data-lang="dart"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;f_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;int&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;f_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;f_class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Object&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SomeStruct&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;runtimeType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;f_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;f_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;f_class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="chained-evaluators"&gt;Chained Evaluators&lt;/h1&gt;
&lt;h2 id="found-in-nowhere"&gt;Found In: Nowhere?&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cs" data-lang="cs"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What I have to do instead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cs" data-lang="cs"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="object-assigment-shorthand"&gt;Object Assigment Shorthand&lt;/h1&gt;
&lt;h2 id="found-in-rust-go"&gt;Found In: Rust; Go&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;S&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;: &lt;span class="kt"&gt;i32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nc"&gt;name&lt;/span&gt;: &lt;span class="nb"&gt;String&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;: &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;xyz&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;: &lt;span class="kt"&gt;i32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;/// But using shorthand, as long as the symbol name and the field name are the same,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;/// the field name can be omitted in favor of the symbol
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s_short&lt;/span&gt;: &lt;span class="nc"&gt;S&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What I have to do instead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-rust" data-lang="rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;S&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;: &lt;span class="kt"&gt;i32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nc"&gt;name&lt;/span&gt;: &lt;span class="nb"&gt;String&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;: &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;xyz&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;: &lt;span class="kt"&gt;i32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s_long&lt;/span&gt;: &lt;span class="nc"&gt;S&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;: &lt;span class="nc"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;: &lt;span class="nc"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="spread"&gt;Spread&lt;/h1&gt;
&lt;h2 id="found-in-javascript-dart"&gt;Found In: JavaScript; Dart;&lt;/h2&gt;
&lt;p&gt;This one has many uses, including spreading arguments into function call parameter lists but what I wnat to focus on is the ability to create new lists and objects. Taken from the MDN docs:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;shoulders&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;knees&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lyrics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;head&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;and&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;toes&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What I have to do instead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-JavaScript" data-lang="JavaScript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;shoulders&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;knees&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;head&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lyrics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;shoulders&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;knees&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;lyrics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;and&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;lyrics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;toes&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="null-coalesce"&gt;Null Coalesce&lt;/h1&gt;
&lt;h2 id="found-in-c-javascript"&gt;Found In: C#; JavaScript;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;may_be_null&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;some value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;may_be_null&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;WasNull&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;may_be_null&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;WasNull&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#34;WasNull&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// &amp;#34;some value&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="null-chain"&gt;Null Chain&lt;/h1&gt;
&lt;h2 id="found-in-c-javascript-1"&gt;Found In: C#; JavaScript;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;may_be_null&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;some value&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;may_be_null&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="n"&gt;ToUpper&lt;/span&gt;&lt;span class="p"&gt;()?.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;_&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// null&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;may_be_null&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="n"&gt;ToUpper&lt;/span&gt;&lt;span class="p"&gt;()?.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;_&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [&amp;#34;SOME&amp;#34;, &amp;#34;VALUE&amp;#34;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="if-let"&gt;If Let&lt;/h1&gt;
&lt;h2 id="found-in-rust-kotlin"&gt;Found In: Rust; Kotlin&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-Rust" data-lang="Rust"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;baz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Instead, I have to do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-cs" data-lang="cs"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;baz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Music Channel Part 3 - Branding</title><link>https://example.com/posts/music/channel2/</link><pubDate>Wed, 27 Mar 2019 13:44:13 -0700</pubDate><guid>https://example.com/posts/music/channel2/</guid><description>&lt;p&gt;This is the third in a series of posts about analyzing YouTube music channels.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://example.com/posts/music/channel0"&gt;Part 1 - Music Channel Introduction and Data Collection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://example.com/posts/music/channel1"&gt;Part 2 - Analysis of Channel Activity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 3 - Branding&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="branding"&gt;Branding&lt;/h1&gt;
&lt;p&gt;Remember that we&amp;rsquo;re basing our channel the behavioral patterns of some other channels:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCudKvbd6gvbm5UCYRk5tZKA"target="_blank" rel="noopener noreferrer"&gt;TheSoundYouNeed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCXIyz409s7bNWVcM-vjfdVA"target="_blank" rel="noopener noreferrer"&gt;MajesticCasual&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UC5nc_ZtjKW1htCVZVRxlQAQ"target="_blank" rel="noopener noreferrer"&gt;MrSuicideSheep&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCM9KEEuzacwVlkt9JfJad7g"target="_blank" rel="noopener noreferrer"&gt;Chill Nation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCa1Q2ic8wDlT1WH7LSO_4Sg"target="_blank" rel="noopener noreferrer"&gt;Eton Messy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCJ6td3C9QlPO9O_J5dF4ZzA"target="_blank" rel="noopener noreferrer"&gt;MonsterCat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCjw0SX_9OGFI7buLG4-M0Fw"target="_blank" rel="noopener noreferrer"&gt;MikuMusicNetwork&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Among their other patterns, we&amp;rsquo;re going use them as a base for how to brand our channel as well.&lt;/p&gt;
&lt;p&gt;Branding in this sense is going to include:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Channel Name&lt;/li&gt;
&lt;li&gt;Main graphics, including:
&lt;ul&gt;
&lt;li&gt;icon&lt;/li&gt;
&lt;li&gt;font choices&lt;/li&gt;
&lt;li&gt;style, like whether it is just text or includes some form of art&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Video Style, including:
&lt;ul&gt;
&lt;li&gt;text layover&lt;/li&gt;
&lt;li&gt;background choice&lt;/li&gt;
&lt;li&gt;animations if applicable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Additional graphics, like channel banners&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The types of music we&amp;rsquo;re going to upload, as well as what we&amp;rsquo;ll put in each video description, is a concern for later.&lt;/p&gt;
&lt;p&gt;With that said, let do some research.&lt;/p&gt;
&lt;h1 id="majestic-casual"&gt;Majestic Casual&lt;/h1&gt;
&lt;h2 id="name"&gt;Name&lt;/h2&gt;
&lt;p&gt;The name doesn&amp;rsquo;t conjure up any image in specific, but does have an elevating, relaxed feeling to it. It is majestic, and it is casual. I find the pronunciation of the back-to-back &amp;lsquo;c&amp;rsquo; sounds to be a little difficult.&lt;/p&gt;
&lt;h2 id="main-graphics"&gt;Main Graphics&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;crest&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/majestic/crest.jpg"
alt="Crest of Majestic Casual"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;stamp&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/majestic/stamp.png"
alt="Stamp of Majestic Casual"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;banner&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/majestic/banner.png"
alt="Banner of Majestic Casual"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;search&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/majestic/main.png"
alt="Search Result for Majestic Casual"/&gt;&lt;/p&gt;
&lt;h2 id="video-style"&gt;Video Style&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/majestic/vids.png"
alt="Video Style Overview for Majestic Casual"/&gt;&lt;/p&gt;
&lt;p&gt;One of the things we notice is that there are really two different logos. There&amp;rsquo;s the main one, found on the channel icon and stamped on each video, and the stylized formal one in the banner. I&amp;rsquo;ve chosen to call this duology, which is common, the House Crest / Stamp duology. The House Crest contains the short form of the channel name, and may also contain some other designs. The Stamp tends to contain the full name.&lt;/p&gt;
&lt;p&gt;To throw things off immediately however, Majestic Casual reverses the use of their crest and stamps - they use their crest for everything, and they only use their stamp for the channel banner.&lt;/p&gt;
&lt;p&gt;Majestic Casual does not include any song or artist information in their thumbnails, they only show their own name.&lt;/p&gt;
&lt;p&gt;Majestic Casual also follows a relatively common pattern among some music channels of making their crest just simple text with simple font. The rest of this list won&amp;rsquo;t include any more examples of that, but it is common, presumably among people running channels who do not have any design chops.&lt;/p&gt;
&lt;h3 id="video-1"&gt;Video 1&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=z1iHqt0-zs0"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=z1iHqt0-zs0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Majestic Casual doesn&amp;rsquo;t do animations, and their video graphics are on a what-you-see-is-what-you-get basis with respect to the video thumbnails.&lt;/p&gt;
&lt;p&gt;Case in point:&lt;/p&gt;
&lt;p&gt;Thumbnail:&lt;br&gt;
&lt;img loading="lazy" src="https://example.com/misc/musicchannel/majestic/vtn1.png"
alt="Thumbnail"/&gt;&lt;/p&gt;
&lt;p&gt;Video:&lt;br&gt;
&lt;img loading="lazy" src="https://example.com/misc/musicchannel/majestic/vid1.png"
alt="Majestic Casual Video1 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;Majestic Casual&amp;rsquo;s video graphics break down into showcasing either a&lt;/p&gt;
&lt;p&gt;A) handsome man&lt;br&gt;
B) hot girl, or&lt;br&gt;
C) shot of nature, featuring either A or B or neither.&lt;/p&gt;
&lt;p&gt;We see here demonstrated Type A.&lt;/p&gt;
&lt;h3 id="video-2"&gt;Video 2&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=glK5DW9070w"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=glK5DW9070w&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/majestic/vid2.png"
alt="Majestic Casual Video2 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;Static shot, mostly of nature but there&amp;rsquo;s a cute girl in the middle too.&lt;/p&gt;
&lt;h3 id="video-3"&gt;Video 3&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=R3zj_c272YM"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=R3zj_c272YM&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/majestic/vid3.png"
alt="Majestic Casual Video3 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;Static shot of hot girl.&lt;/p&gt;
&lt;h3 id="style-summary"&gt;Style Summary&lt;/h3&gt;
&lt;p&gt;Majestic Casual is the easiest of all graphic types to mimic. Easy crest, easy stamp, and the only work they put into their video graphics are changing up the background image. For the lazy among is, this is the way to go.&lt;/p&gt;
&lt;p&gt;As far video graphics go too, they&amp;rsquo;re an easy style to consider. Grab some images of scenery or attractive girls from the internet and go to town. Majestic is a channel of minimal effort.&lt;/p&gt;
&lt;p&gt;The main problem with them is one of recognizability. At a glance, Majestic looks generic, although it is likely that everyone else copied them, given how early they were to the scene.&lt;/p&gt;
&lt;h3 id="video-graphic-information"&gt;Video Graphic Information&lt;/h3&gt;
&lt;p&gt;Majestic Casual includes their branding in each frame of the graphic.&lt;/p&gt;
&lt;p&gt;They do not include song information.&lt;/p&gt;
&lt;p&gt;They do not include artist information.&lt;/p&gt;
&lt;p&gt;They do not include genre information.&lt;/p&gt;
&lt;h2 id="additional-graphics"&gt;Additional Graphics&lt;/h2&gt;
&lt;p&gt;Included in the Majestic stamp is this lion emblem, which contains the year they were established.&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/majestic/crest2.png"
alt="Majestic Casual crest 2"/&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not sure how important this is to their branding, it kind of fades into the background in every video. If they dropped it completely from their branding I don&amp;rsquo;t think they&amp;rsquo;d suffer in any capacity.&lt;/p&gt;
&lt;h2 id="about"&gt;About&lt;/h2&gt;
&lt;p&gt;From their About page:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Majestic Casual was born out of pure appreciation for the things we love.
We don’t care about trends, genres, stats or names. We value authenticity and diversity, things that spark our memories and emotions. To find these rare experiences we stay curious and always with open ears and eyes for the undiscovered.
Majestic Casual is a carefully selected collection of things we admire. Our very favorite discoveries shared with curious minds from around the world – the list of recommendations we’d give to our friends who seek for some good advice beside the commercial and algorithm driven mainstream.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="additional-notes"&gt;Additional notes&lt;/h2&gt;
&lt;p&gt;Majestic has gone all out on the other social media site game. An active twitter (last post October 16), an active SoundCloud (last repost October 15), an active Facebook (last post October 13), an active Instagram (last post October 17), an actively maintained Spotify playlist (last updated October 15), and Snapchat.&lt;/p&gt;
&lt;p&gt;What these guys don&amp;rsquo;t have is a real website, although they do have a store, and the main domain redirects to their YouTube channel.&lt;/p&gt;
&lt;h2 id="website"&gt;Website&lt;/h2&gt;
&lt;p&gt;Although they own the majesticcasual.com domain, it&amp;rsquo;s just a redirect to their youtube channel.&lt;/p&gt;
&lt;h1 id="thesoundyouneed"&gt;TheSoundYouNeed&lt;/h1&gt;
&lt;h2 id="name-1"&gt;Name&lt;/h2&gt;
&lt;p&gt;A bold but smooth choice of name. They got what you need, and it&amp;rsquo;s some good sound. Stylistically they chose to run their name together, which makes it easy to search for and gives it that &amp;ldquo;you know it when you see it&amp;rdquo; quality.&lt;/p&gt;
&lt;h2 id="main-graphics-1"&gt;Main Graphics&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;crest&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/tsyn/crest.jpg"
alt="Crest of TheSoundYouNeed"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;stamp&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/tsyn/stamp.png"
alt="Stamp of TheSoundYouNeed"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;banner&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/tsyn/banner.png"
alt="Banner of TheSoundYouNeed"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;search&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/tsyn/main.png"
alt="Search Result for TheSoundYouNeed"/&gt;&lt;/p&gt;
&lt;h2 id="video-style-1"&gt;Video Style&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/tsyn/vids.png"
alt="Video Style Overview for TheSoundYouNeed"/&gt;&lt;/p&gt;
&lt;p&gt;We see another example of the Crest / Stamp duology.&lt;br&gt;
Their crest is a nicely designed symbol that contains their shortened channel name TSYN, for The Sound You Need, along with when they were created (2012, apparently).&lt;/p&gt;
&lt;p&gt;Their crest is also the perfect size to be used as a user-icon, which in recent trends is a circular crop of a rectangular image.&lt;/p&gt;
&lt;p&gt;Their stamp, a somewhat loopy looking font writing out their full name without spaces, TheSoundYouNeed also contains their crest beneath it in a smaller font.&lt;/p&gt;
&lt;p&gt;TheSoundYouNeed does not include any artist or song information in their thumbnails.&lt;/p&gt;
&lt;h3 id="video-1-1"&gt;Video 1&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=f4VmOSgTL6c"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=f4VmOSgTL6c&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/tsyn/vid1.gif"
alt="TheSoundYouNeed Video1 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;This is really involved - the channel stamp is animated out like handwriting, and the background is constantly sifting between different types of pastel colored kaleidoscope fractals.&lt;/p&gt;
&lt;h3 id="video-2-1"&gt;Video 2&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=Exg0Vmkf190"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=Exg0Vmkf190&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/tsyn/vid2.png"
alt="TheSoundYouNeed Video2 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;Unlike the first one, this is a classic TSYN video graphic - no animations, no fancy fractals, just some brightly abstract piece of art, stamped with their logos.&lt;/p&gt;
&lt;h3 id="video-3-1"&gt;Video 3&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=pdwVANZ5LWc"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=pdwVANZ5LWc&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/tsyn/vid3.gif"
alt="TheSoundYouNeed Video3 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;This is like a mix of the previous two styles - there&amp;rsquo;s no handwriting intro, but there are kaleidoscope fractals. Still sticking to the pastel theme here, too.&lt;/p&gt;
&lt;h3 id="style-summary-1"&gt;Style Summary&lt;/h3&gt;
&lt;p&gt;In terms of artistry-per-upload, I don&amp;rsquo;t think anyone on this list will match TSYN. Who among us has the patience to make fractal geometry for each video, that also seems to be beat-aligned with the music? Not me. On the other hand, they&amp;rsquo;re extremely pleasing to look at, and no doubt is responsible for a lot of captured audience attention over the years.&lt;/p&gt;
&lt;p&gt;That handwriting into they sometimes do is also a neat effect, and although more doable than the fractals, because it can be reused, will require some thinking if we choose to go that route.&lt;/p&gt;
&lt;p&gt;TSYN generally chooses an uplifting pastel color theme, which is nice.&lt;/p&gt;
&lt;p&gt;As far as their logos go, I find their crest to be uninspired, but their stamp has a really nice casual feeling to it.&lt;/p&gt;
&lt;h3 id="video-graphic-information-1"&gt;Video Graphic Information&lt;/h3&gt;
&lt;p&gt;TheSoundYouNeed includes their branding in each frame of the graphic.&lt;/p&gt;
&lt;p&gt;They do not include song information.&lt;/p&gt;
&lt;p&gt;They do not include artist information.&lt;/p&gt;
&lt;p&gt;They do not include genre information.&lt;/p&gt;
&lt;h2 id="about-1"&gt;About&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;Subscribe to TSYN and discover The finest music of our time.
✙ Bass ✙ UK House ✙ Future Garage ✙ Lounge music ✙ Hip-Hop ✙ Minimal ✙ &amp;amp; More..
If you want to stay even more up-to-date, you can track us on Facebook, Tumblr, Soundcloud, Twitter and Instagram
- - - - - - - - - - - -
- - - - - - - - - - - -
Contact Us
TheSoundYouNeed
Third Floor, Bankstock Building,
42-44 De Beauvoir Crescent,
London, N1 5SB
Unites Kingdom
(Disclaimer) We do not own all of these songs. All songs found on the YouTube Channel TSYN are for promotional reasons only. Any artistic perspective portrayed in any of the songs comes from the artist of the song only. No views expressed in the songs come from TSYN, Only the artists themselves.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="website-1"&gt;Website&lt;/h2&gt;
&lt;p&gt;Going by their shortened name, they own the domain tysn.co, although it contains nothing but a splash page.&lt;/p&gt;
&lt;h1 id="mrsuicidesheep"&gt;MrSuicideSheep&lt;/h1&gt;
&lt;h2 id="name-2"&gt;Name&lt;/h2&gt;
&lt;p&gt;I think once upon a time I read that the channel owner just chose the name one day during their teenage years and it became so much more than they could ever have hoped for. This would certainly explain its Invader Zim / Newgrounds-y kind of vibe.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s not terrible branding by any measure, though. Through longevity alone it&amp;rsquo;s become an icon of the Youtube Music field, but also it&amp;rsquo;s as unique as it gets. If we were choosing our name with the explicit intention of creating a brand from it, it&amp;rsquo;s likely not the name we would choose, but it&amp;rsquo;s also not precedent. See also, Death Row Records.&lt;/p&gt;
&lt;h2 id="main-graphics-2"&gt;Main Graphics&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;crest&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mss/crest.jpg"
alt="Crest of MrSuicideSheep"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;stamp&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mss/stamp.png"
alt="Stamp of MrSuicideSheep"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;banner&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mss/banner.png"
alt="Banner of MrSuicideSheep"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;search&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mss/main.png"
alt="Search Result for MrSuicideSheep"/&gt;&lt;/p&gt;
&lt;h2 id="video-style-2"&gt;Video Style&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mss/vids.png"
alt="Video Style Overview for MrSuicideSheep"/&gt;&lt;/p&gt;
&lt;p&gt;MrSuicideSheep&amp;rsquo;s House Crest is the grey-tinted sheep, and the Stamp is the black or white Suicide Sheep text. Sometimes this Stamp logo is big, and centered on the thumbnail, other times it&amp;rsquo;s small and in the corner of the picture.&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s notable here is that although the channel is &lt;code&gt;MrSuicideSheep&lt;/code&gt;, the curator seems to have dropped the &lt;code&gt;Mr&lt;/code&gt; from the formal title, as everything is Stamped with just &lt;code&gt;Suicide Sheep&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;MrSuicideSheep does not elect to show song or artist information in the thumbnail.&lt;/p&gt;
&lt;h3 id="video-1-2"&gt;Video 1&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=pKGn7OiBU_8"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=pKGn7OiBU_8&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mss/vid1.gif"
alt="MrSuicideSheep Video1 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;Although the primary graphic is of an attractive, vaguely anime looking girl, there&amp;rsquo;s a modicum of animation with with the blurry black fade in to the channel stamp, following by a blurry fade in to an increasingly crisper still-image.&lt;/p&gt;
&lt;h3 id="video-2-2"&gt;Video 2&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=ig3YIvO0nmI"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=ig3YIvO0nmI&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mss/vid2.gif"
alt="MrSuicideSheep Video2 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;Like can be inferred from the video thumbnail list, MrSuicideSheep&amp;rsquo;s style is all over the place when it comes to the backing video graphic. This one uses some really nice art of a starry sky.&lt;/p&gt;
&lt;h3 id="video-3-2"&gt;Video 3&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=MCVi8Rxig90"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=MCVi8Rxig90&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mss/vid3.gif"
alt="MrSuicideSheep Video3 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;Back to girls for the graphic.&lt;/p&gt;
&lt;p&gt;This one actually has lyrics at the bottom, but due some video capture errors, I was not able to record the lyrics. But that&amp;rsquo;s one interesting way to do it, if you happen to feel like putting in extra effort and also know the lyrics to the song.&lt;/p&gt;
&lt;h3 id="style-summary-2"&gt;Style Summary&lt;/h3&gt;
&lt;p&gt;As far as video graphics go, MrSuicideSheep has a big variety - some are uplifting, cute girls; others are sprawling vistas; others still are drawings and paintings at varying degrees of abstraction. It almost looks like whatever the channel curator happens to be feeling at that particular moment. There is no overarching, cohesive sense of style to the graphics.&lt;/p&gt;
&lt;p&gt;I also find the channel crest to be very strange. It is such a light shade of gray, with such a nondescript graphic in the middle, that my first impression is that of a thumbnail placeholder while some other asset loads in. Of course that is not the case and that is the full graphic.&lt;/p&gt;
&lt;p&gt;Notably that graphic is almost not used - far more widespread if the stamp, containing the slightly loopy font spelling out their name.&lt;/p&gt;
&lt;p&gt;Additionally, although the channel branding is relatively visible in the thumbnails, it is really hard to find in the video graphic beyond the first 5 seconds of the intro animation. If you look carefully you can see it in the bottom right corner, but the focus is clearly on the good pictures instead.&lt;/p&gt;
&lt;h3 id="video-graphic-information-2"&gt;Video Graphic Information&lt;/h3&gt;
&lt;p&gt;MrSuicideSheep includes their branding in each frame of the graphic, but in a very small and unobtrusive way.&lt;/p&gt;
&lt;p&gt;They do not include song information.&lt;/p&gt;
&lt;p&gt;They do not include artist information.&lt;/p&gt;
&lt;p&gt;They do not include genre information.&lt;/p&gt;
&lt;h2 id="about-2"&gt;About&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;On this channel you will find a wide variety of different electronic and sometimes non-electronic music. I strive to find the best and most enjoyable music for you guys. I hope you have a good time here :)
Please submit your music here.
http://submit.mrsuicidesheep.com/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="website-2"&gt;Website&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.mrsuicidesheep.com/"target="_blank" rel="noopener noreferrer"&gt;https://www.mrsuicidesheep.com/&lt;/a&gt; is an owned domain, but it just serves as a portal to advertise branded shirts.&lt;/p&gt;
&lt;h1 id="chill-nation"&gt;Chill Nation&lt;/h1&gt;
&lt;h2 id="name-3"&gt;Name&lt;/h2&gt;
&lt;p&gt;Like the other *Nation channels, this channel&amp;rsquo;s name evokes images of togetherness, comradery by being members of the nation. It reminds me of Red Sox Nation, which is the same thing but for fans of that baseball team.&lt;/p&gt;
&lt;p&gt;The Chill in this particular channel represents the kind of music they post. They&amp;rsquo;ll post songs of significantly different genre to one of their many other channels.&lt;/p&gt;
&lt;p&gt;Their final branding score? 7/10&lt;/p&gt;
&lt;h2 id="main-graphics-3"&gt;Main Graphics&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;crest&lt;/em&gt;&lt;br&gt;
&lt;img loading="lazy" src="https://example.com/misc/musicchannel/cn/crest.jpg"
alt="Crest of Chill Nation"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;stamp&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/cn/stamp.png"
alt="Stamp of Chill Nation"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;banner&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/cn/banner.png"
alt="Banner of Chill Nation"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;search&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/cn/main.png"
alt="Search Result for Chill Nation"/&gt;&lt;/p&gt;
&lt;h2 id="video-style-3"&gt;Video Style&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/cn/vids.png"
alt="Video Style Overview for Chill Nation"/&gt;&lt;/p&gt;
&lt;p&gt;Although Chill Nation follows the Crest / Stamp duology, the Crest half isn&amp;rsquo;t much different from the Stamp half.&lt;/p&gt;
&lt;p&gt;Both spell out &lt;code&gt;Chill Nation&lt;/code&gt; in the same font, the only difference is the font and background color. Additionally, the Stamp half has some palm-trees in the bottom, which is a nice touch of style.&lt;/p&gt;
&lt;p&gt;I actually wonder why they don&amp;rsquo;t just standardize on the Stamp for all their logos, it&amp;rsquo;s much better than the Crest.&lt;/p&gt;
&lt;p&gt;Chill Nation does not elect to show song or artist information in the thumbnail.&lt;/p&gt;
&lt;h3 id="video-1-3"&gt;Video 1&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=03GwlsRZnMY"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=03GwlsRZnMY&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/cn/vid1.gif"
alt="ChillNation Video1 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;Chill Nation tends to go for either some kind of vaguely interesting but structureless colored background, or for some epic vista of nature as their background.&lt;/p&gt;
&lt;p&gt;They have chosen the vista.&lt;/p&gt;
&lt;p&gt;This is also our first introduction to the sheer production of the Trap Nation network &amp;ndash; Smooth crest fly in from off screen displaying all their other channels for a second, the subtle, constant swaying motion of the palm trees inside that crest, the slight pulsing of the snowflakes to the beat of song, and once the song gets underway, in addition to all of the above, they map the waveform to a kind of oil-colored pulse on the circumference of the crest.&lt;/p&gt;
&lt;p&gt;trap Nations love for animation is abundantly apparent, and it&amp;rsquo;s generally a pleasure to look at.&lt;/p&gt;
&lt;h3 id="video-2-3"&gt;Video 2&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=iAakgRlbJok"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=iAakgRlbJok&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/cn/vid2.gif"
alt="ChillNation Video1 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;Like described above, this is one of their formless color choices of background.&lt;/p&gt;
&lt;p&gt;We can see a good example of what the song beats look like when we&amp;rsquo;re deep into the music. Strong pulses and big animations everywhere.&lt;/p&gt;
&lt;p&gt;Plus we can see their smooth &amp;ldquo;Follow on Instagram&amp;rdquo; plug that rolls in at the bottom left for a bit before rolling away.&lt;/p&gt;
&lt;h3 id="video-3-3"&gt;Video 3&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=OUBrVRcnQds"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=OUBrVRcnQds&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I neglected to grab a video capture for this track because by this point it&amp;rsquo;s clear that Chill Nation has no variation. This one was a nature background exactly like the first, and had no other special qualities.&lt;/p&gt;
&lt;h3 id="style-overview"&gt;Style Overview&lt;/h3&gt;
&lt;p&gt;The Trap Nation channels go big on animation, and they put in effort for each video to make it pleasant to look at with the waveform pulsing. Their background choice leaves something to be desired though, because aside form the nature vibes, each video has a really &amp;ldquo;samey&amp;rdquo; kind of feel to it. All that is different is the strength of the waveform.&lt;/p&gt;
&lt;p&gt;These guys are great at branding though. Stamp in the bottom corner, Instagram banners poking out occasionally, the quick &amp;ldquo;did you know we had all these other channels&amp;rdquo; showcase at the beginning of each video. It&amp;rsquo;s all quite fantastic.&lt;/p&gt;
&lt;h3 id="video-graphic-information-3"&gt;Video Graphic Information&lt;/h3&gt;
&lt;p&gt;Chill Nations branding is front and center, the literal focal point of each piece, plus their sister channel showcasing at the start, and just in case you forgot, their stamp is the bottom righthand corner as well.&lt;/p&gt;
&lt;p&gt;They do not include song information.&lt;/p&gt;
&lt;p&gt;They do not include artist information.&lt;/p&gt;
&lt;p&gt;They do not include genre information.&lt;/p&gt;
&lt;h2 id="about-3"&gt;About&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;Welcome to Chill Nation! This channel is the official second channel of &amp;quot;Trap Nation&amp;quot;, at Chill Nation we upload more chill and laid back music you won't hear on Trap Nation.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="website-3"&gt;Website&lt;/h2&gt;
&lt;p&gt;Chill Nation delegates their website to their parent Nations, at &lt;a href="https://nations.io/pages/chill-nation"target="_blank" rel="noopener noreferrer"&gt;https://nations.io/pages/chill-nation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;These guys actually have legit websites with descriptions, proper links, and a dedicated shop.&lt;/p&gt;
&lt;h1 id="eton-messy"&gt;Eton Messy&lt;/h1&gt;
&lt;h2 id="name-4"&gt;Name&lt;/h2&gt;
&lt;p&gt;What&amp;rsquo;s in a name? Not necessarily anything in particular, apparently. Although it sounds like someone&amp;rsquo;s name, it is no such thing. They&amp;rsquo;ve gone for uniqueness above all else - certainly no google search will ever be confused as to what you mean when you ask it for Eton Messy, or any potentially mistyped variation thereof.&lt;/p&gt;
&lt;p&gt;It leaves them with few obvious choices to create any kind of visual link with their name, but there&amp;rsquo;s a certain freedom that comes with that as well, in that they can make anything at all their brand.&lt;/p&gt;
&lt;h2 id="main-graphics-4"&gt;Main Graphics&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;crest&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/em/crest.jpg"
alt="Crest of Eton Messy"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;banner&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/em/banner.png"
alt="Banner of Eton Messy"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;search&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/em/main.png"
alt="Search Result for Eton Messy"/&gt;&lt;/p&gt;
&lt;h2 id="video-style-4"&gt;Video Style&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/em/vids.png"
alt="Video Style Overview for Eton Messy"/&gt;&lt;/p&gt;
&lt;p&gt;Speaking of standardizing on one logo, Eton Messy definitely standardized on the Crest, and it looks good.
Their video stamps prominently include their formal name, but the real draw is the Crest.&lt;/p&gt;
&lt;p&gt;Like every other channel, Eton Messy does not show the song or artist name in the thumbnail.&lt;/p&gt;
&lt;h3 id="video-1-4"&gt;Video 1&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=e6hQand8MjM"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=e6hQand8MjM&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/em/vid1.gif"
alt="Eton Messy Video1 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;A pleasant looking natural background, with a smooth ripple like animation for the fade-in of the stamp, which contains no text except for the initials of the channel.&lt;/p&gt;
&lt;h3 id="video-2-4"&gt;Video 2&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=qs0biWHy5WU"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=qs0biWHy5WU&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/em/vid2.gif"
alt="Eton Messy Video1 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;An abstract piece, pleasant to look at, with the stamp ripple fade-in.&lt;/p&gt;
&lt;h3 id="video-3-4"&gt;Video 3&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=O9N-0krx57k"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=O9N-0krx57k&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/em/vid3.gif"
alt="Eton Messy Video1 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;A pleasant looking tropical background with the stamp ripple fade in.&lt;/p&gt;
&lt;h3 id="style-overview-1"&gt;Style Overview&lt;/h3&gt;
&lt;p&gt;Although the animation of the logo is nice, it becomes clear that Eton Messy puts less effort into the video once the fade-in has been completed. This is fine, this puts them closer to Majestic Casual than, say, MonsterCat, and that&amp;rsquo;s perfectly okay.&lt;/p&gt;
&lt;p&gt;They tend to go for eye-catching backgrounds, the type you&amp;rsquo;d elect to make your desktop wallpaper.&lt;/p&gt;
&lt;p&gt;If their main logo weren&amp;rsquo;t enough to tell you who you were watching, a faded version of it can be found in the bottom righthand corner.&lt;/p&gt;
&lt;h3 id="graphic-overview"&gt;Graphic Overview&lt;/h3&gt;
&lt;p&gt;Eton Messy does not include any information in their video graphics, only the channel stamp.&lt;/p&gt;
&lt;h2 id="about-4"&gt;About&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;Eton Messy is a Youtube channel turned Record label, which has included dance music events and an international DJ outfit, playing various genres within dance music, including disco, house, deep house, tech house, progressive and funky etc.
For DJ bookings/Event enquiries contact:
tim.levy@mn2s.com
Latest playlists ⟼ Spotify http://bit.ly/EMspotify
Latest news ⟼ Facebook http://on.fb.me/R5QGH6
Latest mixes/music ⟼ Soundcloud http://bit.ly/LMFAUi
Latest chat ⟼ Twitter http://bit.ly/PAcpsh
Latest images ⟼ Insta http://bit.ly/2vC0CRS
Track Submissions ⟼ etonmessysubmissions@gmail.com
DJ Promo list ⟼ https://goo.gl/forms/ygDJf9XUoKSLjJXw2
Business (no music please) ⟼ info@etonmessy.com
For DJ bookings/Event enquiries contact:
info@etonmessy.com
For any copyright issues please get in touch: info@etonmessy.com
Enjoy!
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="website-4"&gt;Website&lt;/h2&gt;
&lt;p&gt;Eton Messy are the first guys on this list to have a truly functional website, although it&amp;rsquo;s a bit busy and overly complex.&lt;/p&gt;
&lt;p&gt;They have their latest YouTube posts in a step-through queue at the top, a list of upcoming events they&amp;rsquo;re sponsoring or are otherwise interested in, featured news, and a decent about page.&lt;/p&gt;
&lt;p&gt;Eton Messy gets points for having a real website, but they really need to tone down the busyness.&lt;/p&gt;
&lt;h1 id="monstercat"&gt;Monstercat&lt;/h1&gt;
&lt;h2 id="name-5"&gt;Name&lt;/h2&gt;
&lt;p&gt;These guys know how to have fun. Their brand is that of a goofy, cartoony, cat-thing. Some kind of monster cat.&lt;/p&gt;
&lt;p&gt;No problems with uniqueness here. Even in obscurity, just adding &amp;ldquo;music&amp;rdquo; would have gotten the proper results, and in their immense popularity they completely dominate anything even related to the term.&lt;/p&gt;
&lt;p&gt;Plus it opens the avenue for some fun graphics that link into the name.&lt;/p&gt;
&lt;h2 id="main-graphics-5"&gt;Main Graphics&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;crest&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mc/crest.jpg"
alt="Crest of Monstercat"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;banner&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mc/banner.png"
alt="Banner of Monstercat"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;search&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mc/main.png"
alt="Search Result for Monstercat"/&gt;&lt;/p&gt;
&lt;h2 id="video-style-5"&gt;Video Style&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mc/vids.png"
alt="Video Style Overview for Monstercat"/&gt;&lt;/p&gt;
&lt;p&gt;And now for something completely different.&lt;/p&gt;
&lt;p&gt;Monster Cat has a funky, distinct and silly logo. High contrast, designed by someone with some humor. You&amp;rsquo;ll never mistake this logo for any other logo, which one might reasonably do with nearly everything else on this list.&lt;/p&gt;
&lt;p&gt;They don&amp;rsquo;t even have a regular stamp - sometimes they&amp;rsquo;ll include the album art of the album of the release they&amp;rsquo;re showcasing, but they take a real different approach to how they stamp their video thumbnails:&lt;/p&gt;
&lt;p&gt;Song info is front and center, below a neat waveform visualization of the track in question.
Below that in the left corner is a small crest icon, just enough that you&amp;rsquo;ll know what it is when you see it, but not big enough to make the channel the main focus. For Monstercat, the music is focus, not the Monstercat.&lt;/p&gt;
&lt;h3 id="video-1-5"&gt;Video 1&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=8Bcw-A92Wbs"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=8Bcw-A92Wbs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mc/vid1.gif"
alt="MonsterCat Video1 graphic"/&gt;&lt;/p&gt;
&lt;h3 id="video-2-5"&gt;Video 2&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=TBiJ-RAmCB4"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=TBiJ-RAmCB4&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mc/vid2.gif"
alt="MonsterCat Video1 graphic"/&gt;&lt;/p&gt;
&lt;h4 id="video-3-5"&gt;Video 3&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=fxOjcjl3TFU"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=fxOjcjl3TFU&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mc/vid3.gif"
alt="MonsterCat Video1 graphic"/&gt;&lt;/p&gt;
&lt;h3 id="style-overview-2"&gt;Style Overview&lt;/h3&gt;
&lt;p&gt;Because Monster Cat is now a major record producer, they have access to a lot of awesome album art assets, so they can do some awesome animation with the album art of the artist they are showcasing.&lt;/p&gt;
&lt;p&gt;The background of each MonsterCat video is the album art, animated in some capacity, either lightly, like in Video 2 and 3, or heavily, like in Video 1.&lt;/p&gt;
&lt;p&gt;The most prominent graphic is the standard audio volume meter, meaning you can pretty easily track and follow along with the song just visually.&lt;/p&gt;
&lt;p&gt;The thing that sticks out the most is how respectful MonsterCat is of the artists:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the Artists name is the largest piece of text on the screen&lt;/li&gt;
&lt;li&gt;The song name is always displayed&lt;/li&gt;
&lt;li&gt;In addition to the album art as background, the album art gets to replace the primary MonsterCat logo&lt;/li&gt;
&lt;li&gt;And the artist name gets to replace the MonsertCat logo too, it flips around a lot&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is super nice, and respectful to both listeners and artists&lt;/p&gt;
&lt;h3 id="graphic-overview-1"&gt;Graphic Overview&lt;/h3&gt;
&lt;p&gt;MonsterCat chooses to prioritize artist and song marketing over themselves&lt;/p&gt;
&lt;p&gt;They do not display genre information in the videos, but their video descriptions all contain &lt;code&gt;#hashtags&lt;/code&gt; of the genre, such as &lt;code&gt;#dubstep&lt;/code&gt;, &lt;code&gt;#heavyedm&lt;/code&gt;, etc.&lt;/p&gt;
&lt;h2 id="about-5"&gt;About&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;Unbound, Unlimited, Uncaged! Monstercat breaks the barriers of expectations with a movement that will make 2018 the biggest year in our history.
Monstercat is a new-age Record Label. It is the convergence of an independent label, tech startup and media company. We empower creative people, musicians, artists, developers, entrepreneurs, and influencers young and old. We looked at the problems within the music industry, asked “why not” and have created the “how to”.
If you would like to use Monstercat's music in your own videos or Twitch streams:
https://license.monstercat.com
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="website-5"&gt;Website&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.monstercat.com/"target="_blank" rel="noopener noreferrer"&gt;https://www.monstercat.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Although their branding is goofy, Monstercat doesn&amp;rsquo;t joke around. Their website is the real deal, professional to the core. Their music is front and center, but their artists, publishing information, blog and other aspects are all available at the click of a button.&lt;/p&gt;
&lt;h1 id="mikumusicnetwork"&gt;MikuMusicNetwork&lt;/h1&gt;
&lt;h2 id="name-6"&gt;Name&lt;/h2&gt;
&lt;p&gt;If their video thumbnails didn&amp;rsquo;t give them away their name sure does. These guys are weebs. Their music taste is alright though.&lt;/p&gt;
&lt;p&gt;They don&amp;rsquo;t really live up to their name of being a music network, that&amp;rsquo;s much more like Chill Nations thing, but they get close enough.&lt;/p&gt;
&lt;h2 id="main-graphics-6"&gt;Main Graphics&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;crest&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mmn/crest.jpg"
alt="Crest of MikuMusicNetwork"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;stamp&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mmn/stamp.png"
alt="Stamp of MikuMusicNetwork"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;banner&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mmn/banner.png"
alt="Banner of MikuMusicNetwork"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;search&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mmn/main.png"
alt="Search Result for MikuMusicNetwork"/&gt;&lt;/p&gt;
&lt;h2 id="video-style-6"&gt;Video Style&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mmn/vids.png"
alt="Video Style Overview for MikuMusicNetwork"/&gt;&lt;/p&gt;
&lt;p&gt;Speaking of completely different, once again here&amp;rsquo;s something different. These guys are taking a new spin to the Crest/Stamp duology. There&amp;rsquo;s a base, which is fractal diamonds, and then they switch up what&amp;rsquo;s inside. The crest has a Miku silhouette with a stylized ミク in the middle.&lt;/p&gt;
&lt;p&gt;As for the stamps, there are actually two, The first takes the base crest and drops the middle image, leaving room for cute anime girls to pop out and be framed by the fractals.&lt;/p&gt;
&lt;p&gt;The second stamp is a more traditional take with the name, the short form in this case, written out along with a splashy icon.&lt;/p&gt;
&lt;p&gt;It seems to be random whether one stamp is used over the other.&lt;/p&gt;
&lt;p&gt;The thumbnails take another interesting twist - Instead of prioritizing either the channel name or the artist, the thumbnails prioritize the genre. Each thumbnail is, to varying degrees of clarity, tagged with &lt;code&gt;Electro&lt;/code&gt;, &lt;code&gt;Drum &amp;amp; Bass&lt;/code&gt;, &lt;code&gt;Future Bass&lt;/code&gt;, &lt;code&gt;Lovestep&lt;/code&gt;. That&amp;rsquo;s an interesting take on the thumbnail concept, and I quite like it.&lt;/p&gt;
&lt;p&gt;Additionally, even without the channel name, it&amp;rsquo;s clear where the video is coming from. The concept, style, and execution of the genre tags are so unique, as well as the choice of vivid, bright color pallet anime girls makes it obvious.&lt;/p&gt;
&lt;h3 id="video-1-6"&gt;Video 1&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=oFbljhlRmIQ"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=oFbljhlRmIQ&lt;/a&gt;
graphic: cute anime girl / with icon&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mmn/vid1.gif"
alt="MikuMusicNetwork Video1 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;These guys seem to have an animation budget, although they also seem to have some strange tastes. Each of their videos is a bit jumpy because there&amp;rsquo;s this constant rocking motion of the frame.&lt;/p&gt;
&lt;p&gt;Putting the rocking aside, the graphic is actually super cool. The rotating squares around the center, and the two diamonds showing the name of the artist, and the song are really neat.&lt;/p&gt;
&lt;p&gt;And then their choice of cute anime girl, in this case a catgirl, gets a cool stripe fade in.&lt;/p&gt;
&lt;p&gt;Their stamp is on the bottom, after the crest gets replaced with the catgirl.&lt;/p&gt;
&lt;h3 id="video-2-6"&gt;Video 2&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=53vGcMbQAuQ"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=53vGcMbQAuQ&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mmn/vid2.gif"
alt="MikuMusicNetwork Video1 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;This is the second of two main styles that MMN opts for. This format opts for an entirely different set of logos for themselves, though they kept their animation budget.&lt;/p&gt;
&lt;p&gt;Their Crest becomes the stylized Miku(ミク), and their stamp becomes this themed Hatsune Miku paint splash.&lt;/p&gt;
&lt;p&gt;They stick to their cute anime girl aesthetic, but don&amp;rsquo;t opt for displaying any information about the song.&lt;/p&gt;
&lt;p&gt;As usual, the rocking continues.&lt;/p&gt;
&lt;h3 id="video-3-6"&gt;Video 3&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=Ahlji3K5MuQ"target="_blank" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=Ahlji3K5MuQ&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/mmn/vid3.gif"
alt="MikuMusicNetwork Video1 graphic"/&gt;&lt;/p&gt;
&lt;p&gt;The third video follows the first - rocking, a cool anime girl fade-in, and rotating diamonds.&lt;/p&gt;
&lt;h3 id="style-overview-3"&gt;Style Overview&lt;/h3&gt;
&lt;p&gt;When in comes to the first of their video styles, I find the MikuMusicNetwork to be just as respectful to the artist as MonsterCat is:
Their priority is to showcase cute anime girls, but the artist and the song title are on prominent display.&lt;/p&gt;
&lt;p&gt;However, style 2 is focused on the network, and doesn&amp;rsquo;t showcase anything about the song in question.&lt;/p&gt;
&lt;p&gt;Their animation budget is evident, and appreciated, but they really need to do away with the constant rocking. It&amp;rsquo;s just weird and distracting.&lt;/p&gt;
&lt;h3 id="graphic-overview-2"&gt;Graphic Overview&lt;/h3&gt;
&lt;p&gt;MMN sometimes chooses to display artist information, and sometimes doesn&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;Notably, the thumbnails actually contain the information all the time, with additional genre information, as available,&lt;/p&gt;
&lt;p&gt;It would be nice if this information was there all the time.&lt;/p&gt;
&lt;p&gt;Their logo is always present, either in the intro fade-in, or at the bottom using one of their two splash icons.&lt;/p&gt;
&lt;h2 id="about-6"&gt;About&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;Welcome to MikuMusicNetwork, a Anime inspired music promotion channel that focuses on bringing smaller artists and bigger ones alike to one convenient place for you to listen to, from the hardest of drops to the chillest of vocals!
Want your track to be uploaded or do you want to label your latest release with us? That is possible! Click on Track Submissions and fill in the form. We'll respond as soon as we can!
Be aware that we get plenty of submissions and we are unable to respond to all of them! We are working currently on a better method that allows us to respond to all submissions!
Music Producer or Label? Have an issue regarding a video hosted on this channel? Please contact us through PM and we will respond as quick as possible!
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="website-6"&gt;Website&lt;/h2&gt;
&lt;p&gt;There is no website associated with this channel.&lt;/p&gt;</description></item><item><title>Music Channel Part 2 - Stats</title><link>https://example.com/posts/music/channel1/</link><pubDate>Tue, 26 Mar 2019 15:50:58 -0700</pubDate><guid>https://example.com/posts/music/channel1/</guid><description>&lt;p&gt;This is the second in a series of posts about analyzing YouTube music channels.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://example.com/posts/music/channel0"&gt;Part 1 - Music Channel Introduction and Data Collection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Part 2 - Analysis of Channel Activity&lt;/li&gt;
&lt;li&gt;&lt;a href="https://example.com/posts/music/channel2"&gt;Part 3 - Branding&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="your-questions-answered"&gt;Your Questions, Answered&lt;/h1&gt;
&lt;p&gt;We left off last time with a freshly created database full of information we could query. We sought to answer a few questions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;How many videos should we seed our channel with?&lt;/li&gt;
&lt;li&gt;How often should we upload?&lt;/li&gt;
&lt;li&gt;Should we upload more than video at once?&lt;/li&gt;
&lt;li&gt;How long can we wait between uploads if something goes wrong?&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="channel-seeding"&gt;Channel Seeding?&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ll take the first upload date of each of our channels and see what their total upload count is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ChannelPublish&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DaysSinceLastPublish&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which returns the following data:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Channel&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Majestic Casual&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ChillNation&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Eton Messy&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MikuMusicNetwork&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monstercat: Uncaged&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MrSuicideSheep&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TheSoundYouNeed&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;With the exception of Majestic Casual, no one seems to seed their channel. That makes things easy on us.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Question:&lt;/em&gt; How many videos should we seed our channel with?&lt;br&gt;
&lt;em&gt;Answer:&lt;/em&gt; None&lt;/p&gt;
&lt;h2 id="upload-pace"&gt;Upload Pace?&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DaysSinceLastPublish&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AvgDaysBetweenPosts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ChannelPublish&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DaysSinceLastPublish&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;GROUP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Channel&lt;/th&gt;
&lt;th&gt;Average Days Between Upload&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ChillNation&lt;/td&gt;
&lt;td&gt;1.72&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Eton Messy&lt;/td&gt;
&lt;td&gt;3.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Majestic Casual&lt;/td&gt;
&lt;td&gt;1.52&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MikuMusicNetwork&lt;/td&gt;
&lt;td&gt;2.81&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monstercat: Uncaged&lt;/td&gt;
&lt;td&gt;2.04&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MrSuicideSheep&lt;/td&gt;
&lt;td&gt;1.34&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TheSoundYouNeed&lt;/td&gt;
&lt;td&gt;6.65&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This might not tell the whole story though, so lets see if we can get some sense of upload pace vs channel popularity.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll look at a channels lifetime views, along with the average number of views per song per channel. If we take all this information together, we&amp;rsquo;ll get a stronger sense of where upload pace fits into the scene.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DaysSinceLastPublish&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AvgDaysBetweenPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Views&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VideoStats&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TotalChannelViews&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;CAST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Views&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VideoStats&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AvgViewsPerUpload&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ChannelPublish&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DaysSinceLastPublish&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;GROUP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AvgViewsPerUpload&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Channel&lt;/th&gt;
&lt;th&gt;Average Days Between Upload&lt;/th&gt;
&lt;th&gt;Total Channel Views&lt;/th&gt;
&lt;th&gt;Average Views per Upload&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TheSoundYouNeed&lt;/td&gt;
&lt;td&gt;6.65&lt;/td&gt;
&lt;td&gt;1,965,150,738&lt;/td&gt;
&lt;td&gt;6,102,952&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MrSuicideSheep&lt;/td&gt;
&lt;td&gt;1.34&lt;/td&gt;
&lt;td&gt;3,912,749,521&lt;/td&gt;
&lt;td&gt;1,956,374&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ChillNation&lt;/td&gt;
&lt;td&gt;1.72&lt;/td&gt;
&lt;td&gt;1,731,630,505&lt;/td&gt;
&lt;td&gt;1,777,854&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monstercat: Uncaged&lt;/td&gt;
&lt;td&gt;2.04&lt;/td&gt;
&lt;td&gt;2,164,378,038&lt;/td&gt;
&lt;td&gt;1,592,625&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Majestic Casual&lt;/td&gt;
&lt;td&gt;1.52&lt;/td&gt;
&lt;td&gt;1,704,478,658&lt;/td&gt;
&lt;td&gt;893,801&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Eton Messy&lt;/td&gt;
&lt;td&gt;3.5&lt;/td&gt;
&lt;td&gt;113,665,075&lt;/td&gt;
&lt;td&gt;143,155&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MikuMusicNetwork&lt;/td&gt;
&lt;td&gt;2.81&lt;/td&gt;
&lt;td&gt;12,827,204&lt;/td&gt;
&lt;td&gt;12,453&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;These stats are a bit wonky because each channel tends to have 3 or 4 super-outliers. For example, TheSoundYouNeed&amp;rsquo;s &lt;a href="https://www.youtube.com/watch?v=4ZHwu0uut3k"target="_blank" rel="noopener noreferrer"&gt;Tom Odell - Another Love (Zwette Edit)&lt;/a&gt; has 395 million views, which is a full 20% of that channels views. There&amp;rsquo;s more statistical magic we could do involving outlier removal and standard deviations, but we&amp;rsquo;re just going to leave it is and say that we should try to target one upload every one or two days.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Question&lt;/em&gt; How often should we upload?&lt;br&gt;
&lt;em&gt;Answer:&lt;/em&gt; Every day, or every other day.&lt;/p&gt;
&lt;h2 id="batch-uploads"&gt;Batch Uploads?&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BatchSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TimesUploaded&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ChannelPublish&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;GROUP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TimesUploaded&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Channel&lt;/th&gt;
&lt;th&gt;Batch Size&lt;/th&gt;
&lt;th&gt;Times Uploaded&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ChillNation&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;914&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ChillNation&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Eton Messy&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;722&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Eton Messy&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Eton Messy&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Majestic Casual&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1318&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Majestic Casual&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;159&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Majestic Casual&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;38&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Majestic Casual&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Majestic Casual&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Majestic Casual&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Majestic Casual&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Majestic Casual&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MikuMusicNetwork&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;474&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MikuMusicNetwork&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;269&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MikuMusicNetwork&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monstercat: Uncaged&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1247&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monstercat: Uncaged&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;56&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MrSuicideSheep&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1938&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MrSuicideSheep&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;31&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TheSoundYouNeed&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;302&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TheSoundYouNeed&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TheSoundYouNeed&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;As we can see, on days that a channel uploads, they only upload one song. There&amp;rsquo;s a small amount of variation within most channels, and the MikuMusicNetwork is an outlier that uploads twice a day roughly a quarter of the time, but it seems with only some exceptions that once-per-upload-day is the norm.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Question:&lt;/em&gt; Should we upload more than video at once?&lt;br&gt;
&lt;em&gt;Answer:&lt;/em&gt; No.&lt;/p&gt;
&lt;h2 id="upload-gaps"&gt;Upload Gaps?&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DaysSinceLastPublish&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MaxDaysBetweenPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DaysSinceLastPublish&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AvgDaysBetweenPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Views&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VideoStats&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TotalChannelViews&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;CAST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Views&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VideoStats&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AvgViewsPerUpload&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ChannelPublish&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DaysSinceLastPublish&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;GROUP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AvgViewsPerUpload&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Channel&lt;/th&gt;
&lt;th&gt;Max Upload Gap&lt;/th&gt;
&lt;th&gt;Total Channel Views&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ChillNation&lt;/td&gt;
&lt;td&gt;149&lt;/td&gt;
&lt;td&gt;1731630505&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Eton Messy&lt;/td&gt;
&lt;td&gt;178&lt;/td&gt;
&lt;td&gt;113665075&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Majestic Casual&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;1704478658&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MikuMusicNetwork &amp;amp; Records&lt;/td&gt;
&lt;td&gt;59&lt;/td&gt;
&lt;td&gt;12827204&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monstercat: Uncaged&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;2164378038&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MrSuicideSheep&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;td&gt;3912749521&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TheSoundYouNeed&lt;/td&gt;
&lt;td&gt;56&lt;/td&gt;
&lt;td&gt;1965150738&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;We&amp;rsquo;ll quickly drop into SQLite DB Browser&amp;rsquo;s ploting mode to graph Upload Gap (x) vs Views (y):&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/sql4.png"
alt="Upload Gap Graph"/&gt;&lt;/p&gt;
&lt;p&gt;We see a correlation between fewer days between uploads and higher total view counts, but again this is basically raw data that has quirks like super-videos going uncompensated for.&lt;/p&gt;
&lt;p&gt;Of course this basically fits with our impression of YouTube, right? Regular uploads are better than sporadic uploads.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Question:&lt;/em&gt; How long can we wait between uploads if something goes wrong?&lt;br&gt;
&lt;em&gt;Answer:&lt;/em&gt; Try to keep it below 150 days, but don&amp;rsquo;t sweat it.&lt;/p&gt;
&lt;h1 id="summary"&gt;Summary&lt;/h1&gt;
&lt;p&gt;So in summary we&amp;rsquo;re not going to seed our channel, and we&amp;rsquo;ll aim to upload about 3 or 4 times a week to start off with.&lt;/p&gt;
&lt;p&gt;Now that we have a sense of what we need to be committing to regarding our upload pattern, we can move on to the more fun aspects of channel curation, such as picking out a name and a logo.&lt;/p&gt;
&lt;p&gt;And once that is done, we&amp;rsquo;ll start picking out our initial upload set.&lt;/p&gt;</description></item><item><title>Music Channel Part 1 - Data</title><link>https://example.com/posts/music/channel0/</link><pubDate>Mon, 25 Mar 2019 18:17:32 -0700</pubDate><guid>https://example.com/posts/music/channel0/</guid><description>&lt;p&gt;This is the first in a series of posts about analyzing YouTube music channels.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Part 1 - Music Channel Introduction and Data Collection&lt;/li&gt;
&lt;li&gt;&lt;a href="https://example.com/posts/music/channel1"&gt;Part 2 - Analysis of Channel Activity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://example.com/posts/music/channel2"&gt;Part 3 - Branding&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="background"&gt;Background&lt;/h1&gt;
&lt;p&gt;I often listen to new music on YouTube because their discovery systems unearth some occasionally great finds. After a while of listening there however you begin to realize that there are only a handful of channels that get recommended to you, and they all seem to just upload songs and let the views roll in, not unlike a radio DJ. Sometimes these channels become so successful that artists will begin to sign with the channels for exclusive releases, in effect turning the channels into a de-facto label. Some of these channels have even turned into de-jure labels, such as Proximity.&lt;/p&gt;
&lt;p&gt;I thought it would be a fun experiment to see if I could create a YouTube channel of my own doing the same thing these channels were doing. It seemed easy enough, just upload a few songs here and there. But before I began, I wanted to get a sense of what, exactly, these channels were doing, what their upload schedule was actually like, what were they like when they started out, how did they evolve, etc.&lt;/p&gt;
&lt;p&gt;This series of posts describes just such an analysis of a selection of music channels on YouTube.&lt;/p&gt;
&lt;h1 id="data-collection"&gt;Data Collection&lt;/h1&gt;
&lt;p&gt;First, I wanted to get a sense of how these channels upload songs, which would help inform me on how run my own channel. The questions that I wanted answers to before starting were:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;How many videos should we seed our channel with?&lt;/li&gt;
&lt;li&gt;How often should we upload?&lt;/li&gt;
&lt;li&gt;Should we upload more than video at once?&lt;/li&gt;
&lt;li&gt;How long can we wait between uploads if something goes wrong?&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="yt-tracker"&gt;YT Tracker&lt;/h2&gt;
&lt;p&gt;To answer these questions, I had to get some data first. I wasn&amp;rsquo;t about to scrape YouTube myself, so after some googling for some tools that could help me gather some channel stats, I came across the excellent &lt;a href="https://chrome.google.com/webstore/detail/yt-tracker/nhebilhcolhlinfcpgbpbecjajeiiajc"target="_blank" rel="noopener noreferrer"&gt;YT Tracker&lt;/a&gt;, an addon for Google Sheets that pulls all kinds of channel information for you.&lt;/p&gt;
&lt;p&gt;You can find its full functionality detailed &lt;a href="https://www.syncwithtech.org/track-youtube-videos-channels/"target="_blank" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="channel-list"&gt;Channel List&lt;/h3&gt;
&lt;p&gt;First I seeded YT Tracker with a list of 7 of the channels I either use or happen to come across often:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCudKvbd6gvbm5UCYRk5tZKA"target="_blank" rel="noopener noreferrer"&gt;TheSoundYouNeed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCXIyz409s7bNWVcM-vjfdVA"target="_blank" rel="noopener noreferrer"&gt;MajesticCasual&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UC5nc_ZtjKW1htCVZVRxlQAQ"target="_blank" rel="noopener noreferrer"&gt;MrSuicideSheep&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCM9KEEuzacwVlkt9JfJad7g"target="_blank" rel="noopener noreferrer"&gt;ChillNation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCa1Q2ic8wDlT1WH7LSO_4Sg"target="_blank" rel="noopener noreferrer"&gt;Eton Messy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCJ6td3C9QlPO9O_J5dF4ZzA"target="_blank" rel="noopener noreferrer"&gt;MonsterCat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCjw0SX_9OGFI7buLG4-M0Fw"target="_blank" rel="noopener noreferrer"&gt;MikuMusicNetwork&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;As the developer of YT Tracker writes on his page, it can sometimes be tricky to extract the channel name from some pages. If you&amp;rsquo;re on a page for a given video, the main uploader link in the video description will contain the channel name - this goes for accounts that are flagged as &amp;ldquo;user&amp;rdquo;, as well for for &amp;ldquo;channel&amp;rdquo; accounts. This is important because YT Tracker only operates on channel ids.&lt;/p&gt;
&lt;h3 id="adding-to-a-yt-tracker-sheet"&gt;Adding to a YT Tracker Sheet&lt;/h3&gt;
&lt;p&gt;We add the channel ids to the first column:&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/YtTracker_ChannelIds.png"
alt="Channel Ids"/&gt;&lt;/p&gt;
&lt;p&gt;YT Tracker takes care of filling in the rest of the data automatically. It&amp;rsquo;s really quite magical.&lt;/p&gt;
&lt;h3 id="grabbing-video-data"&gt;Grabbing Video Data&lt;/h3&gt;
&lt;p&gt;Next we want to grab video data from each channel. With the channel id cell of the channel we want to grab highlighted, we use the Add-Ons drop down menu to select YT Tracker and select &lt;code&gt;Fetch Channel Videos&lt;/code&gt;, which will create a new sheet for us, populated with video upload data:&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/YtTracker_VideoData.png"
alt="Video Data"/&gt;&lt;/p&gt;
&lt;p&gt;You have to do this highlight-menu-fetch process for each item in our list.&lt;/p&gt;
&lt;h3 id="exporting"&gt;Exporting&lt;/h3&gt;
&lt;p&gt;Next we&amp;rsquo;ll take each sheet and Save-As &lt;code&gt;.csv&lt;/code&gt; to some folder on our computer.&lt;/p&gt;
&lt;p&gt;This is the first step to getting the data into a SQL-queryable format.&lt;/p&gt;
&lt;h1 id="data-cleanup-part-1"&gt;Data Cleanup Part 1&lt;/h1&gt;
&lt;p&gt;Every project that involves data will require some form of cleanup process, this is no different.&lt;/p&gt;
&lt;h2 id="csv-cleanup"&gt;CSV Cleanup&lt;/h2&gt;
&lt;h3 id="adding-channel-id"&gt;Adding Channel Id&lt;/h3&gt;
&lt;p&gt;Because we&amp;rsquo;re going to end up putting all this data into SQLite, we need to do some work on the CSV files first. To make our data amenable, one of the things we&amp;rsquo;ll do is add the channel name to each row of each CSV.&lt;/p&gt;
&lt;p&gt;For example, we&amp;rsquo;re going to turn:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csv" data-lang="csv"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;Video Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;Thumbnail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;Publish On&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;# of Views&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;# of Likes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;# of Dislikes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;# of Comments&lt;/span&gt;&lt;span class="p"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;x8Y2iCSGSXI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;Nora Van Elken - Best I Ever Had&lt;/span&gt;&lt;span class="p"&gt;,,&lt;/span&gt;&lt;span class="s"&gt;2018-10-11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;3 : 02&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;58,593&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;3,082&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;78&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;141&lt;/span&gt;&lt;span class="p"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;into&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csv" data-lang="csv"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;Video Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;Thumbnail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;Publish On&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;# of Views&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;# of Likes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;# of Dislikes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;# of Comments&lt;/span&gt;&lt;span class="p"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s"&gt;ChillNation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;x8Y2iCSGSXI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;Nora Van Elken - Best I Ever Had&lt;/span&gt;&lt;span class="p"&gt;,,&lt;/span&gt;&lt;span class="s"&gt;2018-10-11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;3:02&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;58,593&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;3,082&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;78&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;141&lt;/span&gt;&lt;span class="p"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I did this with the following two regexs:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;find: ^([0-9A-Za-z_-]*)?,
replace: ChillNation,$1,
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where ChillNation is whatever channel you&amp;rsquo;re actually working with.&lt;/p&gt;
&lt;p&gt;Be sure to add the Column name of ChannelName before Video Id.&lt;/p&gt;
&lt;h3 id="patching-up-time"&gt;Patching up Time&lt;/h3&gt;
&lt;p&gt;The timestamps are bit messy - consistent, but full of weird spaces that make parsing a bit of a pain.&lt;/p&gt;
&lt;p&gt;We want to turn&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;3 : 02
1 : 26 : 27
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;into&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;3:02
1:26:27
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We fix this with the following regex find/replaces:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;find: ([0-9]{0,2})\s+:\s+([0-9]{0,2})
replace: $1:$2
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Which we run twice to catch any hour+ long tracks with hh:mm:ss formatting.&lt;/p&gt;
&lt;h3 id="changing-column-names"&gt;Changing Column Names&lt;/h3&gt;
&lt;p&gt;The exported named columns would make for some difficult SQL querying. To make our life easier, we&amp;rsquo;ll change the names:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Channel,VID,Title,Thumbnail,Published,Duration,Views,Likes,Dislikes,Comments
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="sql-part-1"&gt;SQL Part 1&lt;/h2&gt;
&lt;p&gt;I like to do as much data processing and analysis in python and sqlite as possible. We&amp;rsquo;ll do that here too, by importing all our exported files into a new Sqlite database.&lt;/p&gt;
&lt;p&gt;I prefer to use &lt;a href="http://sqlitebrowser.org/"target="_blank" rel="noopener noreferrer"&gt;DB Browser for SQLite&lt;/a&gt;, which is a Windows GUI tool.&lt;/p&gt;
&lt;p&gt;Using the &lt;code&gt;Import -&amp;gt; Table From CSV File&lt;/code&gt; menu option, we add in all our exported csv files, saying okay to the &lt;code&gt;append to table?&lt;/code&gt; warning. You can call the new table whatever you like, I&amp;rsquo;ve chosen &lt;code&gt;VideoStats&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/newsqlite.png"
alt="Import From CSV"/&gt;&lt;/p&gt;
&lt;h3 id="table"&gt;Table&lt;/h3&gt;
&lt;p&gt;After this important, we end up with a table that looks something like this:&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/sql0.png"
alt="Table Data"/&gt;&lt;/p&gt;
&lt;p&gt;While a good first step, I realized here that the data wasn&amp;rsquo;t actually in the most useful form. Views, Likes, Dislikes, and Comments all have commas in their data, which makes them strings, not integers.&lt;/p&gt;
&lt;p&gt;Additionally, Duration has colons in it, which makes it a string too.&lt;/p&gt;
&lt;p&gt;The exception is the Published field, which SQLite handles correctly as a date.&lt;/p&gt;
&lt;h3 id="adding-a-duration_ms-column"&gt;Adding a Duration_Ms Column&lt;/h3&gt;
&lt;p&gt;Although I want to fix the duration field, I think it might be useful to keep its original form around because its very human-readable. So we&amp;rsquo;ll add another column to our table, &lt;code&gt;Duration_Ms&lt;/code&gt;, which will represent the duration of the song in milliseconds:&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/sql1.png"
alt="Duration MS"/&gt;&lt;/p&gt;
&lt;h2 id="python-cleanup-part-1"&gt;Python Cleanup Part 1&lt;/h2&gt;
&lt;p&gt;We&amp;rsquo;ll use Python here to remedy these errors. This is python at its best - small scripts for data processing.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;sqlite3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;pathlib&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;dateutil.parser&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;PDT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sqlfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;./ytrackerstats/ytstats.db&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fixDuration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dur&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dur&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;TotalSeconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;multiplier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;seconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;multiplier&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;TotalSeconds&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;seconds&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;TotalSeconds&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dur&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;???&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fixCommaNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;com&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;undefined&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;repl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;repl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;com&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;??&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;FetchAllFromVideoStats&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sqlfile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;SELECT VID,Duration,Views,Likes,Dislikes,Comments FROM VideoStats&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;newRs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;like&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;disl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;comm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;fixed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fixDuration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dur&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;fixCommaNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;fixCommaNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;like&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;fixCommaNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;disl&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;fixCommaNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;comm&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;vid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;newRs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;newRs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;FixVids&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tups&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sqlfile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;UPDATE VideoStats SET Duration_Ms=?, Views=?, Likes=?, Dislikes=?, Comments=? WHERE VID=?&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;executemany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tups&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;03:01:46&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;fixDuration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;10906000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;comma1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;5,600&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;fixCommaNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;comma1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;5600&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;comma2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;56&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;fixCommaNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;comma2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;56&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;comma3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;fixCommaNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;comma3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;vids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FetchAllFromVideoStats&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;FixVids&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The summary of this script is that we remove commas from any numbers, and convert durations to their ms representation, which we update into the &lt;code&gt;Duration_Ms&lt;/code&gt; field.&lt;/p&gt;
&lt;h2 id="sql-part-2"&gt;SQL Part 2&lt;/h2&gt;
&lt;p&gt;Now that most of the data was in SQL, and in a good format, I started running some queries. For instance:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Published&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Published&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Uploaded&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VideoStats&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;GROUP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;Published&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Published&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which returns the number of tracks uploaded per channel per day. This is a useful query - Do people typically upload more than one track per day? Who knows? Well now, you do! With the power of Group By.&lt;/p&gt;
&lt;h3 id="another-table"&gt;Another Table&lt;/h3&gt;
&lt;p&gt;The problem is that some of these queries started to get a bit cumbersome and unwieldly. Running multiple versions got tiring pretty quick. The soluton was another table. I called this one &lt;code&gt;ChannelPublish&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I also wanted another piece of data, which would have otherwise been really difficult to extract using just plain SQL: Days since last publish.&lt;/p&gt;
&lt;p&gt;It seemed important to know how many days had passed between consecutive uploads. This is information that can be derived from the data as it exists, but it&amp;rsquo;d be a lot nicer if we had a dedicated field for it. This process is known as Feature Engineering, and is common when working with tabular data.&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/sql2.png"
alt="Channel Publish Table"/&gt;&lt;/p&gt;
&lt;h3 id="select-insert"&gt;Select Insert&lt;/h3&gt;
&lt;p&gt;To get data into our new table, we run the following query:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;INTO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ChannelPublish2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Published&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Published&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Published&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Uploaded&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VideoStats&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;GROUP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;Published&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Published&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which gets us a table composed entirely of the previous group-by query results.&lt;/p&gt;
&lt;h2 id="python-cleanup-part-2"&gt;Python Cleanup Part 2&lt;/h2&gt;
&lt;p&gt;Moving back to python, we&amp;rsquo;ll update our script to calculate the number of days since the last upload:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#! /usr/bin/python&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;sqlite3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;pathlib&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;dateutil.parser&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;PDT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;sqlfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;./ytrackerstats/ytstats.db&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="n"&gt;Edited&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;brevity&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;DateDiffRaw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;diff&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;FetchAddDaysSinceLastPublish&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sqlfile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;SELECT Id, Channel, Published FROM ChannelPublish ORDER BY Channel, Published ASC&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;currentChannel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;updates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;currentChannel&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;currentChannel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# RESET!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;date_raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PDT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date_raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateDiffRaw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;updates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;updates&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;UpdateDaysSinceLastPublish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tups&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sqlfile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;UPDATE ChannelPublish SET DaysSinceLastPublish=? WHERE Id=?&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;executemany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tups&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;03:01:46&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;fixDuration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;10906000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;comma1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;5,600&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;fixCommaNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;comma1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;5600&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;comma2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;56&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;fixCommaNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;comma2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;56&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;comma3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;fixCommaNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;comma3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dateEarlier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2018-10-09&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dateLater&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;2018-10-10&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;d1p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PDT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dateEarlier&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;d2p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PDT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dateLater&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;DateDiffRaw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d1p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d2p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# test()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# vids = FetchAllFromVideoStats()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# FixVids(vids)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FetchAddDaysSinceLastPublish&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;UpdateDaysSinceLastPublish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="sql-again"&gt;SQL Again&lt;/h2&gt;
&lt;p&gt;Now we have a table of very useful information:&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://example.com/misc/musicchannel/sql3.png"
alt="Useful Information"/&gt;&lt;/p&gt;
&lt;p&gt;Which lets us easily query for stuff like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-SQL" data-lang="SQL"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DaysSinceLastPublish&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MaxDaysBetweenPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;CAST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;avg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DaysSinceLastPublish&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;FLOAT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AvgDaysBetweenPosts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ChannelPublish&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;WHERE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DaysSinceLastPublish&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;--AND Published &amp;gt; date(&amp;#34;2018-01-01&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;GROUP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="summary"&gt;Summary&lt;/h1&gt;
&lt;p&gt;This first post covers the initial setup for being able to graph, chart and otherwise ask statistical questions about some YouTube channels that we&amp;rsquo;re going to use as a basis for our own music channel.&lt;/p&gt;
&lt;p&gt;We gathered our initial dataset, cleaned that data, and put it all into a SQLite file for use later.&lt;/p&gt;
&lt;p&gt;Next time, we&amp;rsquo;ll cover the channel setup, and answer the questions like:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;How many videos should we seed our channel with?&lt;/li&gt;
&lt;li&gt;How often should we upload?&lt;/li&gt;
&lt;li&gt;Should we upload more than video at once?&lt;/li&gt;
&lt;li&gt;How long can we wait between uploads if something goes wrong?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once that information is covered, we&amp;rsquo;ll create a list of songs to upload and check to see if our favorite channels have covered them already. The less channels a song appears on of course, the better for our channel. We&amp;rsquo;re not just trying to be a mirror of the others, after all.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll also see what we can do about creating a Channel Icon, selecting some backgrounds, adding that must-have waveform pulse animation, and some initial channel curation.&lt;/p&gt;</description></item></channel></rss>