<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Gideon Wolfe</title>
    <link>https://gideonwolfe.com/</link>
    <description>Recent content on Gideon Wolfe</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Sat, 07 Nov 2020 00:00:00 +0000</lastBuildDate>
    
	<atom:link href="https://gideonwolfe.com/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>How to add a picom toggle to polybar</title>
      <link>https://gideonwolfe.com/posts/workflow/i3/picom/</link>
      <pubDate>Sat, 07 Nov 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/workflow/i3/picom/</guid>
      <description>&lt;h1 id=&#34;intro&#34;&gt;Intro&lt;/h1&gt;
&lt;p&gt;I think a tasteful blur and a bit of transparency can really spice up a good setup. However, there are times that I &lt;em&gt;don&amp;rsquo;t&lt;/em&gt; want to have the blur on. Whether this be for a specific
color theme, or just to make reading code easier, I like having easy access to my blur settings without memorizing huge commands.&lt;/p&gt;
&lt;h1 id=&#34;solution&#34;&gt;Solution&lt;/h1&gt;
&lt;p&gt;Since I already have a similar module for &lt;code&gt;dunst&lt;/code&gt; notifications, I decided to attempt to replicate the same thing for &lt;code&gt;picom&lt;/code&gt;. We can add the following module to our &lt;code&gt;polybar&lt;/code&gt;
config.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[module/blur-toggle]&lt;/span&gt;
&lt;span style=&#34;color:#a6e22e&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;custom/ipc&lt;/span&gt;
&lt;span style=&#34;color:#a6e22e&#34;&gt;hook-0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;echo &lt;/span&gt;
&lt;span style=&#34;color:#a6e22e&#34;&gt;hook-1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;echo &lt;/span&gt;
&lt;span style=&#34;color:#a6e22e&#34;&gt;click-left&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;/home/gideon/dotfiles/dotfiles/scripts/blurtoggle.sh&lt;/span&gt;
&lt;span style=&#34;color:#a6e22e&#34;&gt;initial&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#a6e22e&#34;&gt;format-foreground&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${colors.color4}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now you can change the filepath on the &lt;code&gt;click-left&lt;/code&gt; variable to point at wherever you keep your scripts. But point it at a script that has the following contents:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/sh
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;((&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;ps -aux | grep &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;p&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;icom | wc -l&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt; &amp;gt; 0&lt;span style=&#34;color:#f92672&#34;&gt;))&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
  polybar-msg hook blur-toggle &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
  pkill -9 picom
&lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;
  polybar-msg hook blur-toggle &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;
  picom -b --config&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/home/gideon/.config/picom/picom.conf --experimental-backends --backend glx --blur-method dual_kawase &amp;amp;
&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Again, you can replace the path used in the &lt;code&gt;--config&lt;/code&gt; flag with wherever you keep your &lt;code&gt;picom&lt;/code&gt; config.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;I have found this method to work rather well with a couple exceptions. I find that if I leave the blur on for extended periods, the &amp;ldquo;button&amp;rdquo; indicator in &lt;code&gt;polybar&lt;/code&gt; will flip to
inactive even though the blur remains.&lt;/p&gt;
&lt;p&gt;When this &amp;ldquo;desyncing&amp;rdquo; occurs, I simply flip the toggle twice and it resets things to normal. If anyone knows a fix or cause for this, I&amp;rsquo;d be glad to hear it.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>xmenu: Desktop Agnostic Menu Utility</title>
      <link>https://gideonwolfe.com/posts/workflow/xmenu/</link>
      <pubDate>Tue, 04 Aug 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/workflow/xmenu/</guid>
      <description>&lt;h1 id=&#34;introduction&#34;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;In the past, I have detailed some of the helper programs I use with the &lt;code&gt;i3&lt;/code&gt; window manager. I have a new one, something that is actually really helpful for my workflow.&lt;/p&gt;
&lt;p&gt;So far, my workflow has been entirely keyboard driven. But that doesn&amp;rsquo;t mean I hate the mouse. I really hate &lt;em&gt;switching&lt;/em&gt; between the keyboard and mouse. So if I am just using the
mouse to click youtube videos or play a game, why would I want to reach for the keyboard to bring up &lt;code&gt;rofi&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s where &lt;a href=&#34;https://github.com/phillbush/xmenu&#34;&gt;xmenu&lt;/a&gt; comes in. &lt;code&gt;xmenu&lt;/code&gt; gives you the openbox style menu that can be navigated with either the keyboard or the mouse.&lt;/p&gt;

  &lt;img src=&#34;https://raw.githubusercontent.com/phillbush/xmenu/master/demo.gif&#34;  class=&#34;center&#34;  /&gt;


&lt;h1 id=&#34;installation&#34;&gt;Installation&lt;/h1&gt;
&lt;p&gt;Since I run arch, I was able to grab the &lt;code&gt;xmenu&lt;/code&gt; program off of the AUR with&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yay -Syu xmenu
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Otherwise you can clone the repository, enter it, and&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make
sudo make install
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I choose to build from source because it allows me to theme on the fly.&lt;/p&gt;
&lt;h1 id=&#34;usage&#34;&gt;Usage&lt;/h1&gt;
&lt;p&gt;The beauty of &lt;code&gt;xmenu&lt;/code&gt; is that it works like &lt;code&gt;dmenu&lt;/code&gt; or &lt;code&gt;rofi&lt;/code&gt;, and takes its options from &lt;code&gt;STDIN&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This means that by default, &lt;code&gt;xmenu&lt;/code&gt; does nothing. When we want to invoke it, we would pipe in the options we want, usually through a bash script for convenience.&lt;/p&gt;
&lt;p&gt;For example, to create the example in the above &lt;code&gt;gif&lt;/code&gt;, simply use this script:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/sh
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
cat &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;&amp;lt;EOF | xmenu | sh &amp;amp;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Applications
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	IMG:./icons/web.png	Web Browser	firefox
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	IMG:./icons/gimp.png	Image editor	gimp
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Terminal (xterm)	xterm
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Terminal (urxvt)	urxvt
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Terminal (st)		st
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Shutdown		poweroff
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;Reboot			reboot
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each value is separated by the &lt;code&gt;TAB&lt;/code&gt; character. On the left is the name to be displayed, and then one tab over is the command/script to be run if that option is selected.&lt;/p&gt;
&lt;p&gt;You can make nested menus by indenting another tab, and line breaks with empty lines. Note that nested line breaks need the appropriate number of tabs at the beginning of the line
followed by nothing.&lt;/p&gt;
&lt;h1 id=&#34;theming&#34;&gt;Theming&lt;/h1&gt;
&lt;p&gt;If you know anything about me, it&amp;rsquo;s that I will not be happy with that lame white menu. Inside the xmenu directory, we can find a file called &lt;code&gt;config.h&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This file defines all of the colors and styles used by &lt;code&gt;xmenu&lt;/code&gt;. Changing this file requires a rebuild of &lt;code&gt;xmenu&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So I created a &lt;code&gt;pywal&lt;/code&gt; template for the &lt;code&gt;config.h&lt;/code&gt; file.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; Config config &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {{
	&lt;span style=&#34;color:#75715e&#34;&gt;/* font */&lt;/span&gt;
  .font &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;HackNerdFont:size=9,FontAwesome:size=9,FontAwesomeBrands:size=11&amp;#34;&lt;/span&gt;,

	&lt;span style=&#34;color:#75715e&#34;&gt;/* colors */&lt;/span&gt;
	.background_color &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{background}&amp;#34;&lt;/span&gt;,
	.foreground_color &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{foreground}&amp;#34;&lt;/span&gt;,
	.selbackground_color &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{background}&amp;#34;&lt;/span&gt;,
	.selforeground_color &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{color2}&amp;#34;&lt;/span&gt;,
	.separator_color &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{color4}&amp;#34;&lt;/span&gt;,
	.border_color &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{color5}&amp;#34;&lt;/span&gt;,

	&lt;span style=&#34;color:#75715e&#34;&gt;/* sizes in pixels */&lt;/span&gt;
	.width_pixels &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;130&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;/* minimum width of a menu */&lt;/span&gt;
	.height_pixels &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;25&lt;/span&gt;,        &lt;span style=&#34;color:#75715e&#34;&gt;/* height of a single menu item */&lt;/span&gt;
	.border_pixels &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;,         &lt;span style=&#34;color:#75715e&#34;&gt;/* menu border */&lt;/span&gt;
	.separator_pixels &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;,      &lt;span style=&#34;color:#75715e&#34;&gt;/* space around separator */&lt;/span&gt;
	.gap_pixels &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,            &lt;span style=&#34;color:#75715e&#34;&gt;/* gap between menus */&lt;/span&gt;

	&lt;span style=&#34;color:#75715e&#34;&gt;/*
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;	 * The variables below cannot be set by X resources.
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;	 * Their values must be less than .height_pixels.
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;	 */&lt;/span&gt;

	&lt;span style=&#34;color:#75715e&#34;&gt;/* geometry of the right-pointing isoceles triangle for submenus */&lt;/span&gt;
	.triangle_width &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;,
	.triangle_height &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt;,

	&lt;span style=&#34;color:#75715e&#34;&gt;/* the icon size is equal to .height_pixels - .iconpadding * 2 */&lt;/span&gt;
	.iconpadding &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;,

	&lt;span style=&#34;color:#75715e&#34;&gt;/* area around the icon, the triangle and the separator */&lt;/span&gt;
	.horzpadding &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;,
}};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Every time &lt;code&gt;wal&lt;/code&gt; is run, a new file is created in &lt;code&gt;~/.cache/wal/&lt;/code&gt;. I symlink this file to the location &lt;code&gt;xmenu&lt;/code&gt;, and rebuild it every time I change theme.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;ln -s /home/gideon/.cache/wal/xmenu-config.h /home/gideon/Programs/xmenu/config.h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I use my own theming tool &lt;a href=&#34;https://github.com/GideonWolfe/Chameleon&#34;&gt;chameleon&lt;/a&gt; to handle themes. If chameleon detects &lt;code&gt;xmenu&lt;/code&gt; on your system, it will attempt to rebuild it on the
fly.&lt;/p&gt;
&lt;p&gt;Look at these colors!!&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/workflow/xmenu/zoom.png&#34;  class=&#34;center&#34;  /&gt;


&lt;h1 id=&#34;polybar-integration&#34;&gt;polybar integration&lt;/h1&gt;
&lt;p&gt;I use &lt;code&gt;i3&lt;/code&gt;, which doesn&amp;rsquo;t exactly have a built in mechanism for &amp;ldquo;right click desktop menu&amp;rdquo;. The author of &lt;code&gt;xmenu&lt;/code&gt; has another tool, &lt;a href=&#34;https://github.com/phillbush/xclickroot&#34;&gt;xclickroot&lt;/a&gt; which helps with this.&lt;/p&gt;
&lt;p&gt;However, since my windows are tiled, I rarely see the desktop anyways. That is why I integrated &lt;code&gt;xmenu&lt;/code&gt; into my &lt;code&gt;polybar&lt;/code&gt; like a traditional start menu!&lt;/p&gt;
&lt;p&gt;In my &lt;code&gt;polybar&lt;/code&gt; config, I have the following module:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[module/xmenu-left]
type = custom/script
click-left = /home/gideon/dotfiles/dotfiles/scripts/xmenu-left-monitor.sh
click-right = /home/gideon/dotfiles/dotfiles/scripts/xmenu-left-monitor.sh
exec = /home/gideon/.config/polybar/scripts/xmenu-button.sh
format-foreground = ${colors.color4}
tail = true
interval = 90
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I have three &lt;em&gt;almost&lt;/em&gt; identical modules, one for each of my monitors. The reason for this is that each monitor calls a &lt;em&gt;different&lt;/em&gt; &lt;code&gt;xmenu&lt;/code&gt; script, which tells &lt;code&gt;xmenu&lt;/code&gt; to position
itself below the bar of &lt;strong&gt;that&lt;/strong&gt; display.&lt;/p&gt;
&lt;p&gt;The script &lt;code&gt;xmenu-button.sh&lt;/code&gt; is dead simple, and can remain consistent across all modules if you like. It simply echoes out the character you want to click on in &lt;code&gt;polybar&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/usr/bin/sh
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; true; &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt;
  echo 
  sleep &lt;span style=&#34;color:#ae81ff&#34;&gt;30&lt;/span&gt; &amp;amp;
  wait
&lt;span style=&#34;color:#66d9ef&#34;&gt;done&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can slap pretty much anything in there, but I like to use FontAwesome icons because that&amp;rsquo;s what the rest of my bar uses.&lt;/p&gt;
&lt;h1 id=&#34;my-config&#34;&gt;My config&lt;/h1&gt;
&lt;p&gt;Here is the ENTIRE &lt;code&gt;xmenu&lt;/code&gt; script I have at the moment for my bars. Note the invocation of &lt;code&gt;xmenu&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;xmenu -i -p 0x25:1&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;-i&lt;/code&gt; tells &lt;code&gt;xmenu&lt;/code&gt; to remove the space for icons&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-p&lt;/code&gt; tells &lt;code&gt;xmenu&lt;/code&gt; to use a specific position&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0x25&lt;/code&gt; the coordinates that place xmenu below my bar (25px down)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;:1&lt;/code&gt; on screen one&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/sh
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
COLORSCRIPTSDIR&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$HOME/Programs/color-scripts/color-scripts
CONFIGDIR&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$HOME/dotfiles/dotfiles/config/


cat &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;lt;&amp;lt;EOF | xmenu -i -p 0x25:1 | sh &amp;amp;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; Applications
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 Firefox	firefox
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 Terminal	urxvt
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 Files	thunar
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 School
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 canvas-tui 		urxvt -e canvas-tui
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Zotero 		zotero
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 CS
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			145
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Notes		urxvt -e nvim $HOME/School/CS/145/notes.java
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			241
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Notes		urxvt -e nvim $HOME/School/CS/241/notes
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			247
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Notes		urxvt -e nvim $HOME/School/CS/247/notes
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Books
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;					Susheel&amp;#39;s notes		zathura $HOME/School/CS/247/CSCI247_CourseNotes.pdf
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;					Intel manual		zathura $HOME/School/CS/247/intel.pdf
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;					C Programming Language		zathura $HOME/School/CS/247/the_c_programming_language_2.pdf
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			301
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Notes		urxvt -e nvim $HOME/School/CS/301/notes
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Books
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;					Theory of Computation		zathura $HOME/School/CS/301/TheoryOfComputation.pdf
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;					Book of Proof		zathura $HOME/School/CS/301/Main.pdf
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			305
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Notes		urxvt -e nvim $HOME/School/CS/305/notes.md
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Textbook		zathura $HOME/School/CS/305/textbook.pdf
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			330
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Notes		urxvt -e nvim $HOME/School/CS/330/notes.md
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			347
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Notes		urxvt -e nvim $HOME/School/CS/347/notes.md
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Textbook		zathura $HOME/School/CS/347/textbook.pdf
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			367
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Notes		urxvt -e nvim $HOME/School/CS/367/notes.md
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Textbook		zathura $HOME/School/CS/367/textbook.pdf
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			461
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Notes		urxvt -e nvim $HOME/School/CS/461/notes.md
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Textbook		zathura $HOME/School/CS/461/textbook.pdf
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			474
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Notes		urxvt -e nvim $HOME/School/CS/474/notes.md
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 Comms
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		Discord (GUI)		discord
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		Discord (cordless)		urxvt -e cordless
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Email (Neomutt)		urxvt -e neomutt
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 IRC (weechat)		urxvt -e weechat
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 SMS (kde-connect)		kdeconnect-sms --style gtk2
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Slack 	slack
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Signal (GUI)		signal-desktop
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Telegram (GUI)		telegram-desktop
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Telegram (nctelegram)		nctelegram
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 Finance
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Crypto (TUI)		urxvt -e cointop
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Stocks (TUI)		urxvt -e mop
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Stonks (CLI)		urxvt -e mop
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 Utilities
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Calculator (TUI)		urxvt -e qalq
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Calculator (GUI)		qalculate-gtk
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Calendar (khal)		urxvt -e khal interactive
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Color Picker		gpick
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Map (TUI)		urxvt -e mapscii
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 System
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Keyboard (Corsair)		ckb-next
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Fonts 	gucharmap
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Smartphone (kdeconnect)		kdeconnect-app --style gtk2
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Docker (lazydocker)		urxvt -e lazydocker
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Kill Window	xkill
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Screen Recording (OBS)		obs
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Screenshot
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				GUI	flameshot gui
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				All Displays	flameshot screen -d 5000 -n 3 -p $HOME/Photos/screenshots
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Middle Display	flameshot screen -d 5000 -n 0 -p $HOME/Photos/screenshots
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Right Display	flameshot screen -d 5000 -n 1 -p $HOME/Photos/screenshots
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Left Display	flameshot screen -d 5000 -n 2 -p $HOME/Photos/screenshots
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Personal
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Nextcloud		nextcloud --style gtk2
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Passwords (keepassxc)		keepassxc --style gtk2
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Keys (Seahorse)		seahorse
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Theming
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			lxappearance 	lxappearance
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			GTK (oomox) 	oomox-gui
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Qt (qt5ct) 	qt5ct --style gtk2
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			WPGTK 	wpg
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Monitors
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			System (ytop)		urxvt -e ytop
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			System (bashtop)		urxvt -e bashtop
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			System (glances)		urxvt -e glances
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Disk Usage (GUI)		baobab
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Disk Usage (TUI)		urxvt -e ncdu
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			IO (iotop)		urxvt -e iotop
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Kernel (kmon)		urxvt -e kmon
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Nvidia GPU (nvtop)		urxvt -e nvtop
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Power (powertop)		urxvt -e powertop
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			DNS (dnstop)		urxvt -e powertop
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Network Usage (jnettop)		urxvt -e jnettop
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Network Load (nload)		urxvt -e nload
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Bandwidth (bmon)		urxvt -e bmon
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Media Server		urxvt -e jellyfinips.sh
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Media
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 EasyTag		easytag
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 Entertainment
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Media
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Podcasts (castero)	castero
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 RSS (newsboat)	newsboat
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Reddit (tuir)	tuir
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Music (cmus)	cmus
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Spotify (GUI)	spotify
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Spotify (spotifytui)	spt
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Soulseek (Nicotine+)	nicotine
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Games
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 Steam	steam
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Itch	itch
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Lutris	lutris
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Tetris	tetris
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Solitaire	ttysolitaire
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Battleship	bs
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Minecraft	minecraft-launcher
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Dopewars	dopewars
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Misc
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Color Scripts
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				alpha	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/alpha; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				arch	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/arch; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				bars	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/bars; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				blocks2	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/blocks2; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				bloks	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/bloks; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				colorbars	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/colorbars; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				colortest	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/colortest; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				colortest-slim	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/colortest-slim; colortest&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				colorview	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/colorview; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				crunch	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/crunch; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				crunchbang	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/crunchbang; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				crunchbang-mini	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/crunchbang-mini; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				darthvader	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/darthvader; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				dna	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/dna; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				dotx	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/dna; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				elfman	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/elfman; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				faces	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/faces; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				fade	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/fade; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				ghosts	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/ghosts; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				guns	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/guns; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				hex	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/hex; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				hex-block	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/hex-block; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				illumina	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/illumina; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				jangofett	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/jangofett; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				monster	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/monster; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				mouseface	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/mouseface; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				pacman	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/pacman; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				panes	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/panes; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				pinguco	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/pinguco; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				pipes1	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/pipes1; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				pipes2	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/pipes2; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				pipes2-slim	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/pipes2-slim; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				pukeskull	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/pukeskull; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				rails	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/rails; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				rally-x	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/rally-x; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				rupees	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/rupees; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				space-invaders	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/space-invaders; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				spectrum	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/spectrum; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				square	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/square; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				tanks	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/tanks; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				thebat	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/thebat; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				thebat2	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/thebat2; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				tiefighter1-no-invo	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/tiefighter1-no-invo; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				tiefighter2	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/tiefighter2; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				zwaves	urxvt -e sh -c &amp;#39;$COLORSCRIPTSDIR/zwaves; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			cava	urxvt -e cava
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			pipes.sh	urxvt -e pipes.sh
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			rain.sh	urxvt -e rain.sh
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			unimatrix	urxvt -e unimatrix -l Gg
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			asciiquarium	urxvt -e asciiquarium
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			bonsai.sh	urxvt -e bonsai -l -i -T
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			eDEX-UI		sh -c (cd $HOME/Programs/edex-ui/ ; npm start)
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 Science
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Astronomy
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Celestia	celestia
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Biology
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Pymol		pymol
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Chemistry
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			ptable	urxvt -e ptable
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			chemtool	chemtool
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Math
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Desmos	desmos
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Geogebra	geogebra
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		Anki		anki
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 Development
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 IDEs
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Neovim	urxvt -e nvim
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			VS Code	code
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			Dr. Racket	drracket
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Github (TUI)	urxvt -e github
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		bitwise	bitwise
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		Github Activity (TUI)	urxvt -e sh -c &amp;#39;ghcal --no-ansi ; read&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		QDbusViewer	qdbusviewer --style gtk2	
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; Configs
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 System
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 i3	urxvt -e nvim $CONFIGDIR/i3/config
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Start Menu	urxvt -e nvim $HOME/dotfiles/dotfiles/scripts/xmenu.sh
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Notifications	urxvt -e nvim $CONFIGDIR/wal/templates/dunstrc
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Smartphone	kdeconnect-settings --style gtk2
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Sound	pavucontrol
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Shell
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			fish
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				config.fish	urxvt -e nvim $CONFIGDIR/fish/config.fish
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;				Web Config	fish -c fish_config
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			bash	urxvt -e nvim $HOME/.bashrc
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 polybar
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			config	urxvt -e nvim $CONFIGDIR/polybar/config
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			launch.sh	urxvt -e nvim $CONFIGDIR/polybar/scripts/launch.sh
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 rofi
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			config	urxvt -e nvim $CONFIGDIR/rofi/config
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			template	urxvt -e nvim $CONFIGDIR/wal/templates/custom-rofi.rasi
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 Utilities
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 khard	urxvt -e nvim $CONFIGDIR/khard/khard.conf
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 khal	urxvt -e nvim $CONFIGDIR/khal/config
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			 vdirsyncer	urxvt -e nvim $CONFIGDIR/vdirsyncer/config
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		 .Xresources	urxvt -e nvim $HOME/.Xresources
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 User
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		ranger	urxvt -e nvim $CONFIGDIR/ranger/rc.conf
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		newsboat	urxvt -e nvim $CONFIGDIR/newsboat/config
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		neomutt
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			neomuttrc	urxvt -e nvim $CONFIGDIR/neomutt/neomuttrc
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			colors	urxvt -e nvim $CONFIGDIR/neomutt/colors
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			settings	urxvt -e nvim $CONFIGDIR/neomutt/settings
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			mappings	urxvt -e nvim $CONFIGDIR/neomutt/mappings
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			mailcap	urxvt -e nvim $CONFIGDIR/neomutt/mailcap
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		neovim
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			coc-settings	urxvt -e nvim $HOME/.config/nvim/coc-settings.json
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			functions	urxvt -e nvim $HOME/.config/nvim/configs/functions.vim
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			main	urxvt -e nvim $HOME/.config/nvim/configs/main.vim
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			mappings	urxvt -e nvim $HOME/.config/nvim/configs/mappings.vim
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			plugin-settings	urxvt -e nvim $HOME/.config/nvim/configs/plugin-settings.vim
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;			plugins	urxvt -e nvim $HOME/.config/nvim/configs/plugin.vim
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		neofetch	urxvt -e nvim $CONFIGDIR/neofetch/config.conf
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		htop	urxvt -e nvim $CONFIGDIR/htop/htoprc
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		s-tui	urxvt -e nvim $CONFIGDIR/s-tui/s-tui.conf
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		spicetify	urxvt -e nvim $CONFIGDIR/spicetify/config.ini
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		stonks	urxvt -e nvim $CONFIGDIR/stonks.yml
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; System
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 Refresh i3		i3-msg restart
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 Refresh polybar		pkill -9 polybar ; $CONFIGDIR/polybar/scripts/launch.sh
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 Logout	i3-nagbar -t warning -m &amp;#39;Do you really want to exit i3? This will end your X session.&amp;#39; -b &amp;#39;Yes, exit i3&amp;#39; &amp;#39;i3-msg exit&amp;#39;
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 Shutdown		poweroff
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	 Reboot			reboot
&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Feel free to take inspiration!&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Good job for making it this far. If you followed along, you should have a desktop environment agnostic menu utility with infinite potential!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Single and Pairwise Mutations and Their Impact on SARS-CoV-2 Proteins</title>
      <link>https://gideonwolfe.com/posts/bio/bioinfoproj/project/</link>
      <pubDate>Mon, 22 Jun 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/bio/bioinfoproj/project/</guid>
      <description>&lt;h1 id=&#34;intro&#34;&gt;Intro&lt;/h1&gt;
&lt;p&gt;This past quarter (Spring 2020) has been an interesting one for sure. With the constant news of COVID and worldwide protests coming through every media outlet, focusing on
schoolwork seemed like futile pursuit at times.&lt;/p&gt;
&lt;p&gt;Thankfully, I was fortunate enough to have (mostly) fantastic professors that managed to provide informative and engaging lectures and assignments for the entirety of
this challenging quarter.&lt;/p&gt;
&lt;p&gt;A part of me is really enjoying working from home this quarter, and that part is mostly my GPA, which ended up being over an entire point higher than my unimpressive cumulative
GPA. Not quite sure why or how that happened, but I guess I&amp;rsquo;ll just continue as I am&amp;hellip;&lt;/p&gt;
&lt;h1 id=&#34;the-class&#34;&gt;The Class&lt;/h1&gt;
&lt;p&gt;One of the things that made this quarter special is the fact that I was able to take my schools Bioinformatics class, which I have been trying to get into for a couple years.&lt;/p&gt;
&lt;p&gt;It was taught by one of my favorite professors (and now my advisor), is only taught once a year, and requires a manual override to register for. I was thrilled when I found out I
scraped one of the last slots!&lt;/p&gt;
&lt;p&gt;This class was a unique opportunity to collaborate with other STEM students (bioilogy/chemistry) as well as grad students and tackle a real world research problem with techniques and tools we learn in the
first part of the quarter.&lt;/p&gt;
&lt;p&gt;The first 4 weeks brought all the CS people up to speed on the basics of DNA transcription/translation, protein structure, and alignment concepts.&lt;/p&gt;
&lt;h1 id=&#34;the-project&#34;&gt;The Project&lt;/h1&gt;
&lt;p&gt;The latter half of the quarter was devoted to a collaborative research project, the groups for which we were allowed to self select out of a pool of pre approved project ideas.&lt;/p&gt;
&lt;p&gt;The project I chose was this: Target various amino acids on the spike protein of the SARS-Cov-2, mutate them, and analyze the effectiveness of said mutations.&lt;/p&gt;
&lt;p&gt;I chose this project because I like the idea of pinpointing vulnerable areas on the protein and mutating them to cause instability in the protein, possibly breaking functionality
in the process.&lt;/p&gt;
&lt;p&gt;My role in the project mainly consisted of managing communications between us and our professor, as well as creating the pipeline for our data. In short, the pipeline worked like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;proMuteBatch&lt;/code&gt; to generate batch files for &lt;code&gt;proMute&lt;/code&gt;, in order to exhaustively mutate multiple locations on the protein&lt;/li&gt;
&lt;li&gt;Extract the output of &lt;code&gt;proMute&lt;/code&gt; (modified PDB files) as well as energy minimization data for each individual mutation (19 per target site)&lt;/li&gt;
&lt;li&gt;Generate a script for the &lt;a href=&#34;http://marid.bioc.cam.ac.uk/sdm2&#34;&gt;SDM&lt;/a&gt; tool, which allows us to predict $$\Delta\Delta G$$ values for each mutation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I created a short bash script to automate this task. Although it could certainly be better optimized, I sacrificed some efficiency for readability by non linux nerds.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;# After making promute, copy this script into the build directory&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;# Change the &amp;#34;FILES&amp;#34; variable to the script (or scripts) you would like to execute&lt;/span&gt;
&lt;span style=&#34;color:#75715e&#34;&gt;# to profile different mutation scripts, you can run this script with the &amp;#34;time&amp;#34; command &lt;/span&gt;

&lt;span style=&#34;color:#75715e&#34;&gt;# Mutations on second PDB 6Y2E&lt;/span&gt;
./proMuteBatch 6Y2E A:A 25:25 X T25 &lt;span style=&#34;color:#75715e&#34;&gt;# exhaustively mutate T at residue 25, chain A&lt;/span&gt;
./proMuteBatch 6Y2E A:A 26:26 X T26 &lt;span style=&#34;color:#75715e&#34;&gt;# exhaustively mutate T at residue 26, chain A&lt;/span&gt;
./proMuteBatch 6Y2E A:A 27:27 X L27 &lt;span style=&#34;color:#75715e&#34;&gt;# exhaustively mutate L at residue 27, chain A&lt;/span&gt;
./proMuteBatch 6Y2E A:A 28:28 X N28 &lt;span style=&#34;color:#75715e&#34;&gt;# exhaustively mutate N at residue 28, chain A&lt;/span&gt;
./proMuteBatch 6Y2E A:A 29:29 X G29 &lt;span style=&#34;color:#75715e&#34;&gt;# exhaustively mutate G at residue 29, chain A&lt;/span&gt;
./proMuteBatch 6Y2E A:A 30:30 X L30 &lt;span style=&#34;color:#75715e&#34;&gt;# exhaustively mutate L at residue 30, chain A&lt;/span&gt;
./proMuteBatch 6Y2E A:A 31:31 X W31 &lt;span style=&#34;color:#75715e&#34;&gt;# exhaustively mutate W at residue 31, chain A&lt;/span&gt;
./proMuteBatch 6Y2E A:A 32:32 X L32 &lt;span style=&#34;color:#75715e&#34;&gt;# exhaustively mutate L at residue 32, chain A&lt;/span&gt;


declare -A residues
residues&lt;span style=&#34;color:#f92672&#34;&gt;+=(&lt;/span&gt; 
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;PHE&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;F&amp;#34;&lt;/span&gt; 
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;LEU&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;L&amp;#34;&lt;/span&gt; 
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ILE&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;I&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;MET&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;M&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;VAL&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;V&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;SER&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;S&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;PRO&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;P&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;THR&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;T&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ALA&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;A&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;TYR&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Y&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;HIS&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;H&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;GLN&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Q&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ASN&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;N&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;LYS&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;K&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ASP&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;D&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;GLU&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;E&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;CYS&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;C&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;TRP&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;W&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ARG&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;R&amp;#34;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;GLY&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;G&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;

sed -i &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/$/ em/&amp;#39;&lt;/span&gt; T25
sed -i &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/$/ em/&amp;#39;&lt;/span&gt; T26
sed -i &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/$/ em/&amp;#39;&lt;/span&gt; L27
sed -i &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/$/ em/&amp;#39;&lt;/span&gt; N28
sed -i &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/$/ em/&amp;#39;&lt;/span&gt; G29
sed -i &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/$/ em/&amp;#39;&lt;/span&gt; L30
sed -i &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/$/ em/&amp;#39;&lt;/span&gt; W31
sed -i &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/$/ em/&amp;#39;&lt;/span&gt; L32


&lt;span style=&#34;color:#75715e&#34;&gt;# Customize with your scripts&lt;/span&gt;
FILES&lt;span style=&#34;color:#f92672&#34;&gt;=(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;T25&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;T26&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;L27&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;N28&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;G29&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;L30&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;W31&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;L32&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;

&lt;span style=&#34;color:#75715e&#34;&gt;# Execute the lines in the script&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; FILE in &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;FILES[@]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt;


  &lt;span style=&#34;color:#75715e&#34;&gt;# Create a file to store SDM script&lt;/span&gt;
  SDMFILE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;FILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;_sdm&amp;#34;&lt;/span&gt;
  touch $SDMFILE

  &lt;span style=&#34;color:#75715e&#34;&gt;# Read each mutation into an array&lt;/span&gt;
  readarray -t LINES &amp;lt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FILE&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;

  &lt;span style=&#34;color:#75715e&#34;&gt;# Routine to execute for every mutation&lt;/span&gt;
  &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; LINE in &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;LINES[@]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt;

    &lt;span style=&#34;color:#75715e&#34;&gt;# Make a directory to store outputs&lt;/span&gt;
    &lt;span style=&#34;color:#75715e&#34;&gt;# Structure is PDBID.Chain.Location.Res2.output&lt;/span&gt;
    OUTPUTDIRNAME&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;echo $LINE | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{ print $2&amp;#34;.&amp;#34;$3&amp;#34;.&amp;#34;$4&amp;#34;.&amp;#34;$5&amp;#34;.output&amp;#34; }&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
    echo &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;INFO&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; Creating Directory $OUTPUTDIRNAME
    mkdir -p $OUTPUTDIRNAME

    &lt;span style=&#34;color:#75715e&#34;&gt;# Directory to look for EM files that were generated&lt;/span&gt;
    &lt;span style=&#34;color:#75715e&#34;&gt;# Structure is PDBID.ChainLocationRes2&lt;/span&gt;
    EMDIRNAME&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;echo $LINE | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{ print $2&amp;#34;.&amp;#34;$3$4$5 }&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;

    &lt;span style=&#34;color:#75715e&#34;&gt;# Actually call proMute&lt;/span&gt;
    $LINE

    &lt;span style=&#34;color:#75715e&#34;&gt;# translate the promute command to an SDM script line&lt;/span&gt;
    PDBID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;echo $LINE | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $2}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
    RESNUM&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;echo $LINE | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $4}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
    CHAIN&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;echo $LINE | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $3}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
    FINALRES&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;echo $LINE | awk &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{print $5}&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
    ORIGRESCODE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;cat &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;PDBID&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;.pdb | grep ATOM | awk -v rn&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$RESNUM&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; -v chn&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;$CHAIN &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;$6 == rn &amp;amp;&amp;amp; $5 == chn {print $4}&amp;#39;&lt;/span&gt; | sed &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;s/.*\(...\)/\1/&amp;#39;&lt;/span&gt; | head -n 1&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
    ORIGRES&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;residues[$ORIGRESCODE]&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$ORIGRES&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; !&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$FINALRES&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
      &lt;span style=&#34;color:#75715e&#34;&gt;# put this line in the script&lt;/span&gt;
      echo &lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;echo $CHAIN $ORIGRES$RESNUM$FINALRES&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt; &amp;gt;&amp;gt; $SDMFILE
    &lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;

    &lt;span style=&#34;color:#75715e&#34;&gt;# Move all output files: PDB, Fasta, and EM data&lt;/span&gt;
    mv *.txt $OUTPUTDIRNAME
    mv *.pdb $OUTPUTDIRNAME
    mv external/em/$EMDIRNAME $OUTPUTDIRNAME
    mv $FILE $OUTPUTDIRNAME
    echo &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;INFO&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; Moving files to $OUTPUTDIRNAME

  &lt;span style=&#34;color:#66d9ef&#34;&gt;done&lt;/span&gt;

  &lt;span style=&#34;color:#75715e&#34;&gt;# cleanup output&lt;/span&gt;
  rm -rf &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;FILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;_output&amp;#34;&lt;/span&gt;
  mkdir -p &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;FILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;_output&amp;#34;&lt;/span&gt;
  echo &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;INFO&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; Cleaning outputs from last run
  echo &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;INFO&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; Moving new files to &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;FILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;_output&amp;#34;&lt;/span&gt;
  mv $SDMFILE &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;FILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;_output/&amp;#34;&lt;/span&gt;
  mv *.output &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;FILE&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;_output/&amp;#34;&lt;/span&gt;

&lt;span style=&#34;color:#66d9ef&#34;&gt;done&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Most of this script is pretty self explanatory. I simply generate a list of &lt;code&gt;proMute&lt;/code&gt; commands using &lt;code&gt;proMuteBatch&lt;/code&gt;, and executed all of them.&lt;/p&gt;
&lt;p&gt;I used clues from filenames and commands (such as protein name and residue number) to generate unique directories of every mutation ran by &lt;code&gt;proMute&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The only &amp;ldquo;confusing&amp;rdquo; part would be the generation of the SDM script. In short, the script format for SDM requires the original residue type for the location that is being mutated.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;proMute&lt;/code&gt; does not care about or output this information, so I had to do some fancy pipelining to get it to work.&lt;/p&gt;
&lt;p&gt;I look into the &lt;code&gt;PDB&lt;/code&gt; file for the target protein, and find isolate all the &lt;code&gt;ATOM&lt;/code&gt; lines, that correspond to individual atoms in the protein.&lt;/p&gt;
&lt;p&gt;I then isolate the residue number of interest, making sure we are looking at the correct chain in the PDB file.&lt;/p&gt;
&lt;p&gt;The first atom of the residue is kept, and then we simply look at the residue it belongs to. I wasn&amp;rsquo;t sure about the PDB notation, because sometimes one amino acid would be
represented by multiple similar 3-4 letter codes.&lt;/p&gt;
&lt;p&gt;So I just chopped off anything after three characters, and then run the three letter name through my dictionary, which spits out the single letter amino acid code required by SDM.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s a &lt;em&gt;lot&lt;/em&gt; of work to go through for one letter&amp;hellip;&lt;/p&gt;
&lt;p&gt;The final step in the pipeline was a script created by an adjacent group studying &lt;em&gt;double&lt;/em&gt; mutations in the same protein. This script analyzed the energy minimization data and used
it to predict an effect on protein function.&lt;/p&gt;
&lt;h1 id=&#34;results&#34;&gt;Results&lt;/h1&gt;
&lt;p&gt;Here are my favorite figures from our final paper. We used &lt;code&gt;pymol&lt;/code&gt; to color and label the locations of interest, as well as illustrate their bonds and connections.&lt;/p&gt;
&lt;p&gt;The colored bar charts on the right represent one mutation for each of the 19 bars. The data plotted is the output $$\Delta\Delta G$$ produced by SDM, where a negative value
indicates reduced stability in the protein.&lt;/p&gt;
&lt;p&gt;
  &lt;img src=&#34;https://gideonwolfe.com/img/bio/bioinfoproj/group1c.jpg&#34;  class=&#34;center&#34;  /&gt;



  &lt;img src=&#34;https://gideonwolfe.com/img/bio/bioinfoproj/group2c.jpg&#34;  class=&#34;center&#34;  /&gt;



  &lt;img src=&#34;https://gideonwolfe.com/img/bio/bioinfoproj/group3c.jpg&#34;  class=&#34;center&#34;  /&gt;



  &lt;img src=&#34;https://gideonwolfe.com/img/bio/bioinfoproj/group4c.jpg&#34;  class=&#34;center&#34;  /&gt;

&lt;/p&gt;
&lt;p&gt;A heatmap visualization of the same data:&lt;/p&gt;
&lt;p&gt;
  &lt;img src=&#34;https://gideonwolfe.com/img/bio/bioinfoproj/6M0J_Heatmap.jpg&#34;  class=&#34;center&#34;  /&gt;



  &lt;img src=&#34;https://gideonwolfe.com/img/bio/bioinfoproj/6Y2E_Heatmap.png&#34;  class=&#34;center&#34;  /&gt;

&lt;/p&gt;
&lt;p&gt;As you can see by the heatmaps, we were able to generate a significant amount of destabilizing mutations, especially on the &lt;code&gt;6Y2E&lt;/code&gt;structure.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;If anyone wants to read our final project, I&amp;rsquo;ll leave it &lt;a href=&#34;https://gideonwolfe.com/files/bio/bioinfoproj/finalreport.pdf&#34;&gt;here&lt;/a&gt; to download. At the last minute, we decided to
combine the reports of group 4 and 5, who investigated single and double mutations respectively. This provides a good way to compare a variety of possible mutations of the same
structure.&lt;/p&gt;
&lt;p&gt;I had a really great time in this class, and could not have dreamed of creating a project of this caliber, and I could not have done it without my awesome group members and my
professor who had the perfect &amp;ldquo;hands off&amp;rdquo; approach where he would happily provide guidance, but left large decisions up to the groups themselves.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Canvas in the terminal with canvas-tui</title>
      <link>https://gideonwolfe.com/posts/workflow/canvas-tui/canvas-tui/</link>
      <pubDate>Thu, 30 Apr 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/workflow/canvas-tui/canvas-tui/</guid>
      <description>&lt;h1 id=&#34;intro&#34;&gt;Intro&lt;/h1&gt;
&lt;p&gt;What better way to spend time during quarantine than to program an application nobody will ever use? Well obviously I couldn&amp;rsquo;t come up with anything, so I did just that.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/GideonWolfe/canvas-tui&#34;&gt;canvas-tui&lt;/a&gt; is an application I wrote in order to view my grades, assignments, and other school information from the comfort of my
terminal.&lt;/p&gt;
&lt;p&gt;This is one of those occasions I have mentioned in previous articles, where no premade solution was readily available, so I was forced to give it a shot myself. The fact that I was
able to produce a perfectly functional application in less than a week is a testament to the flexibility and efficacy of a linux terminal based workflow.&lt;/p&gt;
&lt;h1 id=&#34;history&#34;&gt;History&lt;/h1&gt;
&lt;p&gt;About two weeks before I developed canvas-tui, me and a friend teamed up on a small, python based utility called &lt;a href=&#34;https://github.com/GideonWolfe/canvas-cli&#34;&gt;canvas-cli&lt;/a&gt;. This
program can take simple command line arguments and output tables containing your grades, assignments, and more.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/workflow/canvas-tui/wtfutil.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Here, I used a great program called &lt;a href=&#34;https://wtfutil.com/&#34;&gt;wtfutil&lt;/a&gt; to throw together a static dashboard that showed the result of running various &lt;code&gt;canvas-cli&lt;/code&gt; commands.&lt;/p&gt;
&lt;p&gt;Other than that, I still use it to quickly download a desired file from my course into the working directory.&lt;/p&gt;
&lt;h1 id=&#34;canvas-tui&#34;&gt;canvas-tui&lt;/h1&gt;
&lt;p&gt;My original plan was to use &lt;code&gt;canvas-cli&lt;/code&gt; and plug its output into a terminal interface. I decided on go as my language for this project, as I wanted to take advantage of the
&lt;a href=&#34;https://github.com/gizak/termui&#34;&gt;termui&lt;/a&gt; library.&lt;/p&gt;
&lt;p&gt;Before this project, I had not written a single line of go in my life. I looked into piping output from python into go, but it seemed like far more trouble than it was worth in the
end.&lt;/p&gt;
&lt;p&gt;I decided on rewriting most all of &lt;code&gt;canvas-cli&lt;/code&gt;s features in go, which makes it much easier to integrate new features not possible in &lt;code&gt;canvas-cli&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;dashboard&#34;&gt;Dashboard&lt;/h2&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/workflow/canvas-tui/dashboard.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;I want this page to be a quick glance at your school status.&lt;/p&gt;
&lt;p&gt;So far I have a bar chart that displays your current score in each course, as well as a &amp;ldquo;To do list&amp;rdquo;, which is
comprised of any outstanding assignments in any class.&lt;/p&gt;
&lt;p&gt;Some professors have yet to grade any assignments, causing my &amp;ldquo;Current Score&amp;rdquo; to be zero. Many of the features of &lt;code&gt;canvas-tui&lt;/code&gt; are impacted by how professors choose to utilize the
Canvas features.&lt;/p&gt;
&lt;h2 id=&#34;course-overview&#34;&gt;Course Overview&lt;/h2&gt;
&lt;p&gt;Each course has their own &amp;ldquo;dashboard&amp;rdquo; of sorts. My goal here was to display some of the most commonly sought information such as grades and assignments, but also visualize
other data about the course, such as the weighting of different assignment groups.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/workflow/canvas-tui/courseoverview.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;I use this page daily to view the most recent announcement, click on the zoom link for class, or quickly view assignments to complete.&lt;/p&gt;
&lt;h1 id=&#34;other-pages&#34;&gt;Other Pages&lt;/h1&gt;
&lt;p&gt;On the lefthand side of the course overview, you will see the navigation menu that can be scrolled using &lt;code&gt;j&lt;/code&gt; and &lt;code&gt;k&lt;/code&gt; (like civilized people).&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/workflow/canvas-tui/assignments.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Pressing &lt;code&gt;Space&lt;/code&gt; on any of these items will either bring up a placeholder page, or open the dashboard you choose. While I am always thinking of ways to visualize the course tabs in
the terminal, some are not feasible or useful to see there.&lt;/p&gt;
&lt;p&gt;That is why after selecting the page you want to view, pressing &lt;code&gt;o&lt;/code&gt; will open it in your browser of choice.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/workflow/canvas-tui/grades.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;The main goal of &lt;code&gt;canvas-tui&lt;/code&gt; is to provide statistics and metrics that are usually not provided within the default canvas experience.&lt;/p&gt;
&lt;p&gt;Visualizing scores over time, by assignment group, by course, and more are planned additions to the program, as well as whatever else I can wrangle out of the data provided by the
&lt;a href=&#34;https://canvas.instructure.com/doc/api/&#34;&gt;Canvas API&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;I saw a program that didn&amp;rsquo;t exist, and wondered why. I realized that was probably because the market for an application like this is practically nonexistent.&lt;/p&gt;
&lt;p&gt;I promptly ignored this and set out to create it anyways. At its current form, it does far more than I had initially planned. Nonetheless, I am continually thinking of new features
to add, so make sure to stay up to date on the github!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Agents Standing By: Notifications through Telegram</title>
      <link>https://gideonwolfe.com/posts/sysadmin/huginn/telegram/</link>
      <pubDate>Tue, 31 Mar 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/sysadmin/huginn/telegram/</guid>
      <description>&lt;p&gt;I got a request to go over the setup of a Telegram agent for Huginn. I personally don&amp;rsquo;t use Telegram at the moment, but I managed to get a basic bot set up.&lt;/p&gt;
&lt;h1 id=&#34;create-your-telegram-bot&#34;&gt;Create your Telegram bot&lt;/h1&gt;
&lt;p&gt;First you will need to create a bot by &lt;a href=&#34;https://telegram.me/botfather&#34;&gt;messaging the BotFather&lt;/a&gt; and requesting a new bot.&lt;/p&gt;
&lt;p&gt;This can be done by typing &lt;code&gt;/newbot&lt;/code&gt; and then filling out the prompts for a username and bot name.&lt;/p&gt;
&lt;p&gt;Once this is completed, BotFather will give you an HTTP API token. We will need this value.&lt;/p&gt;
&lt;p&gt;Click the link to start messaging your bot. Send a message, this will come in handy later.&lt;/p&gt;
&lt;h1 id=&#34;setting-up-the-telegram-agent&#34;&gt;Setting up the Telegram Agent&lt;/h1&gt;
&lt;p&gt;In Huginn, we will create a new Telegram Agent.&lt;/p&gt;
&lt;p&gt;The fields are pretty self explanatory.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Paste your auth token from BotFather into the Auth token field&lt;/li&gt;
&lt;li&gt;To get your &lt;code&gt;chat_id&lt;/code&gt;, visit &lt;code&gt;https://api.telegram.org/bot&amp;lt;API TOKEN&amp;gt;/getUpdates&lt;/code&gt;, replacing &lt;code&gt;&amp;lt;API TOKEN&amp;gt;&lt;/code&gt; with your actual token. Then the &lt;code&gt;id&lt;/code&gt; field under &lt;code&gt;chat&lt;/code&gt; will have the
&lt;code&gt;chat_id&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Change other options to preference&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think parsing into markdown is great, since I am familiar with it already.&lt;/p&gt;
&lt;h1 id=&#34;sending-data&#34;&gt;Sending Data&lt;/h1&gt;
&lt;p&gt;The Telegram agent expects events with one of the following tags: &lt;code&gt;text&lt;/code&gt;, &lt;code&gt;photo&lt;/code&gt;, &lt;code&gt;audio&lt;/code&gt;, &lt;code&gt;document&lt;/code&gt; or &lt;code&gt;video&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Most likely you will need to use an &lt;code&gt;EventFormattingAgent&lt;/code&gt; to put your desired messages into this format.&lt;/p&gt;
&lt;p&gt;To test it out, I created a simple &lt;code&gt;ManualEventAgent&lt;/code&gt; and pointed it at the Telegram agent.&lt;/p&gt;
&lt;p&gt;I fired off an event that was simply&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Hello World&amp;#34;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and promptly received the text &amp;ldquo;Hello World&amp;rdquo; from my bot.&lt;/p&gt;
&lt;p&gt;With the use of the &lt;code&gt;EventFormattingAgent&lt;/code&gt; and a bit of imagination, you can format pretty much any incoming event to a telegram message&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Email in the Terminal: Configuring Neomutt</title>
      <link>https://gideonwolfe.com/posts/workflow/neomutt/intro/</link>
      <pubDate>Tue, 31 Mar 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/workflow/neomutt/intro/</guid>
      <description>&lt;h1 id=&#34;intro&#34;&gt;Intro&lt;/h1&gt;
&lt;p&gt;In one of my first posts about building an optimized workflow, I briefly mentioned neomutt was a program who&amp;rsquo;s configuration deserved a post all its own. This is that post.&lt;/p&gt;
&lt;p&gt;Much like weechat, Neomutt is an extremely powerful tool but it needs a bit of customization to make it more &amp;ldquo;user friendly&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;On Arch we can install Neomutt with &lt;code&gt;pacman -Syu neomutt&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You have probably seen tons of tutorials about setting up &lt;code&gt;offlineIMAP&lt;/code&gt; or a similar service. I personally opt to connect directly to the IMAP server as its less of a hassle. Maybe
there is a good reason to do the whole offline sync thing but I haven&amp;rsquo;t found it.&lt;/p&gt;
&lt;h1 id=&#34;files&#34;&gt;Files&lt;/h1&gt;
&lt;p&gt;You may have heard of a &lt;code&gt;muttrc&lt;/code&gt; or &lt;code&gt;neomuttrc&lt;/code&gt;. Like a &lt;code&gt;vimrc&lt;/code&gt;, these files define the settings for neomutt. I place my &lt;code&gt;neomuttrc&lt;/code&gt; in &lt;code&gt;~/.config/neomutt/&lt;/code&gt; because its where most
programs store their config files.&lt;/p&gt;
&lt;p&gt;However much like my &lt;a href=&#34;https://github.com/GideonWolfe/vim.reaper&#34;&gt;custom neovim configuration&lt;/a&gt;, the main configuration file will simply be used to source the discrete configuration
files containing specific configurations.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vim: filetype=muttrc

source ~/.config/neomutt/settings
source ~/.config/neomutt/colors
source ~/.config/neomutt/mappings

# Accounts

source ~/.config/neomutt/accounts/gmail
folder-hook $folder &#39;source ~/.config/neomutt/accounts/gmail&#39;

source ~/.config/neomutt/accounts/school
folder-hook $folder &#39;source ~/.config/neomutt/accounts/school&#39;

source ~/.config/neomutt/accounts/main
folder-hook $folder &#39;source ~/.config/neomutt/accounts/main&#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the above &lt;code&gt;neomuttrc&lt;/code&gt; file, I source three files: &lt;code&gt;settings&lt;/code&gt; for general program configuration, &lt;code&gt;colors&lt;/code&gt; to adjust colors, and &lt;code&gt;mappings&lt;/code&gt; to store custom keybinds.&lt;/p&gt;
&lt;p&gt;Additionally, in the &lt;code&gt;accounts&lt;/code&gt; folder, I have a configuration file for each of the email accounts I want to use with neomutt. We will get to that configuration later.&lt;/p&gt;
&lt;h1 id=&#34;general-settings&#34;&gt;General Settings&lt;/h1&gt;
&lt;p&gt;Here is where we can declare some universal settings for neomutt that change core program behavior.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vim: filetype=muttrc

# set editor to neovim
set editor = &amp;quot;nvim&amp;quot;

set my_name = &amp;quot;Gideon Wolfe&amp;quot;
set imap_check_subscribed

# Set preffered view modes
auto_view text/html text/calendar application/ics # view html automatically
alternative_order text/html text/plain text/enriched text/*


# main options
set envelope_from
set edit_headers                     # show headers when composing
set fast_reply                       # skip to compose when replying
set askcc                            # ask for CC:
set fcc_attach                       # save attachments with the body
set forward_format = &amp;quot;Fwd: %s&amp;quot;       # format of subject when forwarding
set forward_decode                   # decode when forwarding
set attribution = &amp;quot;On %d, %n wrote:&amp;quot; # format of quoting header
set reply_to                         # reply to Reply to: field
set reverse_name                     # reply as whomever it was to
set include                          # include message in replies
set forward_quote                    # include message in forwards
set text_flowed
unset sig_dashes                     # no dashes before sig
unset mime_forward                   # forward attachments as part of body
unset help                           # No help bar at the top of index
# set status_on_top                    # Status bar on top of index
set tmpdir = ~/Programs/neomutt/temp # where to keep temp files

unset confirmappend      # don&#39;t ask, just do!
set quit                 # don&#39;t ask, just do!!
unset mark_old           # read/new is good enough for me
set beep_new             # bell on new mails
set pipe_decode          # strip headers and eval mimes when piping
set thorough_search      # strip headers and eval mimes before searching
set timeout = 0

# status bar, date format, finding stuff etc.
set status_chars = &amp;quot; *%A&amp;quot;
set status_format = &amp;quot;[ Folder: %f ] [%r%m messages%?n? (%n new)?%?d? (%d to delete)?%?t? (%t tagged)? ]%&amp;gt;─%?p?( %p postponed )?&amp;quot;
set date_format = &amp;quot;%d.%m.%Y %H:%M&amp;quot;
set sort = threads
set sort_aux = reverse-last-date-received
set uncollapse_jump
set sort_re
set reply_regexp = &amp;quot;^(([Rr][Ee]?(\[[0-9]+\])?: *)?(\[[^]]+\] *)?)*&amp;quot;
set quote_regexp = &amp;quot;^( {0,4}[&amp;gt;|:#%]| {0,4}[a-z0-9]+[&amp;gt;|]+)+&amp;quot;
set send_charset = &amp;quot;utf-8:iso-8859-1:us-ascii&amp;quot;
set charset = &amp;quot;utf-8&amp;quot;
set arrow_cursor = &amp;quot;no&amp;quot; # Change `color indicator` depending 

# Pager View Options
set pager_index_lines = 10  # Shows 10 lines of index when pager is active
set pager_context = 3
set pager_stop
set menu_scroll
set tilde
unset markers

set mailcap_path = ~/.config/neomutt/mailcap
set header_cache = &amp;quot;~/.cache/mutt&amp;quot;
set message_cachedir = &amp;quot;~/.cache/mutt&amp;quot;

set query_command = &amp;quot;khard email --parsable --search-in-source-files &#39;%s&#39;&amp;quot;

&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I&amp;rsquo;ll go over some of the important parts, and the things people might often want to change:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;editor&lt;/code&gt; is set to neovim, so I can write all my emails with vim.reaper!&lt;/li&gt;
&lt;li&gt;&lt;code&gt;query_command&lt;/code&gt; hooks in with the contact manager &lt;code&gt;khard&lt;/code&gt;, which I wrote about &lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/nextcloud/nextcloudworkflow/#files&#34;&gt;here&lt;/a&gt;. Tab
complete your contacts!&lt;/li&gt;
&lt;li&gt;&lt;code&gt;help&lt;/code&gt; is unset so the top bar disappears. Just press &lt;code&gt;?&lt;/code&gt; if you need to see keybindings.&lt;/li&gt;
&lt;li&gt;Optionally set &lt;code&gt;status_on_top&lt;/code&gt; to see the status bar on top. Personally I like it on the bottom, as that&amp;rsquo;s where weechat puts it.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;arrow_cursor&lt;/code&gt; can be enabled to have an arrow point to the currently selected message. I prefer the line as it&amp;rsquo;s more space efficient.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;rsquo;re curious about any configuration variable, search &lt;a href=&#34;https://neomutt.org/code/config_vars.html&#34;&gt;this&lt;/a&gt; page and you can find a description.&lt;/p&gt;
&lt;h1 id=&#34;colors&#34;&gt;Colors&lt;/h1&gt;
&lt;p&gt;This file contains the color settings for various elements within neomutt.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vim: filetype=muttrc

# Header colors:
color header blue default &amp;quot;.*&amp;quot;
color header brightmagenta default &amp;quot;^(From)&amp;quot;
color header brightcyan default &amp;quot;^(Subject)&amp;quot;
color header brightwhite default &amp;quot;^(CC|BCC)&amp;quot;

mono bold bold
mono underline underline
mono indicator reverse
mono error bold
color normal default default
color indicator brightyellow default # currently selected message. default makes bar clear, disabled arrow to save space.
color sidebar_highlight red default
color sidebar_divider brightblack black
color sidebar_flagged red black
color sidebar_new green black
color normal brightyellow default
color error red default
color tilde black default
color message cyan default
color markers red white
color attachment white default
color search brightmagenta default
color status brightyellow black
color hdrdefault brightgreen default
color quoted green default
color quoted1 blue default
color quoted2 cyan default
color quoted3 yellow default
color quoted4 red default
color quoted5 brightred default
color signature brightgreen default
color bold black default
color underline black default
color normal default default

color body brightred default &amp;quot;[\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+&amp;quot; # Email addresses
color body brightblue default &amp;quot;(https?|ftp)://[\-\.,/%~_:?&amp;amp;=\#a-zA-Z0-9]+&amp;quot; # URL
color body green default &amp;quot;\`[^\`]*\`&amp;quot; # Green text between ` and `
color body brightblue default &amp;quot;^# \.*&amp;quot; # Headings as bold blue
color body brightcyan default &amp;quot;^## \.*&amp;quot; # Subheadings as bold cyan
color body brightgreen default &amp;quot;^### \.*&amp;quot; # Subsubheadings as bold green
color body yellow default &amp;quot;^(\t| )*(-|\\*) \.*&amp;quot; # List items as yellow
color body brightcyan default &amp;quot;[;:][-o][)/(|]&amp;quot; # emoticons
color body brightcyan default &amp;quot;[;:][)(|]&amp;quot; # emoticons
color body brightcyan default &amp;quot;[ ][*][^*]*[*][ ]?&amp;quot; # more emoticon?
color body brightcyan default &amp;quot;[ ]?[*][^*]*[*][ ]&amp;quot; # more emoticon?
color body red default &amp;quot;(BAD signature)&amp;quot;
color body cyan default &amp;quot;(Good signature)&amp;quot;
color body brightblack default &amp;quot;^gpg: Good signature .*&amp;quot;
color body brightyellow default &amp;quot;^gpg: &amp;quot;
color body brightyellow red &amp;quot;^gpg: BAD signature from.*&amp;quot;
mono body bold &amp;quot;^gpg: Good signature&amp;quot;
mohttps://neomutt.org/code/config_vars.htmlno body bold &amp;quot;^gpg: BAD signature from.*&amp;quot;
color body red default &amp;quot;([a-z][a-z0-9+-]*://(((([a-z0-9_.!~*&#39;();:&amp;amp;=+$,-]|%[0-9a-f][0-9a-f])*@)?((([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?|[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)(:[0-9]+)?)|([a-z0-9_.!~*&#39;()$,;:@&amp;amp;=+-]|%[0-9a-f][0-9a-f])+)(/([a-z0-9_.!~*&#39;():@&amp;amp;=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*&#39;():@&amp;amp;=+$,-]|%[0-9a-f][0-9a-f])*)*(/([a-z0-9_.!~*&#39;():@&amp;amp;=+$,-]|%[0-9a-f][0-9a-f])*(;([a-z0-9_.!~*&#39;():@&amp;amp;=+$,-]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([a-z0-9_.!~*&#39;();/?:@&amp;amp;=+$,-]|%[0-9a-f][0-9a-f])*)?(#([a-z0-9_.!~*&#39;();/?:@&amp;amp;=+$,-]|%[0-9a-f][0-9a-f])*)?|(www|ftp)\\.(([a-z0-9]([a-z0-9-]*[a-z0-9])?)\\.)*([a-z]([a-z0-9-]*[a-z0-9])?)\\.?(:[0-9]+)?(/([-a-z0-9_.!~*&#39;():@&amp;amp;=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*&#39;():@&amp;amp;=+$,]|%[0-9a-f][0-9a-f])*)*(/([-a-z0-9_.!~*&#39;():@&amp;amp;=+$,]|%[0-9a-f][0-9a-f])*(;([-a-z0-9_.!~*&#39;():@&amp;amp;=+$,]|%[0-9a-f][0-9a-f])*)*)*)?(\\?([-a-z0-9_.!~*&#39;();/?:@&amp;amp;=+$,]|%[0-9a-f][0-9a-f])*)?(#([-a-z0-9_.!~*&#39;();/?:@&amp;amp;=+$,]|%[0-9a-f][0-9a-f])*)?)[^].,:;!)? \t\r\n&amp;lt;&amp;gt;\&amp;quot;]&amp;quot;

# Default index colors:
color index yellow default &#39;.*&#39;
color index_author red default &#39;.*&#39;
color index_number blue default
color index_subject cyan default &#39;.*&#39;

# For new mail:
color index brightyellow black &amp;quot;~N&amp;quot;
color index_author brightred black &amp;quot;~N&amp;quot;
color index_subject brightcyan black &amp;quot;~N&amp;quot;

color progress black cyan
&lt;/code&gt;&lt;/pre&gt;
  &lt;img src=&#34;https://gideonwolfe.com/img/workflow/neomutt/pager.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Here are some of the highlights (pun very intended):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;color indicator&lt;/code&gt; changes the color of the highlighted message line, or the arrow if &lt;code&gt;arrow_cursor&lt;/code&gt; is enabled.&lt;/li&gt;
&lt;li&gt;neomutt does colors by &lt;em&gt;layering&lt;/em&gt;. For example you might assign one color to the whole &lt;code&gt;index&lt;/code&gt;, and then manually add different colors for new mail, from address, etc.&lt;/li&gt;
&lt;li&gt;The various &lt;code&gt;color body&lt;/code&gt; settings assign specific colors to anything matching a given regular expression, from list items to emoticons.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These colors look good with my pywal generated themes, and are easy to read without being too hard on the eyes. Here is a &lt;a href=&#34;https://neomutt.org/feature/index-color&#34;&gt;reference&lt;/a&gt; for coloring the index page if you want to make any tweaks.&lt;/p&gt;
&lt;h1 id=&#34;mappings&#34;&gt;Mappings&lt;/h1&gt;
&lt;p&gt;On any page in neomutt, press &lt;code&gt;?&lt;/code&gt; to get a full list of defined mappings for that page.&lt;/p&gt;
&lt;p&gt;neomutt assigns mappings on a view basis. For example you could have a specific set of keybinds for when you are viewing an inbox (the &lt;code&gt;index&lt;/code&gt; view)
and another set for actually reading a message (&lt;code&gt;pager&lt;/code&gt; view).&lt;/p&gt;
&lt;p&gt;Many keybinds can be assigned to &lt;em&gt;multiple&lt;/em&gt; views by
listing the views we want to pick.&lt;/p&gt;
&lt;p&gt;Here is the contents of my &lt;code&gt;mappings&lt;/code&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vim: filetype=muttrc

# General rebindings
bind attach &amp;lt;return&amp;gt; view-mailcap
bind attach l view-mailcap
bind editor &amp;lt;space&amp;gt; noop
bind pager c imap-fetch-mail
bind index G last-entry
bind index g noop
bind index gg first-entry
bind pager,attach h exit
bind pager j next-line
bind pager k previous-line
bind pager l view-attachments
bind index D delete-message
bind index U undelete-message
bind index L limit
bind index h noop
bind index l display-message
bind browser h goto-parent
bind browser l select-entry
bind pager,browser gg top-page
bind pager,browser G bottom-page
bind index,pager,browser d half-down
bind index,pager,browser u half-up
bind index,pager R group-reply
bind index \031 previous-undeleted	# Mouse wheel
bind index \005 next-undeleted		# Mouse wheel
bind pager \031 previous-line		# Mouse wheel
bind pager \005 next-line		# Mouse wheel
bind editor &amp;lt;Tab&amp;gt; complete-query


# sidebar mappings
bind index,pager \Ck sidebar-prev
bind index,pager \Cj sidebar-next
bind index,pager \Co sidebar-open
bind index,pager \Cp sidebar-prev-new
bind index,pager \Cn sidebar-next-new
bind index,pager B sidebar-toggle-visible

# global index and pager shortcuts
bind index,pager @ compose-to-sender
bind index,pager D purge-message
bind index &amp;lt;tab&amp;gt; sync-mailbox
bind index &amp;lt;space&amp;gt; collapse-thread

# Email completion bindings
bind editor &amp;lt;Tab&amp;gt; complete-query
bind editor ^T complete

# Press A to add contact to Khard address book
macro index,pager A \
    &amp;quot;&amp;lt;pipe-message&amp;gt;khard add-email&amp;lt;return&amp;gt;&amp;quot; \
    &amp;quot;add the sender email address to khard&amp;quot;

## Shortcuts
macro index,pager &amp;lt;f2&amp;gt; &#39;&amp;lt;sync-mailbox&amp;gt;&amp;lt;enter-command&amp;gt;source ~/.config/neomutt/accounts/gmail&amp;lt;enter&amp;gt;&amp;lt;change-folder&amp;gt;!&amp;lt;enter&amp;gt;&#39;
macro index,pager &amp;lt;f3&amp;gt; &#39;&amp;lt;sync-mailbox&amp;gt;&amp;lt;enter-command&amp;gt;source ~/.config/neomutt/accounts/main&amp;lt;enter&amp;gt;&amp;lt;change-folder&amp;gt;!&amp;lt;enter&amp;gt;&#39;
macro index,pager &amp;lt;f4&amp;gt; &#39;&amp;lt;sync-mailbox&amp;gt;&amp;lt;enter-command&amp;gt;source ~/.config/neomutt/accounts/school&amp;lt;enter&amp;gt;&amp;lt;change-folder&amp;gt;!&amp;lt;enter&amp;gt;&#39;

&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The main differences between my config and the default:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;vim keybinds! &lt;code&gt;k&lt;/code&gt; and &lt;code&gt;j&lt;/code&gt; to go up and down, and &lt;code&gt;l&lt;/code&gt; and &lt;code&gt;h&lt;/code&gt; to move forwards and back pages.&lt;/li&gt;
&lt;li&gt;Open the sidebar with &lt;code&gt;B&lt;/code&gt;. &lt;code&gt;Ctrl+j&lt;/code&gt; and &lt;code&gt;Ctrl+k&lt;/code&gt; to navigate, &lt;code&gt;Ctrl+o&lt;/code&gt; to open selection&lt;/li&gt;
&lt;li&gt;&lt;code&gt;A&lt;/code&gt; will attempt to create a new contact with &lt;code&gt;khard&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;F2&lt;/code&gt;, &lt;code&gt;F3&lt;/code&gt;, and &lt;code&gt;F4&lt;/code&gt; are used to switch between my three mailboxes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I put the important binds in a little cheatsheet table for myself!&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Keybind&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Go to last entry&lt;/td&gt;
&lt;td&gt;&lt;code&gt;G&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Go to first entry&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gg&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page down&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page up&lt;/td&gt;
&lt;td&gt;&lt;code&gt;u&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete message&lt;/td&gt;
&lt;td&gt;&lt;code&gt;D&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete thread&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+d&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mark thread read&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+r&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Undelete message&lt;/td&gt;
&lt;td&gt;&lt;code&gt;U&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Limit/Filter&lt;/td&gt;
&lt;td&gt;&lt;code&gt;L&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open message&lt;/td&gt;
&lt;td&gt;&lt;code&gt;l&lt;/code&gt;, &lt;code&gt;Enter&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Group reply&lt;/td&gt;
&lt;td&gt;&lt;code&gt;R&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reply&lt;/td&gt;
&lt;td&gt;&lt;code&gt;r&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forward message&lt;/td&gt;
&lt;td&gt;&lt;code&gt;f&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New message&lt;/td&gt;
&lt;td&gt;&lt;code&gt;m&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View attachments&lt;/td&gt;
&lt;td&gt;&lt;code&gt;v&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compose to Sender&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resend message&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Esc+e&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Save message (to file)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;s&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Toggle collapse thread&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Space&lt;/code&gt;, &lt;code&gt;Esc+v&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Toggle collapse all threads&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Esc+V&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add contact to Khard&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jump to parent message&lt;/td&gt;
&lt;td&gt;&lt;code&gt;P&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Email PGP public key&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Esc+k&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;pager&#34;&gt;Pager&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Keybind&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bottom of page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;G&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Top of page&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gg&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next line&lt;/td&gt;
&lt;td&gt;&lt;code&gt;j&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Previous line&lt;/td&gt;
&lt;td&gt;&lt;code&gt;k&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View attachments&lt;/td&gt;
&lt;td&gt;&lt;code&gt;l&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page down&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page up&lt;/td&gt;
&lt;td&gt;&lt;code&gt;u&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Group reply&lt;/td&gt;
&lt;td&gt;&lt;code&gt;R&lt;/code&gt;,&lt;code&gt;g&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reply&lt;/td&gt;
&lt;td&gt;&lt;code&gt;r&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compose to Sender&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete thread&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+d&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mark thread read&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+r&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mark thread new&lt;/td&gt;
&lt;td&gt;&lt;code&gt;N&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;sidebar&#34;&gt;Sidebar&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Keybind&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Show sidebar&lt;/td&gt;
&lt;td&gt;&lt;code&gt;B&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Up&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+k&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Down&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+j&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+o&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open next new&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+n&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open previous new&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+p&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1 id=&#34;mailcap&#34;&gt;Mailcap&lt;/h1&gt;
&lt;p&gt;This file defines which programs should handle various filetypes included in email attachments.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# MS Word documents
application/msword; ~/dotfiles/office/view-attachment.sh %s &amp;quot;-&amp;quot; &#39;/Applications/LibreOffice.app&#39;
application/vnd.ms-excel; ~/dotfiles/office/view-attachment.sh %s &amp;quot;-&amp;quot; &#39;/Applications/LibreOffice.app&#39;
application/vnd.openxmlformats-officedocument.presentationml.presentation; ~/dotfiles/office/view-attachment.sh %s &amp;quot;-&amp;quot; &#39;/Applications/LibreOffice.app&#39;
application/vnd.oasis.opendocument.text; ~/dotfiles/office/view-attachment.sh %s &amp;quot;-&amp;quot; &#39;/Applications/LibreOffice.app&#39;

# HTML
text/html; w3m -I %{charset} -T text/html; copiousoutput;
text/plain; nvim %s

#PDFs
application/pdf; /usr/bin/zathura %s pdf

#Images
image/png; /usr/bin/feh %s
image/jpeg; /usr/bin/feh %s
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;I use &lt;code&gt;feh&lt;/code&gt; as a lightweight image viewer&lt;/li&gt;
&lt;li&gt;All MS office docs are handled by &lt;code&gt;LibreOffice&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;zathura&lt;/code&gt; reads my PDFs (with &lt;a href=&#34;https://github.com/GideonWolfe/Zathura-Pywal&#34;&gt;style&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HTML&lt;/code&gt; is rendered as text with &lt;code&gt;w3m&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;accounts&#34;&gt;Accounts&lt;/h1&gt;
&lt;p&gt;I won&amp;rsquo;t go over the specifics of each account here, because getting neomutt to actually talk to your mailserver is another matter entirely, for which there are dozens of tutorials.&lt;/p&gt;
&lt;p&gt;Here is a generic template for hooking up an &lt;code&gt;IMAP&lt;/code&gt; account.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# vim: filetype=muttrc
unmailboxes *

# in/out mail servers
set realname = &amp;quot;Firstname Lastname&amp;quot;
set imap_pass = &amp;quot;SOME_PASSWORD&amp;quot;
set smtp_url = &amp;quot;smtps://you@somedomain.com@mailserver.com:465&amp;quot;
set smtp_pass = &amp;quot;SOME_PASSWORD&amp;quot;
set folder = &amp;quot;imaps://you@somedomain.com@mailserver.com:993&amp;quot;
set spoolfile = &amp;quot;+INBOX&amp;quot;

set from = &amp;quot;you@somedomain.com&amp;quot;
set envelope_from
set use_from = &amp;quot;yes&amp;quot;
set record = &amp;quot;+Sent&amp;quot;
set trash = &amp;quot;+Trash&amp;quot;
set postponed = &amp;quot;+Drafts&amp;quot;
set mail_check = 6

# Allow Mutt to open a new IMAP connection automatically.
unset imap_passive

# Keep the IMAP connection alive by polling intermittently (time in seconds).
set imap_keepalive = 300

## Hook -- IMPORTANT!
account-hook $folder &amp;quot;set imap_pass=SOME_PASSWORD&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;unmailboxes *&lt;/code&gt; hides the inboxes of accounts we are not currently viewing.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;account-hook&lt;/code&gt; is the line that allows us to switch to this account with a keybind.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;And that&amp;rsquo;s basically it. If you have done everything correctly, you should be able to use neomutt to interact with multiple email accounts, switching with just a keypress.&lt;/p&gt;
&lt;p&gt;The colors should look good, and the keybinds should feel natural to a vim user. I am constantly improving this setup so don&amp;rsquo;t hesitate to throw me some suggestions.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Agents Standing By: Monitoring National Emergencies</title>
      <link>https://gideonwolfe.com/posts/sysadmin/huginn/disasters/</link>
      <pubDate>Fri, 27 Mar 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/sysadmin/huginn/disasters/</guid>
      <description>&lt;p&gt;This scenario we will go over today will allow you to set up real time alerts as FEMA updates its online database of natural disasters and emergencies.&lt;/p&gt;
&lt;p&gt;Firstly, we are going to need to set up a &lt;code&gt;Website Agent&lt;/code&gt;. This will be similar to our previous agent, as it will extract the target data from a &lt;code&gt;json&lt;/code&gt; data stream.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start by messing around with the API a little bit. Take a look at the &lt;a href=&#34;https://www.fema.gov/openfema-api-documentation&#34;&gt;full documentation&lt;/a&gt; if you have questions, but this
should introduce you to the basics.&lt;/p&gt;
&lt;p&gt;We can take a look at all the &lt;a href=&#34;https://www.fema.gov/data-sets#APIs&#34;&gt;APIs&lt;/a&gt; offered by FEMA. Let&amp;rsquo;s select the &lt;code&gt;Disaster Declarations Summaries - V2&lt;/code&gt; dataset.&lt;/p&gt;
&lt;p&gt;Under the &lt;code&gt;Data Fields&lt;/code&gt; dropdown, we can see all of the various metrics returned for a disaster declaration. To view the data, we can visit the &lt;a href=&#34;https://www.fema.gov/api/open/v2/DisasterDeclarationsSummaries&#34;&gt;link&lt;/a&gt; under the &lt;code&gt;API Endpoint&lt;/code&gt; dropdown.&lt;/p&gt;
&lt;p&gt;This will display &lt;strong&gt;ALL&lt;/strong&gt; disaster declarations. For our case, we may want to provide some filters to this data. Let&amp;rsquo;s narrow this down to our state shall we? For my cases, I will
change the URL to the following&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://www.fema.gov/api/open/v2/DisasterDeclarationsSummaries?$filter=state&#34;&gt;https://www.fema.gov/api/open/v2/DisasterDeclarationsSummaries?$filter=state&lt;/a&gt; eq &amp;lsquo;WA&amp;rsquo;&lt;/p&gt;
&lt;/blockquote&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/huginn/disasters/data.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;And then we can use a second URL to provide a list of all terrorist attacks nationwide;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://www.fema.gov/api/open/v2/DisasterDeclarationsSummaries?$filter=incidentType&#34;&gt;https://www.fema.gov/api/open/v2/DisasterDeclarationsSummaries?$filter=incidentType&lt;/a&gt; eq &amp;lsquo;Terrorist&amp;rsquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We can create website agents to monitor any number of specific queries. We could narrow down the list arbitrarily, say to Floods in Oregon from 1980 onwards. Take full advantage of
the &lt;code&gt;URI Commands&lt;/code&gt; section on the documentation, which details these filtering options.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;json&lt;/code&gt; for one of these agents is shown below&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;expected_update_period_in_days&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;url&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://www.fema.gov/api/open/v2/DisasterDeclarationsSummaries?$filter=incidentType%20eq%20%27Terrorist%27&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;json&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;on_change&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;extract&amp;#34;&lt;/span&gt;: {
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;declarationTitle&amp;#34;&lt;/span&gt;: {
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;path&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;DisasterDeclarationsSummaries.[*].declarationTitle&amp;#34;&lt;/span&gt;
    },
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;state&amp;#34;&lt;/span&gt;: {
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;path&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;DisasterDeclarationsSummaries.[*].state&amp;#34;&lt;/span&gt;
    },
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;declarationDate&amp;#34;&lt;/span&gt;: {
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;path&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;DisasterDeclarationsSummaries.[*].declarationDate&amp;#34;&lt;/span&gt;
    },
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;incidentType&amp;#34;&lt;/span&gt;: {
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;path&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;DisasterDeclarationsSummaries.[*].incidentType&amp;#34;&lt;/span&gt;
    },
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;designatedArea&amp;#34;&lt;/span&gt;: {
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;path&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;DisasterDeclarationsSummaries.[*].designatedArea&amp;#34;&lt;/span&gt;
    },
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;placeCode&amp;#34;&lt;/span&gt;: {
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;path&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;DisasterDeclarationsSummaries.[*].placeCode&amp;#34;&lt;/span&gt;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will extract values from the data like &lt;code&gt;placeCode&lt;/code&gt;, &lt;code&gt;incidentType&lt;/code&gt;, and more which can all be used as variables to format your notifications.&lt;/p&gt;
&lt;p&gt;In this scenario I have the notifications sent via email and push notification. I will show how you can format the email to correctly display information passed by the website
agent.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;subject&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{{incidentType}} Alert!&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;expected_receive_period_in_days&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;from&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Huginn@somedomain.com&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;body&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;lt;h1&amp;gt;{{declarationTitle}}&amp;lt;\/h1&amp;gt;&amp;lt;br&amp;gt;Alert! &amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;State: {{state}}&amp;lt;\/li&amp;gt;&amp;lt;li&amp;gt;Date Declared: {{declarationDate}}&amp;lt;\/li&amp;gt;&amp;lt;li&amp;gt;Area: {{designatedArea}}&amp;lt;\/li&amp;gt;&amp;lt;li&amp;gt;ZIP: {{placeCode}}&amp;lt;\/li&amp;gt;&amp;lt;\/ul&amp;gt;&amp;#34;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now I certainly could have passed the original event through a &lt;code&gt;Event Formatting&lt;/code&gt; agent to format the message before it hit the email agent. But I decided it would be easier to
simply write the formatting inline in this case.&lt;/p&gt;
&lt;p&gt;Notice that I use &lt;code&gt;HTML&lt;/code&gt; tags like &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;br&amp;gt;&lt;/code&gt;. This is extremely useful for formatting emails (especially digests) where you might want a visual indicator of how information
is separated.&lt;/p&gt;
&lt;p&gt;We also use liquid formatting to include variables passed by the incoming event, like &lt;code&gt;{{declarationTitle}}&lt;/code&gt;. The end result of this scenario is an email with all the information,
for example;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;COVID-19 PANDEMIC

Alert!

    State: WA
    Date Declared: 2020-03-22T16:21:00.000Z
    Area: Chelan (County)
    ZIP: 99007

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;note&#34;&gt;NOTE!&lt;/h3&gt;
&lt;p&gt;These listeners might appear to be &lt;code&gt;Not Working&lt;/code&gt; according to Huginn. I believe this happens if the &lt;code&gt;json&lt;/code&gt; source goes a long time without updating, or more days than allowed in &lt;code&gt;expected_receive_period_in_days&lt;/code&gt;. Be assured the agent will function when the actual data source changes.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Just by poking around the API documentation from FEMA, we are able to scrape tons of valuable data relating to events happening in the country. No longer be reliant on news
reports, be the first to know.&lt;/p&gt;
&lt;p&gt;This technique can be applied to countless open data sources and incorporated into your informational web!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Agents Standing By: Monitoring Website Status</title>
      <link>https://gideonwolfe.com/posts/sysadmin/huginn/status/</link>
      <pubDate>Wed, 25 Mar 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/sysadmin/huginn/status/</guid>
      <description>&lt;h1 id=&#34;intro&#34;&gt;Intro&lt;/h1&gt;
&lt;p&gt;One thing you might want to get a notification for immediately is when one of your websites or services is malfunctioning. Luckily, huginn has agents built to handle usecases like
this.&lt;/p&gt;
&lt;h1 id=&#34;creating-our-status-agent&#34;&gt;Creating our Status Agent&lt;/h1&gt;
&lt;p&gt;For each service you want to monitor, you are going to want to create a new &lt;code&gt;HttpStatusAgent&lt;/code&gt; with the &lt;code&gt;url&lt;/code&gt; field pointing towards the site you are monitoring. I decided to enable
redirect follows, so I can see the true &lt;code&gt;HTTP&lt;/code&gt; code my site is returning.&lt;/p&gt;
&lt;p&gt;Additionally, I set &lt;code&gt;changes_only&lt;/code&gt; to true. That means that an event is only created by this agent when the &lt;code&gt;HTTP&lt;/code&gt; status code &lt;strong&gt;changes&lt;/strong&gt; from its previous value (a 200 success
code).&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;changes_only&lt;/code&gt; field is very common with agents, and prevents your agent from re-emitting tons of duplicate events.&lt;/p&gt;
&lt;p&gt;The JSON for such an agent looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;url&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://www.somedomain.com&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;disable_redirect_follow_radio&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;false&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;disable_redirect_follow&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;false&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;changes_only_radio&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;changes_only&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;headers_to_save&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When creating a huginn agent, it is extremely helpful to look at the agent documentation to the right of the page. Any confusing fields should be explained there.&lt;/p&gt;
&lt;h1 id=&#34;creating-our-alert-agent&#34;&gt;Creating our Alert Agent&lt;/h1&gt;
&lt;p&gt;Now that we have an agent that creates events when the status of your site changes, we now want an agent to act upon those events and notify you in your preferred manner.&lt;/p&gt;
&lt;p&gt;Here we will set up a simple &lt;code&gt;Email Agent&lt;/code&gt; to notify us of a service disruption. Take a look at the complete &lt;a href=&#34;https://huginnio.herokuapp.com/agents&#34;&gt;list of agents&lt;/a&gt; for more ideas
about notifications.&lt;/p&gt;
&lt;p&gt;We want to make sure the &lt;code&gt;Event Sources&lt;/code&gt; field is populated with the status agent we made in a previous step. This means the status agent sends its events to the alert agent.&lt;/p&gt;
&lt;p&gt;Set the &lt;code&gt;subject&lt;/code&gt; and &lt;code&gt;headline&lt;/code&gt; field to whatever you want. In the below &lt;code&gt;json&lt;/code&gt; code you will notice that I used variables like &lt;code&gt;{{url}}&lt;/code&gt;. If we look in the bottom right of the
documentation for our agent, we can see a field that shows what data fields we are expecting to see from our source status agent.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;subject&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Service Interruption!&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;headline&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Your notification:&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;expected_receive_period_in_days&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;body&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{{url}} is returning status code {{status}}.&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;from&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Huginn@somedomain.com&amp;#34;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can reference these fields in our receiving agent, using what is called &lt;a href=&#34;https://github.com/huginn/huginn/wiki/Formatting-Events-using-Liquid&#34;&gt;liquid formatting&lt;/a&gt;. This allows us
to create reusable, modular agents.&lt;/p&gt;
&lt;p&gt;We can create many status agents, and because they will all output an event of the same format, we can have them all pointing to the same alert agent.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/huginn/status/flow.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Here I have a push notification set up in tandem with email, because I want to know about these alerts ASAP.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;With just two agent types we were able to create a robust HTTP monitor that will format and send notifications whenever a service is experiencing disruption.&lt;/p&gt;
&lt;p&gt;In later posts we will build up to more complex scenarios with more moving parts.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Agents Standing By: Setting Up Huginn</title>
      <link>https://gideonwolfe.com/posts/sysadmin/huginn/setup/</link>
      <pubDate>Wed, 25 Mar 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/sysadmin/huginn/setup/</guid>
      <description>&lt;h1 id=&#34;intro&#34;&gt;Intro&lt;/h1&gt;
&lt;p&gt;In my last post, I went over what Huginn is used for, and how I implement it in my workflow. Today we are going to go over the initial set up of a basic Huginn container as well as
an SMTP container to send our emails.&lt;/p&gt;
&lt;h1 id=&#34;docker-setup&#34;&gt;Docker setup&lt;/h1&gt;
&lt;p&gt;Here&amp;rsquo;s the docker compose file I am currently using for my Huginn instance:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-docker&#34; data-lang=&#34;docker&#34;&gt;version: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;3.5&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;services:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;  huginn:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    image: huginn/huginn&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    restart: always&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    ports:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - 4750:3000&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    volumes:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - $HOME/data/programs/docker/huginn/config:/var/lib/mysql&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    environment:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      &lt;span style=&#34;color:#75715e&#34;&gt;# Email Configuration&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      EMAIL_FROM_ADDRESS: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;someemail@somedomain.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      SMTP_USER_NAME: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      SMTP_PASSWORD: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      SMTP_SERVER: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mail&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      SMTP_PORT: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;25&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      SMTP_AUTHENTICATION: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      SMTP_ENABLE_STARTTLS_AUTO: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;  mail:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    image: bytemark/smtp&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    restart: always&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The important parts here are the &lt;code&gt;config&lt;/code&gt; volume mounted to the huginn container which will store our persistent data, and the &lt;code&gt;SMTP&lt;/code&gt; server that simply listens for and sends
emails sent by huginn.&lt;/p&gt;
&lt;p&gt;This setup should run fine after a &lt;code&gt;docker-compose up&lt;/code&gt;, &lt;code&gt;-d&lt;/code&gt; optional. Now navigate to your huginn instance on the machine you are running it on at port &lt;code&gt;4750&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Navigate to the &lt;code&gt;Agents&lt;/code&gt; tab and start looking around at some of the &lt;code&gt;Default Scenario&lt;/code&gt; agents. Pay attention to the layout and documentation of each agent, because in my next post
er will be doing some agent configuration.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Agents Standing By: Introduction to Huginn</title>
      <link>https://gideonwolfe.com/posts/sysadmin/huginn/intro/</link>
      <pubDate>Mon, 23 Mar 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/sysadmin/huginn/intro/</guid>
      <description>&lt;h1 id=&#34;what-is-huginn&#34;&gt;What is Huginn?&lt;/h1&gt;
&lt;p&gt;Have you ever felt out of the loop on current events? Do you tire of manually checking dozens of sites every day for the information you need? Do you wish you could quickly whip up
a bot without learning a new API and programming language?&lt;/p&gt;
&lt;p&gt;Before last week, I had heard of Huginn, but not seen how it could fit into my workflow. Now that I have a better understanding of its features, allow me to explain the ways Huginn
can improve the way you monitor important data.&lt;/p&gt;
&lt;p&gt;At its core, Huginn is an &lt;strong&gt;event monitoring&lt;/strong&gt; framework. Huginn operates with something called &lt;strong&gt;agents&lt;/strong&gt;. These agents are analogous to a &lt;code&gt;function&lt;/code&gt; in programming.&lt;/p&gt;
&lt;p&gt;An agent will listen for a specific type of data (known as an &lt;code&gt;event&lt;/code&gt;), preform some logic based operations with that data, and then emit another event with the processed data.&lt;/p&gt;
&lt;p&gt;On their own, the agents have limited capability. The true power of Huginn is leveraged when we &lt;em&gt;combine&lt;/em&gt; agents, into something called a &lt;strong&gt;scenario&lt;/strong&gt;. A scenario is a tagged collection
of agents, which usually communicate with each other to perform more complex tasks.&lt;/p&gt;
&lt;p&gt;Let me go over an example scenario so you can get an idea of how agents interact&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/huginn/economic/economic_reports.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;The top level shows three &lt;code&gt;Website Agents&lt;/code&gt;. These scrape the sites of your choice and extract data from &lt;code&gt;HTML&lt;/code&gt;, &lt;code&gt;JSON&lt;/code&gt;, or &lt;code&gt;XML&lt;/code&gt;. I have these website agents monitoring a &lt;code&gt;JSON&lt;/code&gt;
feed of cryptocurrency, market indexes, and stocks.&lt;/p&gt;
&lt;p&gt;Here is the &lt;code&gt;JSON&lt;/code&gt; for the stock monitoring agent.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;expected_update_period_in_days&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;url&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https://financialmodelingprep.com/api/v3/quote/AAPL,FB&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;json&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;mode&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;on_change&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;extract&amp;#34;&lt;/span&gt;: {
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;price&amp;#34;&lt;/span&gt;: {
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;path&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;[*].price&amp;#34;&lt;/span&gt;
    },
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;symbol&amp;#34;&lt;/span&gt;: {
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;path&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;[*].symbol&amp;#34;&lt;/span&gt;
    },
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: {
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;path&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;[*].name&amp;#34;&lt;/span&gt;
    },
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;changesPercentage&amp;#34;&lt;/span&gt;: {
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;path&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;[*].changesPercentage&amp;#34;&lt;/span&gt;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These &lt;code&gt;JSON&lt;/code&gt; feeds get sent to the middle layer of &lt;code&gt;Trigger Agents&lt;/code&gt;. These agents take the incoming event (in this case &lt;code&gt;JSON&lt;/code&gt; stock data) and evaluate it based on a value
comparison or regex.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;expected_receive_period_in_days&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;keep_event&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;false&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;rules&amp;#34;&lt;/span&gt;: [
    {
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;field&amp;gt;=value&amp;#34;&lt;/span&gt;,
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;10.00&amp;#34;&lt;/span&gt;,
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;path&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;changesPercentage&amp;#34;&lt;/span&gt;
    }
  ],
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;message&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{{name}} changed {{changesPercentage}}%. Current rate is {{price}}$.&amp;#34;&lt;/span&gt;,
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;must_match&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I have them set to extract the &lt;code&gt;changesPercentage&lt;/code&gt; field from the incoming event and re-emit an event if the symbol fluctuated +/- 10%.&lt;/p&gt;
&lt;p&gt;When these trigger agents emit an event, it is a stock fluctuation I want to know about immediately. That is why these events are sent to two notification agents. One is an email,
which I will see whenever I check it. I also send a push notification to myself so I can see the events as they happen.&lt;/p&gt;
&lt;h1 id=&#34;what-about-grafana&#34;&gt;What about Grafana?&lt;/h1&gt;
&lt;p&gt;The way I see it, Huginn and Grafana fill very separate rolls in my workflow. Grafana (and the whole TIG stack) excel at monitoring lots of different data points over time and
visualizing them beautifully. For example I could view how my hard drives are filling up over time, or which docker container is causing my CPU to throttle.&lt;/p&gt;
&lt;p&gt;Huginn is great for on the fly creation of &amp;ldquo;bots&amp;rdquo; that will monitor very specific data points and perform actions based on them. Maybe I want an text whenever a specific model of
CPU goes on sale. Or maybe I want an XKCD comic and a weather report delivered to me in a daily morning email. This is where Huginn shines.&lt;/p&gt;
&lt;p&gt;However, I plan on experimenting with &lt;em&gt;combining&lt;/em&gt; the two. What if I used Huginn to monitor and format a web data source, and send that nice formatted data to Grafana to display? I
am still trying to figure out how this would work. I have attempted to use the &lt;a href=&#34;https://grafana.com/grafana/plugins/simpod-json-datasource&#34;&gt;JSON Datasource&lt;/a&gt; on Grafana, but I have
not been able to get it working even once.&lt;/p&gt;
&lt;p&gt;Does Grafana &lt;em&gt;require&lt;/em&gt; you to store the data in some external DB? I could make the Huginn data go to &lt;code&gt;InfluxDB&lt;/code&gt;, but it seems like it would be a lot of extra work.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;In my next post, I will go over installing Huginn using docker-compose and setting up the basic SMTP server which allows for email notifications. Then we will get into setting up
some useful agents and getting used to the Huginn workflow.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Keeping your docker containers updated with Watchtower</title>
      <link>https://gideonwolfe.com/posts/sysadmin/docker/watchtower/</link>
      <pubDate>Thu, 19 Mar 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/sysadmin/docker/watchtower/</guid>
      <description>&lt;h1 id=&#34;who-needs-this&#34;&gt;Who needs this?&lt;/h1&gt;
&lt;p&gt;I for one have found myself guilty of neglecting my containers once they&amp;rsquo;re up and running. Not only am I missing out on critical security patches, but many quality of life
improvements made to my programs since I initially set them up.&lt;/p&gt;
&lt;p&gt;However I didn&amp;rsquo;t want to cause downtime for my users by updating during peak usage hours, or even break something by doing something sloppily.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s where &lt;a href=&#34;https://containrrr.github.io/watchtower/&#34;&gt;Watchtower&lt;/a&gt; comes in. Watchtower constantly checks docker containers for updates to their image. What it does next is up to
you. By default, it will stop, update, and restart the containers. It can also be set to simply download the image and notify you.&lt;/p&gt;
&lt;h1 id=&#34;setting-it-up&#34;&gt;Setting it up&lt;/h1&gt;
&lt;p&gt;This is one of the most painless setups I&amp;rsquo;ve experienced. This &lt;code&gt;docker-compose&lt;/code&gt; file contains everything I used to get it working.,&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-docker&#34; data-lang=&#34;docker&#34;&gt;version: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;services:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;   watchtower:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      image: containrrr/watchtower&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      container_name: watchtower&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      volumes:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /var/run/docker.sock:/var/run/docker.sock&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      command: --schedule &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;0 0 3 * * ?&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You have to mount the &lt;code&gt;docker&lt;/code&gt; socket in order for Watchtower to be able see the other containers. I added an optional &lt;code&gt;--schedule&lt;/code&gt; command, which takes a &lt;code&gt;cron&lt;/code&gt; expression as its
input. Here I have Watchtower scheduled to do its business at 3am, a time when I expect little to no traffic.&lt;/p&gt;
&lt;p&gt;Learn more about the configuration options &lt;a href=&#34;https://containrrr.github.io/watchtower/arguments/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One great use case is if you&amp;rsquo;re working with your own docker images/registries, you can integrate watchtower into your CI/CD pipeline to have the newest image pulled into
production as soon as it is deployed.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Using preset layouts in i3</title>
      <link>https://gideonwolfe.com/posts/workflow/i3/layouts/</link>
      <pubDate>Tue, 17 Mar 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/workflow/i3/layouts/</guid>
      <description>&lt;p&gt;While I already knew how to launch programs with my i3 &lt;code&gt;config&lt;/code&gt; file, I was lacking a way to predefine specific workspace layouts that I would want to launch on startup.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s where i3 layouts come in handy.&lt;/p&gt;
&lt;h1 id=&#34;how-to-create-a-layout&#34;&gt;How to create a layout&lt;/h1&gt;
&lt;p&gt;The first step in creating a layout is to spawn the windows you want to be launched when the layout is deployed.&lt;/p&gt;
&lt;p&gt;In this example I created a &lt;code&gt;monitor&lt;/code&gt; layout, which I use to monitor system stats, crypto prices, the news, and more.&lt;/p&gt;
&lt;p&gt;We can save the layout of the target workspace into a &lt;code&gt;json&lt;/code&gt; file with the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;i3-save-tree --workspace 8 &amp;gt; ./monitor.json
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this command &lt;code&gt;8&lt;/code&gt; is the number of the workspace I wanted to capture.&lt;/p&gt;
&lt;p&gt;Opening this file should give you a &lt;code&gt;json&lt;/code&gt; layout that includes the programs and position of your windows.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;{
    &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;//&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;tabbed&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;split&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;container&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;with&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;4&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;children&lt;/span&gt;
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;border&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pixel&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;floating&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;auto_off&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;layout&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;tabbed&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;percent&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;null&lt;/span&gt;,
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;con&amp;#34;&lt;/span&gt;,
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;nodes&amp;#34;&lt;/span&gt;: [
        {
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;border&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pixel&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_border_width&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;floating&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;auto_off&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;geometry&amp;#34;&lt;/span&gt;: {
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;height&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;614&lt;/span&gt;,
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;width&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;914&lt;/span&gt;,
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;x&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;y&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
            },
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;gotop&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;percent&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0.25&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;swallows&amp;#34;&lt;/span&gt;: [
               {
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;class&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;^URxvt$&amp;#34;&lt;/span&gt;,
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;instance&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;^gotop-startup$&amp;#34;&lt;/span&gt;
               }
            ],
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;con&amp;#34;&lt;/span&gt;
        },
        {
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;border&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pixel&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_border_width&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;floating&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;auto_off&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;geometry&amp;#34;&lt;/span&gt;: {
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;height&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;614&lt;/span&gt;,
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;width&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;914&lt;/span&gt;,
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;x&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;y&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
            },
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;newsboat&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;percent&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0.25&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;swallows&amp;#34;&lt;/span&gt;: [
               {
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;class&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;^URxvt$&amp;#34;&lt;/span&gt;,
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;instance&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;^newsboat-startup$&amp;#34;&lt;/span&gt;
               }
            ],
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;con&amp;#34;&lt;/span&gt;
        },
        {
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;border&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pixel&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_border_width&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;floating&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;auto_off&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;geometry&amp;#34;&lt;/span&gt;: {
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;height&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;614&lt;/span&gt;,
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;width&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;914&lt;/span&gt;,
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;x&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;y&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
            },
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;cointop&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;percent&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0.25&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;swallows&amp;#34;&lt;/span&gt;: [
               {
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;class&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;^URxvt$&amp;#34;&lt;/span&gt;,
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;instance&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;^cointop-startup$&amp;#34;&lt;/span&gt;
               }
            ],
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;con&amp;#34;&lt;/span&gt;
        },
        {
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;border&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pixel&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;current_border_width&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;floating&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;auto_off&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;geometry&amp;#34;&lt;/span&gt;: {
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;height&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;614&lt;/span&gt;,
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;width&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;914&lt;/span&gt;,
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;x&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;,
               &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;y&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
            },
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mop&amp;#34;&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;percent&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0.25&lt;/span&gt;,
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;swallows&amp;#34;&lt;/span&gt;: [
               {
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;class&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;^URxvt$&amp;#34;&lt;/span&gt;,
                &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;instance&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;^mop-startup$&amp;#34;&lt;/span&gt;
               }
            ],
            &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;con&amp;#34;&lt;/span&gt;
        }
    ]
}



&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can save this &lt;code&gt;json&lt;/code&gt; file in a safe place for later use.&lt;/p&gt;
&lt;h1 id=&#34;deploying-a-layout&#34;&gt;Deploying a layout&lt;/h1&gt;
&lt;p&gt;Let&amp;rsquo;s say we want this layout to launch when we log into i3. First, we need to add the following command to your i3 &lt;code&gt;config&lt;/code&gt; file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec --no-startup-id &amp;quot;i3-msg &#39;workspace 8: Monitor ; append_layout /home/gideon/.config/i3/layouts/monitor.json&#39;&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here we would replace &lt;code&gt;workspace 8: Monitor &lt;/code&gt; with the number and name of the workspace where you want this layout to be deployed.&lt;/p&gt;
&lt;p&gt;We would also change the filepath to reflect the actual location of the file where you stored your layout.&lt;/p&gt;
&lt;p&gt;What this will do is open up a series of windows corresponding to the position defined in the &lt;code&gt;json&lt;/code&gt; file. However, these windows will not be populated with any programs.&lt;/p&gt;
&lt;p&gt;These windows are placeholders, and as soon as they see a specific program has been launched, it swallows it into that window.&lt;/p&gt;
&lt;p&gt;So to get the programs to launch into our layout, we can launch them with our i3 &lt;code&gt;config&lt;/code&gt;. Here is an example for &lt;code&gt;urxvt&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;What this will do is open up a series of windows corresponding to the position defined in the &lt;code&gt;json&lt;/code&gt; file. However, these windows will not be populated with any programs.&lt;/p&gt;
&lt;p&gt;These windows are placeholders, and as soon as they see a specific program has been launched, it swallows it into that window.&lt;/p&gt;
&lt;p&gt;So to get the programs to launch into our layout, we can launch them with our i3 &lt;code&gt;config&lt;/code&gt;. Here is an example for &lt;code&gt;urxvt&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec i3-msg &#39;exec urxvt -name cointop-startup -e fish -c cointop&#39;
exec i3-msg &#39;exec urxvt -name gotop-startup -e fish -c gotop&#39;
exec i3-msg &#39;exec urxvt -name mop-startup -e fish -c mop&#39;
exec i3-msg &#39;exec urxvt -name newsboat-startup -e fish -c newsboat&#39;
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;If you know you want a certain series of windows opened up in a certain way, i3 layouts are for you.&lt;/p&gt;
&lt;p&gt;I only covered launching a layout as i3 starts, but you could just as easily bind a hotkey to start a layout for a specific task.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Adding RSS to your Hugo Site</title>
      <link>https://gideonwolfe.com/posts/sysadmin/hugo/hugorss/</link>
      <pubDate>Tue, 11 Feb 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/sysadmin/hugo/hugorss/</guid>
      <description>&lt;p&gt;I recently received a request from a reader to make a working RSS feed for my website.&lt;/p&gt;
&lt;p&gt;Even though I have posted about RSS and newsboat before, I had no idea that Hugo autogenerates an RSS feed when your website is built.&lt;/p&gt;
&lt;p&gt;The only issue is that I had a couple things misconfigured, so not everything was working as desired. In this post I will describe how I went about fixing my RSS feed.&lt;/p&gt;
&lt;h1 id=&#34;editing-configtoml&#34;&gt;Editing config.toml&lt;/h1&gt;
&lt;p&gt;The biggest misconfiguration I had was setting &lt;code&gt;baseurl=&amp;quot;/&amp;quot;&lt;/code&gt; in my &lt;code&gt;config.toml&lt;/code&gt;. This caused all links in my generated website to be &lt;strong&gt;relative paths&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For example, a link to an image on the site would be &lt;code&gt;/img/category/image.jpg&lt;/code&gt; instead of &lt;code&gt;https://gideonwolfe.com/img/category/image.jpg&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This made browsers fail to open the page when opening from an RSS reader, because the post URL was bad. Let&amp;rsquo;s change this by pointing &lt;code&gt;baseurl&lt;/code&gt; to the actual address of your site.
This should make the RSS feed at &lt;code&gt;index.xml&lt;/code&gt; include valid links.&lt;/p&gt;
&lt;p&gt;Next you can the following to the file so you show up as the &amp;ldquo;author&amp;rdquo; for all your posts.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[author]
    name = &amp;quot;My Name Here&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;showing-all-your-content&#34;&gt;Showing all your content&lt;/h1&gt;
&lt;p&gt;I really like reading the entirety of an article in my RSS reader if I can. It removes all the bloat of the original website, and just gives me the text I care about.&lt;/p&gt;
&lt;p&gt;By default, Hugo only includes a brief summary of your post in every RSS item. It took me a second to figure this out, but it&amp;rsquo;s quite a simple fix.&lt;/p&gt;
&lt;p&gt;Much like how we overrode our themes &lt;code&gt;header.html&lt;/code&gt; by copying it to &lt;code&gt;&amp;lt;HUGO ROOT&amp;gt;/layouts/partials/header.html&lt;/code&gt;, we can override the default &lt;code&gt;rss.xml&lt;/code&gt; by copying it to &lt;code&gt;&amp;lt;HUGO ROOT&amp;gt;/layouts/_default/rss.xml&lt;/code&gt; and editing it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-xml&#34; data-lang=&#34;xml&#34;&gt;{{- $pctx := . -}}
{{- if .IsHome -}}{{ $pctx = .Site }}{{- end -}}
{{- $pages := $pctx.RegularPages -}}
{{- $limit := .Site.Config.Services.RSS.Limit -}}
{{- if ge $limit 1 -}}
{{- $pages = $pages | first $limit -}}
{{- end -}}
{{- printf &amp;#34;&lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;?xml version=\&amp;#34;1.0\&amp;#34; encoding=\&amp;#34;utf-8\&amp;#34; standalone=\&amp;#34;yes\&amp;#34;?&amp;gt;&lt;/span&gt;&amp;#34; | safeHTML }}
&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;rss&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;version=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;xmlns:atom=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http://www.w3.org/2005/Atom&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;channel&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;{{ if eq  .Title  .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;link&amp;gt;&lt;/span&gt;{{ .Permalink }}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/link&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;description&amp;gt;&lt;/span&gt;Recent content {{ if ne  .Title  .Site.Title }}{{ with .Title }}in {{.}} {{ end }}{{ end }}on {{ .Site.Title }}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;generator&amp;gt;&lt;/span&gt;Hugo -- gohugo.io&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/generator&amp;gt;&lt;/span&gt;{{ with .Site.LanguageCode }}
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;language&amp;gt;&lt;/span&gt;{{.}}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/language&amp;gt;&lt;/span&gt;{{end}}{{ with .Site.Author.email }}
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;managingEditor&amp;gt;&lt;/span&gt;{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/managingEditor&amp;gt;&lt;/span&gt;{{end}}{{ with .Site.Author.email }}
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;webMaster&amp;gt;&lt;/span&gt;{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/webMaster&amp;gt;&lt;/span&gt;{{end}}{{ with .Site.Copyright }}
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;copyright&amp;gt;&lt;/span&gt;{{.}}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/copyright&amp;gt;&lt;/span&gt;{{end}}{{ if not .Date.IsZero }}
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;lastBuildDate&amp;gt;&lt;/span&gt;{{ .Date.Format &amp;#34;Mon, 02 Jan 2006 15:04:05 -0700&amp;#34; | safeHTML }}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/lastBuildDate&amp;gt;&lt;/span&gt;{{ end }}
    {{ with .OutputFormats.Get &amp;#34;RSS&amp;#34; }}
	{{ printf &amp;#34;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;atom:link&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;href=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%q&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;rel=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;\&amp;#34;self\&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;type=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;%q&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;/&amp;gt;&lt;/span&gt;&amp;#34; .Permalink .MediaType | safeHTML }}
    {{ end }}
    {{ range $pages }}
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;item&amp;gt;&lt;/span&gt;
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;{{ .Title }}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;link&amp;gt;&lt;/span&gt;{{ .Permalink }}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/link&amp;gt;&lt;/span&gt;
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;pubDate&amp;gt;&lt;/span&gt;{{ .Date.Format &amp;#34;Mon, 02 Jan 2006 15:04:05 -0700&amp;#34; | safeHTML }}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/pubDate&amp;gt;&lt;/span&gt;
      {{ with .Site.Author.email }}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;author&amp;gt;&lt;/span&gt;{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/author&amp;gt;&lt;/span&gt;{{end}}
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;guid&amp;gt;&lt;/span&gt;{{ .Permalink }}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/guid&amp;gt;&lt;/span&gt;
      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;description&amp;gt;&lt;/span&gt;{{ .Content | html }}&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/description&amp;gt;&lt;/span&gt; 
    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/item&amp;gt;&lt;/span&gt;
    {{ end }}
  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/channel&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;/rss&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The only thing that I did was change the word &lt;code&gt;.Summary&lt;/code&gt; to &lt;code&gt;.Content&lt;/code&gt; near the bottom of the file. Now my posts display the full text when opened in an RSS reader.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Now you should be able to view your site in an RSS reader, just like your other favorite blogs and websites.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Adding Google Analytics to your Hugo Site</title>
      <link>https://gideonwolfe.com/posts/sysadmin/hugo/hugogoogleanalytics/</link>
      <pubDate>Mon, 10 Feb 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/sysadmin/hugo/hugogoogleanalytics/</guid>
      <description>&lt;p&gt;When I first created this site, I really wasn&amp;rsquo;t expecting much traffic. But since that time, I have become aware of many backlinks pointing this way, and I wanted to find out some
statistics about the visitors to my site.&lt;/p&gt;
&lt;p&gt;The solution to this came when a friend of mine told me about Google Analytics. Being a Google product, the primary purpose of this tool is to collect metrics on your users so you
can more effectively cram ads down their throats.&lt;/p&gt;
&lt;p&gt;Since I have no interest in advertising on this site, I will only be making use of the basic analytics features.&lt;/p&gt;
&lt;h1 id=&#34;set-up-your-google-analytics-account&#34;&gt;Set up your Google Analytics account&lt;/h1&gt;
&lt;p&gt;This part is pretty straightforward, and took me about 5 minutes to do.&lt;/p&gt;
&lt;p&gt;Head over to &lt;a href=&#34;https://analytics.google.com/&#34;&gt;https://analytics.google.com/&lt;/a&gt; and make an account (or sign in with your Google account).&lt;/p&gt;
&lt;p&gt;Set up your &amp;ldquo;Property&amp;rdquo;, give it a name, and point it to the URL of the site you plan on tracking.&lt;/p&gt;
&lt;p&gt;Click through the basic options until you land on a page with a &lt;code&gt;Tracking Code&lt;/code&gt;. This is the value we need to be keeping track of.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re having trouble with this step then I recommend checking out &lt;a href=&#34;http://cloudywithachanceofdevops.com/posts/2018/05/17/setting-up-google-analytics-on-hugo/&#34;&gt;this&lt;/a&gt; tutorial,
which has &lt;em&gt;very&lt;/em&gt; detailed step by step instructions for configuring your GA account.&lt;/p&gt;
&lt;h1 id=&#34;configuring-hugo&#34;&gt;Configuring Hugo&lt;/h1&gt;
&lt;p&gt;Thankfully, Hugo has a built in template for Google Analytics. All we need to do is make sure the template gets included in all our pages, so we can have more detailed tracking.&lt;/p&gt;
&lt;h3 id=&#34;headerhtml&#34;&gt;header.html&lt;/h3&gt;
&lt;p&gt;The easiest way to do this is to insert the template into the &lt;code&gt;header.html&lt;/code&gt; file used by your Hugo theme of choice.&lt;/p&gt;
&lt;p&gt;Since it is common to use a git submodule as a theme directory, it could be undesirable and messy to write changes directly into the submodule.&lt;/p&gt;
&lt;p&gt;The solution to this is to create another directory &lt;code&gt;layouts&lt;/code&gt; in the root of your hugo directory. Hugo looks at the contents of this folder and uses it to overwrites the styles
defined by your theme.&lt;/p&gt;
&lt;p&gt;For example I use the &lt;code&gt;Terminal&lt;/code&gt; theme. The header file is located at &lt;code&gt;&amp;lt;HUGO ROOT&amp;gt;/themes/terminal/layouts/partials/header.html&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We can copy this file to our new directory, so it sits at &lt;code&gt;&amp;lt;HUGO ROOT&amp;gt;/layouts/partials/header.html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Next we can edit our &lt;code&gt;header.html&lt;/code&gt; file to include the template for google analytics. Your &lt;code&gt;header.html&lt;/code&gt; will look different depending on the theme you&amp;rsquo;re using, but there
should be a &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; section at the top. If not we can simply create it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-HTML&#34; data-lang=&#34;HTML&#34;&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;head&lt;/span&gt;&amp;gt;
  {{ template &amp;#34;_internal/google_analytics.html&amp;#34; . }}
  {{ template &amp;#34;_internal/google_analytics_async.html&amp;#34; . }}
&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;head&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Adding these two lines inside &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; will make the google tracking code embed in the &lt;code&gt;HTML&lt;/code&gt; of all of your pages.&lt;/p&gt;
&lt;h3 id=&#34;configtoml&#34;&gt;config.toml&lt;/h3&gt;
&lt;p&gt;Finally we need to use that tracking code from earlier. At the top level of your &lt;code&gt;config.toml&lt;/code&gt;, add the line&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;googleAnalytics = &amp;quot;UA-302012394-1&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Replacing the string with your Google Analytics tracking code. After you rebuild the site, everything should work as expected! You should also be able to detect the traffic by
running the server locally as well, before you push to production.&lt;/p&gt;
&lt;h2 id=&#34;note&#34;&gt;Note!&lt;/h2&gt;
&lt;p&gt;I had quite the time figuring out why I couldn&amp;rsquo;t see any activity on my site. Being the paranoid privacy nut that I am, I have a multitude of tracker/script blocker plugins on my
browsers, to block nefarious ads/scripts.&lt;/p&gt;
&lt;p&gt;This also blocks the tracking I &lt;em&gt;do&lt;/em&gt; want, wouldn&amp;rsquo;t you know. I switched over to a private window without plugins and the traffic was instantly visible!&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Google Analytics is probably the most painless way to get in depth tracking for your Hugo site. In a future post I want to investigate ways to get all that beautiful data into
Grafana, the tool built for scenarios like these.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>vim.reaper: 💀 What&#39;s new?</title>
      <link>https://gideonwolfe.com/posts/programming/general/vimreaper-update/</link>
      <pubDate>Sat, 01 Feb 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/programming/general/vimreaper-update/</guid>
      <description>&lt;h1 id=&#34;what-is-vimreaper&#34;&gt;What is vim.reaper?&lt;/h1&gt;
&lt;p&gt;vim.reaper is simply my publicly available neovim configuration that includes advanced functionality out of the box, is easy to modify to your usecase, and looks great with your
system theme.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/neovim/reaper/startify.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;If you are a fan of customizing your dotfiles like me, you may find it helpful to have a solid jumping off point for an ambitious project as a fully customized vim setup.&lt;/p&gt;
&lt;p&gt;I spent more time than I would like to admit trawling through the documentation for various plugins, finding the best ones, and configuring them to my preferences.&lt;/p&gt;
&lt;p&gt;If your preferences don&amp;rsquo;t happen to match mine, vim.reaper allows you to easily find the configuration of choice and modify it to your hearts content.&lt;/p&gt;
&lt;h2 id=&#34;lazygit&#34;&gt;Lazygit&lt;/h2&gt;
&lt;p&gt;Now I know some people swear by the command line git (which is what I use 99% of the time), but every once in a while it can be nice to have a visual overview of your current git
environment, which can get quite complicated at times.&lt;/p&gt;
&lt;p&gt;Even the built in git keybinds vim.reaper already has can only get you so far.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/neovim/reaper/lazygit.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;This is where &lt;a href=&#34;https://github.com/jesseduffield/lazygit&#34;&gt;lazygit&lt;/a&gt; comes in. This neat TUI provides you with a visual interface to manage your current git environment. Commits,
merges and more can be managed with common sense keybinds.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t need fancy VCS integration into my IDE, but a quick interface like lazygit really comes in handy!&lt;/p&gt;
&lt;h2 id=&#34;lazydocker&#34;&gt;Lazydocker&lt;/h2&gt;
&lt;p&gt;From the developer of lazygit comes &lt;a href=&#34;https://github.com/jesseduffield/lazydocker&#34;&gt;lazydocker&lt;/a&gt;, a TUI for managing your docker environment.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/neovim/reaper/lazydocker.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Like lazygit, lazydocker opens in a centered floating window and uses common sense keybinds to allow you to quickly peruse your images, containers, volumes, configurations and
more.&lt;/p&gt;
&lt;p&gt;This is an invaluable tool for my media server, allowing me to check the logs and status of every container in the stack, with informative graphs and stats.&lt;/p&gt;
&lt;p&gt;lazygit and lazydocker can be opened with &lt;code&gt;&amp;lt;Leader&amp;gt;lg&lt;/code&gt; and &lt;code&gt;&amp;lt;Leader&amp;gt;ld&lt;/code&gt; respectively.&lt;/p&gt;
&lt;h2 id=&#34;vimtex&#34;&gt;vimtex&lt;/h2&gt;
&lt;p&gt;If you take any upper level Math/CS class, or research in pretty much any STEM field, you are bound to encounter or be required to produce LaTeX documents at some point.&lt;/p&gt;
&lt;p&gt;LaTeX is an extremely powerful typesetting engine, but it can be quite a pain to learn at first.&lt;/p&gt;
&lt;p&gt;Most people rely on online tools like &lt;a href=&#34;https://www.overleaf.com/&#34;&gt;overleaf&lt;/a&gt; which can be helpful, but I prefer a workflow where I can actually work on my projects if I have no
internet, or if overleaf is down for whatever reason.&lt;/p&gt;
&lt;p&gt;The plugin suite I have implemented in vim.reaper provides an overleaf like workflow, complete with automatic document compilation and linting.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/neovim/reaper/latex.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Simply open a LaTeX document, press &lt;code&gt;&amp;lt;Leader&amp;gt;lc&lt;/code&gt; to start compilation, and see the pdf open in your configured reader, I use zathura.&lt;/p&gt;
&lt;p&gt;As you can see on the left side of the image, neovim is more than happy to scold me for my sloppy syntax, which is helpful for a learner like me.&lt;/p&gt;
&lt;h2 id=&#34;markdown-preview&#34;&gt;Markdown preview&lt;/h2&gt;
&lt;p&gt;For years I struggled to find a way to effectively take notes on my computer, because every program seemed far too clunky to accommodate the variety of structures and equations I
would need to record.&lt;/p&gt;
&lt;p&gt;Some true gods take notes in pure LaTeX, but that seems a bit excessive, and I would waste most my time debugging errors instead of listening to the lecture.&lt;/p&gt;
&lt;p&gt;The workflow I settled on was the same one I use to write this very blog. I use neovim to write markdown, and have it previewed to me live on a local webserver.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/neovim/reaper/markdown.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;This setup is essentially the best of both worlds. These markdown files can be opened and read by any markdown viewer, or just read as plain text files.&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s more, I can use any of the extremely flexible markdown syntax that suits my needs, including support for LaTeX rendering, diagrams, code blocks, and more.&lt;/p&gt;
&lt;p&gt;To make the whole setup perfect, I manually modified the look of the markdown preview to take colors from &lt;code&gt;wal&lt;/code&gt;, meaning it will look just like any other program in your cohesively
themed system.&lt;/p&gt;
&lt;p&gt;Finally, a setup that allows me to take the notes I need without being slowed down by cumbersome software.&lt;/p&gt;
&lt;h2 id=&#34;translation&#34;&gt;Translation&lt;/h2&gt;
&lt;p&gt;Now there is a configurable translation plugin! Run your text of choice through your favorite translation engine.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/neovim/reaper/translate.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;You can set the output to display in a window, or simply replace the target text in your document.&lt;/p&gt;
&lt;h2 id=&#34;misc&#34;&gt;Misc&lt;/h2&gt;
&lt;p&gt;Taking advantage of this fancy new centered floating window patch, vista fzf now Opens in a centered window instead of at the bottom of the screen.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/neovim/reaper/vistafuzzy.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I am always looking to improve this setup, so don&amp;rsquo;t hesitate to send a PR if you have a good idea. I&amp;rsquo;m looking forward to continued development of this robust configuration.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Chat like it&#39;s ~~2000~~ 2020: Using IRC in the modern world</title>
      <link>https://gideonwolfe.com/posts/workflow/irc/</link>
      <pubDate>Fri, 17 Jan 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/workflow/irc/</guid>
      <description>&lt;p&gt;Have you ever been frustrated with the bloated nature of todays favorite chat applications? I for one prefer the simplicity of a text based chat to all the bells and whistles
provided by competitors.&lt;/p&gt;
&lt;p&gt;On IRC you can browse thousands of publicly listed chatrooms, many tailored to the exact software or system you happen to be using. While IRC might not be a drop in substitute to
more fleshed out teamchat programs, nothing beats hopping into a chat room full of strangers to troubleshoot and discuss whatever the topic of the room may be. Think subreddits,
but in real time.&lt;/p&gt;
&lt;p&gt;Now currently I&amp;rsquo;m not in a position where I&amp;rsquo;m forced to use a proprietary chat software at work. Thusly I have not yet been forced to configure my IRC clients to work with other
protocols like Slack or Steam.&lt;/p&gt;
&lt;p&gt;If and when I am put into that unfortunate position, you can expect a tutorial on configuring bitlbee!&lt;/p&gt;
&lt;h1 id=&#34;the-irc-client&#34;&gt;The IRC Client&lt;/h1&gt;
&lt;p&gt;To keep consistency in my terminal workflow, I opt to use &lt;a href=&#34;https://weechat.org/&#34;&gt;Weechat&lt;/a&gt;, a fast and configurable terminal IRC client.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/workflow/irc/weechat.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;The configuration for weechat is crazy complex, so I will leave the custom settings for another post. Let&amp;rsquo;s address the basics. On my left side there is a list of active buffers. A
buffer can be a public channel, a PM with another user, or even a window to issue settings and commands.&lt;/p&gt;
&lt;p&gt;The networks I am connected to are the farthest to the left, and indented under them are the channels to which I am connected.&lt;/p&gt;
&lt;p&gt;If a channel is highlighted pink, it means there has been activity since I last saw it. The buffer I am currently attached to is denoted with the &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; before it.&lt;/p&gt;
&lt;h1 id=&#34;adding-networks&#34;&gt;Adding networks&lt;/h1&gt;
&lt;p&gt;In today&amp;rsquo;s climate, the go to IRC network is &lt;a href=&#34;https://www.freenode.net&#34;&gt;freenode&lt;/a&gt;, having by far the most active channels.&lt;/p&gt;
&lt;p&gt;I also opt to join the &lt;a href=&#34;https://snoonet.org&#34;&gt;snoonet&lt;/a&gt; network, which hosts channels for many popular subreddits.&lt;/p&gt;
&lt;p&gt;You can browse thousands of channels &lt;a href=&#34;https://netsplit.de/&#34;&gt;here&lt;/a&gt;, with topics spanning all hobbies and professions (with a heavy tech slant, seeing as this is IRC after all).&lt;/p&gt;
&lt;p&gt;I will quickly break down how to get up and running with freenode and weechat.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/server add freenode chat.freenode.net&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/connect freenode&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You should be connected to freenode. Now we need to register a nickname.&lt;/p&gt;
&lt;p&gt;Change the your nickname to your desired one with this command&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/nick &amp;lt;nickname&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Assuming the nick is available, you can register it with&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/msg NickServ REGISTER password youremail@example.com&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Assuming you are only using IRC on one machine at a time, and only plan on using weechat, you can go ahead and start joining channels with &lt;code&gt;/join #channel&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&#34;znc&#34;&gt;ZNC&lt;/h1&gt;
&lt;p&gt;This wasn&amp;rsquo;t enough for me. I wanted to be able to access IRC on my phone, and see the history of conversations I had missed, or carry on a conversation if I had to leave the
house. These are default features for any modern chat client.&lt;/p&gt;
&lt;p&gt;As it stands now, you are only allowed to log in to your nickname from one client at a time, throwing a wrench in the above requirements. Even if I diligently logged in and out of
each client anytime I went anywhere, I would be joining the channels without any context of the conversation currently in place.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s where an IRC bouncer comes in. A bouncer keeps a constant connection to your favorite networks and channels, allowing you to connect to your bouncer with as many clients as
you please.&lt;/p&gt;

  &lt;img src=&#34;https://wiki.znc.in/images/4/4f/Overview_network_scheme.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Not only that, there are a host of additional features such as logging and support for multiple users! The bouncer I am using is &lt;a href=&#34;https://wiki.znc.in/ZNC&#34;&gt;ZNC&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Normally, I would reverse proxy my ZNC traffic with Traefik. Unfortunately, Traefik seems to have a real tough time with TCP, and the documentation is just not there yet for me to
get this working. Many others I talked to shared my frustrations.&lt;/p&gt;
&lt;p&gt;Because of this, I am simply exposing the port on the container and then forwarding the port on my router to the IRC entrypoint.&lt;/p&gt;
&lt;p&gt;The docker compose section for ZNC is as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-docker&#34; data-lang=&#34;docker&#34;&gt;   znc:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      image: linuxserver/znc&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      container_name: znc&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      environment:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - PUID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - PGID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - TZ&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;Europe/Los_Angeles&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      volumes:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - $HOME/data/programs/docker/znc/config/:/config&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      ports:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - 4798:4798 &lt;span style=&#34;color:#75715e&#34;&gt;# Port bind for IRC only traffic&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - 6501:6501 &lt;span style=&#34;color:#75715e&#34;&gt;# Only exposed locally for web admin&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I opted to create a second port bind in ZNC, which I expose to the web. This only allows IRC traffic, nobody will mess with the config page.&lt;/p&gt;

  &lt;img src=&#34;https://wiki.znc.in/images/d/d5/Webadmin-settings-dark-clouds.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Here you can see the ZNC settings page, where you can configure users, the networks they belong to, and the channels they should connect to. Scrolling down even further we can see
a list of modules, their arguments and their status.&lt;/p&gt;
&lt;p&gt;Now we want to connect to our ZNC instance from Weechat! That can be done with the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/server add ZNC-Network &amp;lt;znc address&amp;gt;/&amp;lt;port&amp;gt; -username=user/Network -password=&amp;lt;znc pass&amp;gt; -autoconnect
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you are connected to multiple IRC networks through ZNC, you need to add a separate ZNC connection for every network. For example for freenode, I would do the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/server add ZNC-Freenode irc.mydomain.tld/4798 -username=gideon/Freenode -password=&amp;lt;znc pass&amp;gt; -autoconnect
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note the name of the network (defined in ZNC settings) becomes part of the username argument. Different clients will have different ways of Handling this.&lt;/p&gt;
&lt;p&gt;If everything works correctly, your client should rapidly connect to all the channels you configured. Grab your favorite mobile IRC client (there is a mobile version of Weechat)
and connect to the ZNC! Now you can take all your conversations on the go.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;IRC is a super valuable resource for discussing and troubleshooting various topics with knowledgeable people from around the world!&lt;/p&gt;
&lt;p&gt;This guide is meant to outline the steps to creating a seamless IRC experience in the 21st century, while keeping what makes IRC special in the first place. In another tutorial I
will go into some advanced Weechat configuration to bring out the best of the client!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Quantifying Your life: Advanced TIG Techniques</title>
      <link>https://gideonwolfe.com/posts/sysadmin/tig/advanced/</link>
      <pubDate>Wed, 01 Jan 2020 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/sysadmin/tig/advanced/</guid>
      <description>&lt;h1 id=&#34;introduction&#34;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Happy 2020! I can&amp;rsquo;t think of a better way to welcome in the new decade than taking control of your technical and personal life through hard data. In my last post I went over how to
setup the TIG stack, a software ecosystem that collects, stores, and displays data collected from a variety of sources.&lt;/p&gt;
&lt;p&gt;In this post, I will go over some more advanced techniques for Grafana in particular, and how to get custom charts and graphics specifically tailored to your needs. Let&amp;rsquo;s get right
into it!&lt;/p&gt;
&lt;h1 id=&#34;monitoring-docker&#34;&gt;Monitoring Docker&lt;/h1&gt;
&lt;p&gt;Since all of my mission critical software runs in docker containers, I thought my first priority should be to make sure I can see how all the containers are doing individually. I
started searching the &lt;a href=&#34;https://grafana.com/grafana/dashboards&#34;&gt;Grafana Dashboard&lt;/a&gt; website and started messing with some of the docker ones users had made. I&amp;rsquo;ll walk you through one
I took and modified to suit my needs.&lt;/p&gt;
&lt;h2 id=&#34;defining-variables&#34;&gt;Defining variables&lt;/h2&gt;
&lt;p&gt;Grafana has a great feature where you can query your database and save the result to a dashboard variable. In this example, we are going to get the name of all the containers so we
can make one row and duplicate it for every docker container.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/TIG/variables.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;The top query will return a list of the current docker containers.&lt;/p&gt;
&lt;h2 id=&#34;crafting-queries&#34;&gt;Crafting Queries&lt;/h2&gt;
&lt;p&gt;Now we can start creating panels using this variable&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/TIG/cpu_query.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;If we start creating more panels to show more stats about a container, we can put it in a row and duplicate it for every instance of the &lt;code&gt;Container&lt;/code&gt; variable.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/TIG/jellyfinpanel.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Jellyfin isn&amp;rsquo;t logging anything interesting at the moment, but all these metrics are helpful to have on hand if you are experiencing issues with any of your services.&lt;/p&gt;
&lt;h1 id=&#34;system-metrics&#34;&gt;System Metrics&lt;/h1&gt;
&lt;p&gt;Much like monitoring docker containers, monitoring your actual hardware mostly involves clicking around the query constructor to see what fields are available in the database. I
organized my system metrics dashboard in a sane way, with a variable for the host so I could reuse the same dashboard to monitor different hosts.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/TIG/systemstats.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Make sure to check out the full list of &lt;a href=&#34;https://grafana.com/grafana/plugins?orderBy=weight&amp;amp;direction=asc&#34;&gt;Grafana plugins&lt;/a&gt; to see if there are any visualizations that make sense
for your usecase. I love the singlestats and guages, which allow you to see the current status of a metric at a quick glance without worrying about temporal changes.&lt;/p&gt;
&lt;p&gt;I also prefer a black background for most of my dashboards, with transparent panels on top. I guess that&amp;rsquo;s because I&amp;rsquo;m &lt;code&gt;1337&lt;/code&gt;. Or I don&amp;rsquo;t have better design ideas. Let&amp;rsquo;s just go
with the first one.&lt;/p&gt;
&lt;h1 id=&#34;flowcharts&#34;&gt;Flowcharts&lt;/h1&gt;
&lt;p&gt;Speaking of third party plugins, allow me to introduce the &lt;a href=&#34;https://grafana.com/grafana/plugins/agenty-flowcharting-panel&#34;&gt;flowcharting&lt;/a&gt; plugin. This plugin allows you to create
custom &lt;code&gt;xml&lt;/code&gt; diagrams using draw.io, and link the xml elements to database queries.&lt;/p&gt;
&lt;p&gt;If all that sounded like nonsense, let me give you an example. Remember the cover of this
article? That&amp;rsquo;s a neat little diagram of my current docker stack.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/TIG/dockerstats.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;What if I told you this was more than a static diagram? By simply hovering my mouse over a container, I am presented with at-a-glance statistics about that container.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/TIG/hoverstats.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 50%&#34;  /&gt;


&lt;p&gt;How does this work? Well it took me a bit of trial and error to get this working as it is a bit unintuitive at first. First, we have to create database queries for everything we
want to measure. This is done from within the &amp;ldquo;Queries&amp;rdquo; menu of your new flowcharting panel.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/TIG/lidarr_query.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;There could be a &lt;em&gt;lot&lt;/em&gt; of queries. I was monitoring the CPU and memory usage of 12+ containers, so plugging in all the queries can get tedious.&lt;/p&gt;
&lt;p&gt;Now we go back to the &amp;ldquo;Visualization&amp;rdquo; section of the panel. Here we can click the link to open draw.io and edit our XML diagram to your hearts content. Once you&amp;rsquo;ve done this,
scroll down to the &amp;ldquo;rules&amp;rdquo; section.&lt;/p&gt;
&lt;p&gt;Here we will need to create a new rule for every metric we want to monitor. In the example below, I am setting up a rule to monitor the CPU usage of Lidarr, like the query from the
previous image.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/TIG/rules.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;In the &amp;ldquo;Apply to metrics&amp;rdquo; field, we use the alias names of one of the queries we created in the previous menu. We set Aggregation to &amp;ldquo;Last&amp;rdquo; to collect the last stored value in our
database.&lt;/p&gt;
&lt;p&gt;Next we can set some value thresholds, which define acceptable levels for any particular metric. In this example, any CPU usage above 50% would be a &lt;code&gt;warning&lt;/code&gt; level, but that
would change to &lt;code&gt;critical&lt;/code&gt; if the CPU usage exceeded 80%.&lt;/p&gt;
&lt;p&gt;On the lower half of the rule menu, we can enable the on-hover tooltip metrics, along with an optional graph. I like to have the graph colored to whatever state the rule is in.
That way, I can have a visual representation of any issues in my system.&lt;/p&gt;
&lt;p&gt;Not only can you hover over objects to get information, you can color the objects too!&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/TIG/alert.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 70%&#34;  /&gt;


&lt;p&gt;Here I changed the warning threshold to 1% to show you what it looks like if I was at a high level of memory usage. The box turned the warning color (whatever you define it to be)
and flashes an icon (if enabled).&lt;/p&gt;
&lt;p&gt;I set the Traefik container and the surrounding box to always display the state color, so I could always be sure my reverse proxy was functioning
intentionally.&lt;/p&gt;
&lt;h1 id=&#34;other-data-sources&#34;&gt;Other data sources&lt;/h1&gt;
&lt;p&gt;Getting data from Telegraf is great, but InfluxDB and Grafana can do so much more. In the future when I can afford such luxuries, I intend to hook up all manors of metrics into
Influx, so they can all be viewed within Grafana. The possibilities are truly endless. I could monitor everything from my stock portfolio to my smarthome (when I get around to
setting that up).&lt;/p&gt;
&lt;p&gt;One interesting source is the &amp;ldquo;Sun and Moon&amp;rdquo; datasource. Here I&amp;rsquo;ve created a fun dashboard that covers most of the metrics available from that datasource.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/TIG/space.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Here&amp;rsquo;s a snippet from an economics dashboard I threw together with the &amp;ldquo;Finance&amp;rdquo; datasource:&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/TIG/finance.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;I really would like more documentation on the &amp;ldquo;Simple JSON&amp;rdquo; datasource, so we could use regular JSON endpoints as data and log it from there.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;In this post I showed you how to take your Grafana game to the next level and utilize some amazing plugins to make your TIG stack work for you.&lt;/p&gt;
&lt;p&gt;With enough experimentation, you can
get your TIG stack to monitor everything from your beer brewing operation to your home security system. I hope to explore some of these options in the near future!&lt;/p&gt;
&lt;p&gt;Happy New Years! 😄&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Quantifying Your life: Introduction to the TIG Stack</title>
      <link>https://gideonwolfe.com/posts/sysadmin/tig/intro/</link>
      <pubDate>Wed, 11 Dec 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/sysadmin/tig/intro/</guid>
      <description>&lt;h1 id=&#34;introduction&#34;&gt;Introduction&lt;/h1&gt;
&lt;p&gt;Ever since I was little, I admired the flashy neon-filled screens of fictional tech-wizards, with colorful graphs and charts flying all over place. Since settling into my Linux
lifestyle, I had come to terms with the fact that I will be interacting much more with plaintext output logs and debug files than I would be hypnotizing myself with data straight
out of NGE.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/TIG/nge1.gif&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;That was before I found out about the TIG/TICK stack. These software stacks can be used to monitor and visualize pretty much any data input you can imagine. Smart home appliances,
sensors, ping stats, CPU usage, stock prices, you name it. There are a few differences between the two stacks, which I will briefly outline:&lt;/p&gt;
&lt;p&gt;TICK Stack:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.influxdata.com/time-series-platform/telegraf/&#34;&gt;Telegraf&lt;/a&gt;: Scoops up metrics from a huge variety of inputs&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.influxdata.com/products/influxdb-overview/&#34;&gt;InfluxDB&lt;/a&gt;: Stores metrics in a time-series database&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.influxdata.com/time-series-platform/chronograf/&#34;&gt;Chronograf&lt;/a&gt;: Visualize and interact with the metrics and database&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.influxdata.com/time-series-platform/kapacitor/&#34;&gt;Kapacitor&lt;/a&gt;: Streams data from database and acts on it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are all programs made by the same company, &lt;a href=&#34;https://www.influxdata.com/&#34;&gt;InfluxData&lt;/a&gt;. This stack would probably be my first choice for a production level enterprise
environment. This is because the ecosystem is all tied together, and Kapacitor allows you to designate actions to be executed in the case of defined metrics being hit.&lt;/p&gt;
&lt;p&gt;However for the home lab usecase, I think the TIG stack is a better fit.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.influxdata.com/time-series-platform/telegraf/&#34;&gt;Telegraf&lt;/a&gt;: Scoops up metrics from a huge variety of inputs&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.influxdata.com/products/influxdb-overview/&#34;&gt;InfluxDB&lt;/a&gt;: Stores metrics in a time-series database&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://grafana.com/&#34;&gt;Grafana&lt;/a&gt;: Query database and display desired data&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this stack you are still able to see all of your collected data in whatever format you like, but there&amp;rsquo;s no need to set up an actions/trigger system if you don&amp;rsquo;t need one.
Additionally, I prefer the interface and options provided by Grafana. Let&amp;rsquo;s start setting stuff up!&lt;/p&gt;
&lt;h1 id=&#34;a-note-about-influxdb&#34;&gt;A Note About InfluxDB&lt;/h1&gt;
&lt;p&gt;When I began this project, I opted for the newest version of InfluxDB, V 2.0. Although I knew it was in alpha, I wanted to reduce my technical debt up the road as much as possible.
Getting it up and running was fairly easy, and it has a beautiful UI that has much of the dashboarding ability of Grafana.&lt;/p&gt;
&lt;p&gt;The only issue is that querying the V2.0 database is
&lt;em&gt;quite&lt;/em&gt; different than V1, and requires use of the proprietary &lt;a href=&#34;https://v2.docs.influxdata.com/v2.0/reference/flux/&#34;&gt;Flux language&lt;/a&gt;. Not that I have anything against this, but V2
and Flux are not widely used/documented, so setting things up would have been frustrating to say the least.&lt;/p&gt;
&lt;p&gt;For example, none of the premade dashboards on the community forum
(which I relied on to get a feel for how things worked) work with V2.0, and require rewriting the queries from scrath.&lt;/p&gt;
&lt;p&gt;For this reason I decided to spin up a V1 database instead, and it works great! The configuration for V2 is already in the file (commented out), so I can hook it up whenever it is
in a usable state. The only downside to V1 is that it doesn&amp;rsquo;t have a web UI to configure things (usually Chronograf is used). The good news is there is &lt;em&gt;minimal&lt;/em&gt; configuration
required, if any.&lt;/p&gt;
&lt;h1 id=&#34;docker&#34;&gt;Docker&lt;/h1&gt;
&lt;p&gt;If you&amp;rsquo;ve read my other posts, you know the drill by now. All these services are going into the Docker stack, so I can easily configure and deploy them anywhere. Here is a
&lt;code&gt;docker-compose.yaml&lt;/code&gt; for the TIG stack. A Traefik container is included here because I use it to reverse proxy my services.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-docker-compose&#34; data-lang=&#34;docker-compose&#34;&gt;
version: &#39;3&#39;
services:

#      ____                                   ____
#     / __ \___ _   _____  _____________     / __ \_________  _  ____  __
#    / /_/ / _ \ | / / _ \/ ___/ ___/ _ \   / /_/ / ___/ __ \| |/_/ / / /
#   / _, _/  __/ |/ /  __/ /  (__  )  __/  / ____/ /  / /_/ /&amp;gt;  &amp;lt;/ /_/ /
#  /_/ |_|\___/|___/\___/_/  /____/\___/  /_/   /_/   \____/_/|_|\__, /
#                                                               /____/

   traefik:
      image: &amp;quot;traefik:v2.0.2&amp;quot;
      container_name: &amp;quot;traefik&amp;quot;
      command:
         - &amp;quot;--log.level=DEBUG&amp;quot;
         - &amp;quot;--api.insecure=true&amp;quot;
         - &amp;quot;--providers.docker=true&amp;quot;
         - &amp;quot;--providers.docker.exposedbydefault=false&amp;quot;
         - &amp;quot;--entrypoints.web.address=:80&amp;quot;
         - &amp;quot;--entrypoints.websecure.address=:443&amp;quot;
         - &amp;quot;--certificatesresolvers.mytlschallenge.acme.tlschallenge=true&amp;quot;
         #- &amp;quot;--certificatesresolvers.mytlschallenge.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory&amp;quot;
         - &amp;quot;--certificatesresolvers.mytlschallenge.acme.email=you@yourdomain.com&amp;quot;
         - &amp;quot;--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json&amp;quot;
      ports:
         - &amp;quot;80:80&amp;quot;
         - &amp;quot;8081:8081&amp;quot;
         - &amp;quot;443:443&amp;quot;
      volumes:
         - &amp;quot;/var/run/docker.sock:/var/run/docker.sock:ro&amp;quot;
         - &amp;quot;$HOME/Data/Programs/Docker/TraefikV2/letsencrypt:/letsencrypt&amp;quot;
      networks:
         - traefik
      restart: unless-stopped
      labels:
         - &amp;quot;traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)&amp;quot;
         - &amp;quot;traefik.http.routers.http-catchall.entrypoints=web&amp;quot;
         - &amp;quot;traefik.http.routers.http-catchall.middlewares=redirect-to-https@docker&amp;quot;
         - &amp;quot;traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https&amp;quot;

#    ________________   _____ __             __
#   /_  __/  _/ ____/  / ___// /_____ ______/ /__
#    / /  / // / __    \__ \/ __/ __ `/ ___/ //_/
#   / / _/ // /_/ /   ___/ / /_/ /_/ / /__/ ,&amp;lt;
#  /_/ /___/\____/   /____/\__/\__,_/\___/_/|_|
#
   grafana:
      image: grafana/grafana
      container_name: grafana
      ports:
         - 3000:3000
      volumes:
         - /home/gideon/Data/Programs/Docker/TIG/Grafana/Data:/var/lib/grafana
      restart: always
      user: &amp;quot;0&amp;quot;
      networks:
         - traefik
      labels:
         - &amp;quot;traefik.enable=true&amp;quot;
         - &amp;quot;traefik.http.routers.grafana.rule=Host(`your.grafana.url`)&amp;quot;
         - &amp;quot;traefik.http.routers.grafana.entrypoints=websecure&amp;quot;
         - &amp;quot;traefik.http.routers.grafana.tls.certresolver=mytlschallenge&amp;quot;
         - &amp;quot;traefik.http.middlewares.grafana.redirectscheme.scheme=https&amp;quot;
      environment:
         - &amp;quot;GF_SERVER_ROOT_URL=your.grafana.url&amp;quot;

   influxdb_V1:
      image: influxdb
      container_name: influxdb_v1
      restart: always
      ports:
         - 8086:8086
      networks:
         - traefik
      volumes:
         - $HOME/Data/Programs/Docker/TIG/InfluxDBV1/:/var/lib/influxdb


   telegraf:
      image: telegraf
      hostname: nas
      volumes:
         - &amp;quot;/:/hostfs:ro&amp;quot;
         - &amp;quot;/etc:/hostfs/etc:ro&amp;quot;
         - &amp;quot;/proc:/hostfs/proc:ro&amp;quot;
         - &amp;quot;/sys:/hostfs/sys:ro&amp;quot;
         - &amp;quot;/var:/hostfs/var:ro&amp;quot;
         - &amp;quot;/run:/hostfs/run:ro&amp;quot;
         #- &amp;quot;/etc/telegraf/telegraf.conf:/etc/telegraf/telegraf.conf&amp;quot;
         - &amp;quot;$HOME/Data/Programs/Docker/TIG/telegraf.conf:/etc/telegraf/telegraf.conf&amp;quot;
         - &amp;quot;/var/run/docker.sock:/var/run/docker.sock:ro&amp;quot;
      environment:
         - &amp;quot;HOST_ETC=/hostfs/etc&amp;quot;
         - &amp;quot;HOST_PROC=/hostfs/proc&amp;quot;
         - &amp;quot;HOST_SYS=/hostfs/sys&amp;quot;
         - &amp;quot;HOST_VAR=/hostfs/var&amp;quot;
         - &amp;quot;HOST_RUN=/hostfs/run&amp;quot;
         - &amp;quot;HOST_MOUNT_PREFIX=/hostfs&amp;quot;
      ports:
         - 8888:8888
      networks: traefik

networks:
  traefik:
    external: true

&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;telegraf&#34;&gt;Telegraf&lt;/h1&gt;
&lt;p&gt;Telegraf took me a bit to get used to when I first learned it, but now it all makes sense. To get anything useful out of telegraf, you have to use &lt;em&gt;plugins&lt;/em&gt;. Using a plugin is as
simple as adding a line to your &lt;code&gt;telegraf.conf&lt;/code&gt; file, that is located by default at &lt;code&gt;etc/telegraf&lt;/code&gt;. This is where we mounted in the docker container, so you can keep it anywhere on
your local filesystem.&lt;/p&gt;
&lt;p&gt;The two types of plugin we need today are &lt;code&gt;input&lt;/code&gt; and &lt;code&gt;output&lt;/code&gt;. &lt;code&gt;output&lt;/code&gt; is pretty simple. We simply need to point our telegraf instance at out database and say &amp;ldquo;store data
there!&amp;rdquo;. That can be done with the following code:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-conf&#34; data-lang=&#34;conf&#34;&gt;# OUTPUTS
[[outputs.influxdb]]
  url = &amp;quot;http://IP.OF.INFLUXDB:8086&amp;quot; # required.
  database = &amp;quot;telegraf&amp;quot; # required.
  precision = &amp;quot;s&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: I had to explicitly type my local IP into the &lt;code&gt;url&lt;/code&gt; field. &lt;code&gt;localhost&lt;/code&gt; did not work for whatever reason&amp;hellip;&lt;/p&gt;
&lt;p&gt;And that&amp;rsquo;s it! You could have telegraf broadcast data to multiple locations if you wanted. Next is to configure the &lt;code&gt;input&lt;/code&gt; plugins. I will post my config here, but I recommend you
take a look at the &lt;a href=&#34;https://docs.influxdata.com/telegraf/v1.12/plugins/plugin-list/&#34;&gt;list of plugins&lt;/a&gt; for some that may suit a usecase you have and I don&amp;rsquo;t.&lt;/p&gt;
&lt;p&gt;The lines below will set up monitoring for the host&amp;rsquo;s docker environment, as well as system hardware/software statistics. Additionally there are some &amp;ldquo;fun&amp;rdquo; plugins to gather data
about github repositories, the weather, and more.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-config&#34; data-lang=&#34;config&#34;&gt;# INPUTS
[[inputs.docker]]
  endpoint = &amp;quot;unix:///var/run/docker.sock&amp;quot;
  container_names = []
  timeout = &amp;quot;5s&amp;quot;
  perdevice = true
  ## Whether to report for each container total blkio and network stats or not
  total = false
  ## docker labels to include and exclude as tags.  Globs accepted.
  ## Note that an empty array for both will include all labels as tags
  docker_label_include = []
  docker_label_exclude = []

[[inputs.docker_log]]
  ## Docker Endpoint
  ##   To use TCP, set endpoint = &amp;quot;tcp://[ip]:[port]&amp;quot;
  ##   To use environment variables (ie, docker-machine), set endpoint = &amp;quot;ENV&amp;quot;
  endpoint = &amp;quot;unix:///var/run/docker.sock&amp;quot;

[[inputs.cpu]]
  percpu = true
  totalcpu = true
  # filter all fields beginning with &#39;time_&#39;
  fielddrop = [&amp;quot;time_*&amp;quot;]

[[inputs.disk]]
  [inputs.disk.tagpass]
    # tagpass conditions are OR, not AND.
    # If the (filesystem is ext4 or xfs) OR (the path is /opt or /home)
    # then the metric passes
    fstype = [ &amp;quot;ext4&amp;quot;, &amp;quot;xfs&amp;quot; ]
    # Globs can also be used on the tag values
    path = [ &amp;quot;/opt&amp;quot;, &amp;quot;/home*&amp;quot; ]

[[inputs.diskio]]

[[inputs.kernel]]

[[inputs.net]]

[[inputs.netstat]]

[[inputs.nstat]]

# Collect response time of a TCP or UDP connection
[[inputs.net_response]]
  ## Protocol, must be &amp;quot;tcp&amp;quot; or &amp;quot;udp&amp;quot;
  ## NOTE: because the &amp;quot;udp&amp;quot; protocol does not respond to requests, it requires
  ## a send/expect string pair (see below).
  protocol = &amp;quot;tcp&amp;quot;
  ## Server address (default localhost)
  address = &amp;quot;localhost:80&amp;quot;

[[inputs.processes]]

[[inputs.sensors]]

[[inputs.swap]]

[[inputs.mem]]

[[inputs.internal]]

[[inputs.interrupts]]

[[inputs.temp]]

[[inputs.wireless]]

[[inputs.bond]]

# This plugin gets dns information/response time from configured domains.
# Super helpful for checking status of service or machine
[[inputs.dns_query]]
  ## servers to query
  servers = [&amp;quot;8.8.8.8&amp;quot;]
  domains = [&amp;quot;exampledomain.tld&amp;quot;]

[[inputs.system]]

[[inputs.github]]
  ## List of repositories to monitor
  repositories = [
	  &amp;quot;GideonWolfe/vim.reaper&amp;quot;,
	  &amp;quot;GideonWolfe/gideonwolfe.com&amp;quot;
  ]

  ## Github API access token.  Unauthenticated requests are limited to 60 per hour.
  access_token = &amp;quot;YOUR_TOKEN_HERE&amp;quot;

[[inputs.openweathermap]]
  ## OpenWeatherMap API key.
  app_id = &amp;quot;YOUR_KEY_HERE&amp;quot;

  ## City ID&#39;s to collect weather data from.
  city_id = [&amp;quot;098008&amp;quot;]

  ## APIs to fetch; can contain &amp;quot;weather&amp;quot; or &amp;quot;forecast&amp;quot;.
  fetch = [&amp;quot;weather&amp;quot;, &amp;quot;forecast&amp;quot;]

  ## Preferred unit system for temperature and wind speed. Can be one of
  ## &amp;quot;metric&amp;quot;, &amp;quot;imperial&amp;quot;, or &amp;quot;standard&amp;quot;.
  # units = &amp;quot;metric&amp;quot;

  ## Query interval; OpenWeatherMap weather data is updated every 10
  ## minutes.
  interval = &amp;quot;10m&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And that&amp;rsquo;s it! I&amp;rsquo;m always on the lookout for cool plugins and ways to integrate my data into telegraf.&lt;/p&gt;
&lt;h1 id=&#34;influxdb&#34;&gt;InfluxDB&lt;/h1&gt;
&lt;p&gt;This is the quickest set up by far. Simply get a shell inside the influx docker container with &lt;code&gt;docker exec -it &amp;lt;container-name&amp;gt; bash&lt;/code&gt;. Run &lt;code&gt;influx&lt;/code&gt; to start the interactive
database prompt.&lt;/p&gt;
&lt;p&gt;Create a user with the following command:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;CREATE USER &amp;lt;username&amp;gt; WITH PASSWORD &amp;lt;password&amp;gt; WITH ALL PRIVILEGES&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then add a database with this one:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;CREATE DATABASE telegraf&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you want to add a data retention policy, do it like so:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;CREATE RETENTION POLICY &amp;ldquo;keep_x_days&amp;rdquo; ON &amp;ldquo;telegraf&amp;rdquo; DURATION xd REPLICATION 1&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;where &lt;code&gt;x&lt;/code&gt; is the amount of days you want InfluxDB to keep your data.&lt;/p&gt;
&lt;h1 id=&#34;bring-it-all-up&#34;&gt;Bring it all up&lt;/h1&gt;
&lt;p&gt;The only thing to do now is bring the whole thing up with &lt;code&gt;docker-compose&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To start out, bring the stack up with &lt;code&gt;docker-compose up&lt;/code&gt; so you can read the logs and identify possible configuration errors. If everything is going as planned, you should be able
to access your Grafana instance at &lt;a href=&#34;http://localhost:3000&#34;&gt;http://localhost:3000&lt;/a&gt;. Additionally, telegraf should be feeding into the InfluxDB container without error.&lt;/p&gt;
&lt;h1 id=&#34;grafana&#34;&gt;Grafana&lt;/h1&gt;
&lt;p&gt;The first step for setting up Grafana is adding InfluxDB as a data source, so you can actually start getting some data. Go to &lt;code&gt;Configuration &amp;gt; Data Sources &amp;gt; Add data source&lt;/code&gt; and
fill in the details for your InfluxDB instance. Since Grafana is querying a database that isn&amp;rsquo;t exposed to the internet and instead running on the local system, we can skip the
security settings for now and simply enter in the IP of our database, the database name (which should be &lt;code&gt;telegraf&lt;/code&gt;), and the credentials for the user we just created.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/TIG/influxsetup.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;If this was set up correctly, the &lt;code&gt;Save &amp;amp; Test&lt;/code&gt; button will let you know. Next, we should download some panels. Browse the &lt;a href=&#34;https://grafana.com/grafana/plugins?orderBy=weight&amp;amp;direction=asc&amp;amp;type=panel&#34;&gt;Grafana panel plugin
list&lt;/a&gt; to find ones that you want. The last part of the url of the page of each panel is it&amp;rsquo;s &lt;code&gt;id&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;grafana-cli plugins install &amp;lt;plugin_id&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now these added panels will show up in the menus. You can add datasources the same way, but they don&amp;rsquo;t seem to show up unless you manually add and enable them through the GUI as
well.&lt;/p&gt;
&lt;p&gt;The next step is where the real fun begins; adding dashboards. I would also recommend checking out the
other available datasources, because there are some neat ones that don&amp;rsquo;t require any installation.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re a complete novice at this like I was, browse some community &lt;a href=&#34;https://grafana.com/grafana/dashboards&#34;&gt;dashboards&lt;/a&gt; to get inspired. I will briefly show you how to set up a
simple CPU monitor dashboard, but the more advanced stuff will be for a later tutorial.&lt;/p&gt;
&lt;p&gt;Click the &amp;ldquo;New Panel&amp;rdquo; icon at the top right of your dashboard. Then click &amp;ldquo;add query&amp;rdquo;. Here is the basic idea of how your queries should be structured. You can click on each field
to see the possible values, and explore the metrics collected by your various input plugins.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/TIG/examplequery.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Play around with the visualization settings, and the various configuration options each one has. Community dashboards are a great way to get inspired for what you should include on
yours.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;In this post I showed you how to get the TIG stack up and running with docker. This software stack allows you to collect metrics from one or more machines, store this metrics in a
purpose built database, and display these metrics in a beautiful fashion with customizable dashboards and panels.&lt;/p&gt;
&lt;p&gt;In my next post I will give some examples of advanced database queries, live diagrams, and customized dashboards.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Unifying the News: Nextcloud, Newsboat, and Linux.</title>
      <link>https://gideonwolfe.com/posts/workflow/newsboat/</link>
      <pubDate>Tue, 03 Dec 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/workflow/newsboat/</guid>
      <description>&lt;p&gt;In a previous post, I explained how to set up a Nextcloud server and integrate some crucial applications into your workflow. I briefly touched on the news application, which is a
nice way of seeing some RSS feeds in your nextcloud. But much like email, I prefer using the terminal as my primary viewing method. I have found a great way to achieve this: an
application called &lt;a href=&#34;https://www.archlinux.org/packages/community/x86_64/newsboat/&#34;&gt;newsboat&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;newsboat allows you to create a list of feed URLs, but I will be configuring it to pull from the feeds defined in my Nextcloud News app.&lt;/p&gt;
&lt;p&gt;Install newsboat on Arch linux by running&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;sudo pacman -Syu newsboat&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;By default, newsboat is configured with files in the &lt;code&gt;~/.newsboat&lt;/code&gt; directory. However, I prefer the files to be in &lt;code&gt;~/.config/newsboat/&lt;/code&gt;, which will work just fine. Create the file
&lt;code&gt;config&lt;/code&gt; in the directory you choose. Here is my configuration file:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-config&#34; data-lang=&#34;config&#34;&gt;
prepopulate-query-feeds yes

urls-source &amp;quot;ocnews&amp;quot;
ocnews-url &amp;quot;https://nextcloud.yourdomain.com&amp;quot; # Domain of your Nextcloud
ocnews-login &amp;quot;username&amp;quot; # Desired nextcloud user to log in as
ocnews-password &amp;quot;password&amp;quot; # Nextcloud password (app password if using 2Fa)

# -- display -------------------------------------------------------------------

show-read-feeds no
feed-sort-order unreadarticlecount-asc

color info default default reverse
color listnormal_unread cyan default
color listfocus blue default reverse bold
color listfocus_unread blue default reverse bold
color article cyan default
color listnormal yellow default

text-width 80

articlelist-format &amp;quot;%4i %f %D  %?T?|%-17T| ?%t&amp;quot;

highlight feedlist    &amp;quot;^  *[0-9]+  *N  &amp;quot;                    magenta  magenta
highlight articlelist &amp;quot;^  *[0-9]+  *N  &amp;quot;                    magenta  magenta

highlight article     &amp;quot;(^Feed:.*|^Title:.*|^Author:.*)&amp;quot;     red      default
highlight article     &amp;quot;(^Link:.*|^Date:.*)&amp;quot;                 white    default
highlight article     &amp;quot;^Podcast Download URL:.*&amp;quot;            cyan     default
highlight article     &amp;quot;^Links:&amp;quot;                             magenta  black    underline
highlight article     &amp;quot;https?://[^ ]+&amp;quot;                      green    default
highlight article     &amp;quot;^(Title):.*$&amp;quot;                        blue     default
highlight article     &amp;quot;\\[[0-9][0-9]*\\]&amp;quot;                   magenta  default  bold
highlight article     &amp;quot;\\[image\\ [0-9]+\\]&amp;quot;                green    default  bold
highlight article     &amp;quot;\\[embedded flash: [0-9][0-9]*\\]&amp;quot;   green    default  bold
highlight article     &amp;quot;:.*\\(link\\)$&amp;quot;                      cyan     default
highlight article     &amp;quot;:.*\\(image\\)$&amp;quot;                     blue     default
highlight article     &amp;quot;:.*\\(embedded flash\\)$&amp;quot;            magenta  default


# -- navigation ----------------------------------------------------------------

goto-next-feed no

browser &amp;quot;xdg-open&amp;quot; # This will open the browser defined by xdg-settings

# Below bindings apply vim like keybindings in most places

bind-key h quit articlelist
bind-key h quit article
bind-key h quit tagselection
bind-key h quit feedlist
bind-key j down feedlist
bind-key j down tagselection
bind-key j next articlelist
bind-key j down article
bind-key J next-feed articlelist
bind-key k up feedlist
bind-key k prev articlelist
bind-key k up tagselection
bind-key K prev-feed articlelist
bind-key k up article
bind-key l open articlelist
bind-key l open feedlist
bind-key l open tagselection

bind-key G end
bind-key g home

bind-key d pagedown
bind-key u pageup
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you filled out this information correctly, you should be able to start newsboat and see your saved RSS feeds populate! note: you may need to manually create a file called &lt;code&gt;urls&lt;/code&gt;
in order for newsboat to start, even if it&amp;rsquo;s empty.&lt;/p&gt;
&lt;p&gt;Press &lt;code&gt;t&lt;/code&gt; to see tags. These are the equivalent of categories in the news app on Nextcloud, and are nice if you prefer browsing by category.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/workflow/newsboat/articlelist.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Some articles will let you read the entire thing in newsboat, but usually only the description is visible. Pressing &lt;code&gt;O&lt;/code&gt; will open the story in your preferred browser if you want to
read a full article.&lt;/p&gt;
&lt;p&gt;Let me know if you have any configuration tips, I just recently found about this killer app combo!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Chemistry Practice: Buffer Systems</title>
      <link>https://gideonwolfe.com/posts/chemistry/bufferpractice1/</link>
      <pubDate>Wed, 27 Nov 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/chemistry/bufferpractice1/</guid>
      <description>&lt;p&gt;$\require{\mhchem}$&lt;/p&gt;

&lt;p&gt;Buffer systems are important part of of organic and inorganic chemistry. In short, a buffer is a solution that is resistant to pH changes, such as the addition of an acid or a
base.&lt;/p&gt;

&lt;p&gt;Let&#39;s go over an example problem you might encounter on a homework assignment or exam.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the pH of an 80 mL .30M NH₃/0.36M NH₄⁺ buffer system after 20.0 mL of 0.050M NaOH has been added? The Kₐ value for &lt;span  class=&#34;math&#34;&gt;\(\ce{NH4+}\)&lt;/span&gt; is &lt;span  class=&#34;math&#34;&gt;\(5.8\text{x}10^{-10}\)&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lets break this problem down. We have 80 mL of a solution made up of &lt;span  class=&#34;math&#34;&gt;\(\ce{NH3}\)&lt;/span&gt; (ammonia) and &lt;span  class=&#34;math&#34;&gt;\(\ce{NH4+}\)&lt;/span&gt; (ammonium).&lt;/p&gt;

&lt;p&gt;We know the concentrations of each of these species, denoted by brackets.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\([\ce{NH3}] = \frac{\text{0.30 moles } \ce{NH3}}{\text{1 Liter}}\)&lt;/span&gt; &lt;span  class=&#34;math&#34;&gt;\([\ce{NH4+}] = \frac{\text{0.36 moles } \ce{NH4+}}{\text{1 Liter}}\)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Then we add 20.0 mL of &lt;span  class=&#34;math&#34;&gt;\(\ce{NaOH}\)&lt;/span&gt;, which has the following concentration.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[[\ce{Na+}] = \frac{\text{0.050 moles } \ce{Na+}}{\text{1 Liter}}\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;To proceed with this problem, we need to figure out what will happen to the &lt;span  class=&#34;math&#34;&gt;\(\ce{NaOH}\)&lt;/span&gt; (sodium hydroxide) when it is added to the solution.&lt;/p&gt;

&lt;p&gt;Sodium hydroxide is a strong base, and will completely disassociate into the Sodium and Hydroxide ions like so.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \ce{NaOH -&gt;[H₂O] Na+ + OH- } \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Theoretically &lt;span  class=&#34;math&#34;&gt;\(\ce{Na+}\)&lt;/span&gt; would react with &lt;span  class=&#34;math&#34;&gt;\(\ce{H2O}\)&lt;/span&gt; to form more &lt;span  class=&#34;math&#34;&gt;\(\ce{NaOH}\)&lt;/span&gt;, but this will &lt;strong&gt;not&lt;/strong&gt; happen, because &lt;span  class=&#34;math&#34;&gt;\(\ce{NaOH}\)&lt;/span&gt; is a strong base and will not be formed.
For this reason, we can ignore it in our further calculations. This leaves us only the &lt;span  class=&#34;math&#34;&gt;\(\ce{OH-}\)&lt;/span&gt; to worry about.&lt;/p&gt;

&lt;p&gt;Since &lt;span  class=&#34;math&#34;&gt;\(\ce{OH-}\)&lt;/span&gt; is a base, it will react with the &lt;em&gt;acid&lt;/em&gt; in our buffer solution. Buffer solutions are always made up of conjugate acid/base pairs. In this case, &lt;span  class=&#34;math&#34;&gt;\(\ce{NH4+}\)&lt;/span&gt;
is the acid, because it is the conjugate acid of &lt;span  class=&#34;math&#34;&gt;\(\ce{NH3}\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[\ce{NH4+(aq) + OH- (aq) &lt;-&gt; NH3(aq) + H2O(l)}\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;In this reaction, hydroxide acts as a base and accepts the proton from ammonium.&lt;/p&gt;

&lt;p&gt;To further solve this problem, we are going to need to use a RICE table.&lt;/p&gt;

&lt;div&gt;
$$
\begin{array}{c|c@{}c@{}c@{}c@{}c}
  \hline
  R   &amp; \ce{NH4+(aq) &amp; $${}+{}$$ &amp; OH- (aq) &amp; &lt;-&gt; &amp; NH3(aq) &amp; $${}+{}$$ &amp; H2O(l)} \\
  \hline
  I   &amp;       ?.??    &amp;&amp;   ?.??                         &amp;&amp;  ?.??  &amp;&amp; \text{---} \\
  C   &amp;       ?.??    &amp;&amp;   ?.??                         &amp;&amp;  ?.??  &amp;&amp; \text{---} \\
  E   &amp;       ?.??    &amp;&amp;   ?.??                         &amp;&amp;  ?.??  &amp;&amp; \text{---}  \\
  \hline
\end{array}
$$
&lt;/div&gt;

&lt;p&gt;Let&#39;s start by figuring out &lt;span  class=&#34;math&#34;&gt;\(I\)&lt;/span&gt;, the initial amount of moles for each species. Since water is in such high abundance, we can leave it out of the equation.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \text{moles } \ce{NH4+} = \frac{0.36 \text{ moles } \ce{NH4+}}{1 \text{ L}} * 0.0800 \text{ L} = 0.0288 \text{ moles}\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \text{moles } \ce{OH-} = \frac{0.050 \text{ moles } \ce{OH-}}{1 \text{ L}} * 0.0200 \text{ L} = 0.0010 \text{ moles}\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \text{moles } \ce{NH3} = \frac{0.30 \text{ moles } \ce{NH3}}{1 \text{ L}} * 0.0800 \text{ L} = 0.0240 \text{ moles}\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Here is our updated rice table with the initial amounts of each species.&lt;/p&gt;

&lt;div&gt;
$$
\begin{array}{c|c@{}c@{}c@{}c@{}c}
  \hline
  R   &amp; \ce{NH4+(aq) &amp; $${}+{}$$ &amp; OH- (aq) &amp; &lt;-&gt; &amp; NH3(aq) &amp; $${}+{}$$ &amp; H2O(l)} \\
  \hline
  I   &amp;       0.0288  &amp;&amp;   0.0010                       &amp;&amp;  0.0240  &amp;&amp; \text{---} \\
  C   &amp;       ?.??    &amp;&amp;   ?.??                         &amp;&amp;  ?.??  &amp;&amp; \text{---} \\
  E   &amp;       ?.??    &amp;&amp;   ?.??                         &amp;&amp;  ?.??  &amp;&amp; \text{---}  \\
  \hline
\end{array}
$$
&lt;/div&gt;

&lt;p&gt;We can see that all species in this reaction are one to one ratios. This means that &lt;span  class=&#34;math&#34;&gt;\(\ce{OH-}\)&lt;/span&gt; is the limiting reactant, as it has the least amount of moles present.&lt;/p&gt;

&lt;p&gt;Additionally, this means the initial number of moles of &lt;span  class=&#34;math&#34;&gt;\(\ce{OH-}\)&lt;/span&gt; is the maximum number of moles that can be reacted of either of the other chemical species.&lt;/p&gt;

&lt;p&gt;Now we can fill in &lt;span  class=&#34;math&#34;&gt;\(C \)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(E \)&lt;/span&gt;, or the &lt;em&gt;change&lt;/em&gt; in moles during the reaction and the final amount at &lt;em&gt;equilibrium&lt;/em&gt;.&lt;/p&gt;

&lt;div&gt;
$$
\begin{array}{c|c@{}c@{}c@{}c@{}c}
  \hline
  R   &amp; \ce{NH4+(aq) &amp; $${}+{}$$ &amp; OH- (aq) &amp; &lt;-&gt; &amp; NH3(aq) &amp; $${}+{}$$ &amp; H2O(l)} \\
  \hline
  I   &amp;       0.0288  &amp;&amp;   0.0010                       &amp;&amp;  0.0240  &amp;&amp; \text{---} \\
  C   &amp;       -0.0010    &amp;&amp;   -0.0010               &amp;&amp;  -0.0010  &amp;&amp; \text{---} \\
  E   &amp;       0.0278    &amp;&amp;   0                         &amp;&amp;  0.0250  &amp;&amp; \text{---}  \\
  \hline
\end{array}
$$
&lt;/div&gt;

&lt;p&gt;We can see that all of the hydroxide was depleted in this reaction. Now that we have the number of moles of each species at equilibrium, we can preform the following calculations
to find the concentration at equilibrium.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\([\ce{NH3}]_{eq} = \frac{\text{0.0250 moles } \ce{NH3}}{\text{0.1000 Liter}}\)&lt;/span&gt; = 0.250 M&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\([\ce{NH4+}]_{eq} = \frac{\text{0.0278 moles } \ce{NH4+}}{\text{0.1000 Liter}}\)&lt;/span&gt; = 0.278 M&lt;/p&gt;

&lt;p&gt;We use the volume of .1 L because we had an initial volume of 80 mL and then we added an additional 20 mL of &lt;span  class=&#34;math&#34;&gt;\(\ce{NaOH}\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;We can use these equilibrium molarities as inputs to the &lt;a href=&#34;https://en.wikipedia.org/wiki/Henderson%E2%80%93Hasselbalch_equation&#34;&gt;Henderson–Hasselbalch equation&lt;/a&gt;, which takes the
following form:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ pH = pK_a + \text{log}\left( \frac{[A^-]}{[HA]} \right) \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;In this example, &lt;span  class=&#34;math&#34;&gt;\(\ce{HA}\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(\ce{A-}\)&lt;/span&gt; represent the acid and it&#39;s conjugate base respectively.&lt;/p&gt;

&lt;p&gt;Let&#39;s start substituting in values. We know that the Kₐ of &lt;span  class=&#34;math&#34;&gt;\(\ce{NH4+}\)&lt;/span&gt; is &lt;span  class=&#34;math&#34;&gt;\(5.8\text{x}10^{-10}\)&lt;/span&gt;, and from that we can derive the pKₐ value, which is equal to &lt;span  class=&#34;math&#34;&gt;\(-\text{log}\left( K_a
\right)\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;We also have the equilibrium concentrations for the conjugate acid/base pair. After filling in our values, the HH equation should look like:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ pH = 9.24 + \text{log}\left( \frac{0.250}{0.278} \right) \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Plug this into your calculator, and you should get a resulting pH of &lt;span  class=&#34;math&#34;&gt;\(9.19\)&lt;/span&gt;.&lt;/p&gt;

&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;Please let me know if you have any questions or corrections for me! Writing these exercises helps me practice for my exams 😄&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Controlling Your Cloud: Integrating Nextcloud Into Your Workflow</title>
      <link>https://gideonwolfe.com/posts/sysadmin/nextcloud/nextcloudworkflow/</link>
      <pubDate>Sun, 24 Nov 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/sysadmin/nextcloud/nextcloudworkflow/</guid>
      <description>&lt;h1 id=&#34;intro&#34;&gt;Intro&lt;/h1&gt;
&lt;p&gt;In my last tutorial, I demonstrated how to set up a barebones Nextcloud instance using Docker. The following guide assumes you have completed this step, and will focus on tying it
all together into a seamless system.&lt;/p&gt;
&lt;h1 id=&#34;files&#34;&gt;Files&lt;/h1&gt;
&lt;p&gt;The most essential part of your workflow is going to be your file management. Figure out which devices you want to include in this system and install the appropriate Nextcloud
client on all of them.&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;ul&gt;
&lt;li&gt;Contacts&lt;/li&gt;
&lt;li&gt;Calendars&lt;/li&gt;
&lt;li&gt;Location&lt;/li&gt;
&lt;li&gt;Tasks&lt;/li&gt;
&lt;li&gt;Photos&lt;/li&gt;
&lt;li&gt;Texts&lt;/li&gt;
&lt;li&gt;Notes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For my &lt;strong&gt;photos&lt;/strong&gt;, I simply add the camera libraries I care about to the &amp;ldquo;Auto Upload&amp;rdquo; section in the Android Nextcloud client. These are auto-organized into folders by month, and put
into a central &amp;ldquo;Photos&amp;rdquo; location on my server. Any screenshot, meme, or photo will be auto uploaded to the appropriate folder.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Contacts&lt;/strong&gt; and &lt;strong&gt;calendars&lt;/strong&gt; are all handled with &lt;a href=&#34;https://play.google.com/store/apps/details?id=at.bitfire.davdroid&amp;amp;hl=en_US&#34;&gt;DAVx⁵&lt;/a&gt; android app. Link this with the Nextcloud client and
choose which address books and calendars you want to synchronize with your server. These should show up in the native Contacts and Calendar apps.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Texts&lt;/strong&gt; can be synchronized with the &lt;a href=&#34;https://f-droid.org/en/packages/fr.unix_experience.owncloud_sms/&#34;&gt;Nextcloud SMS&lt;/a&gt; app. This does have some limitations, as you cannot write/send
SMS messages in the mobile or desktop app. It is useful for backing up and viewing conversations though.&lt;/p&gt;
&lt;p&gt;Optionally, a &lt;strong&gt;location&lt;/strong&gt; client like &lt;a href=&#34;https://play.google.com/store/apps/details?id=org.traccar.client&amp;amp;hl=en_US&#34;&gt;Traccar&lt;/a&gt; can be set up using a link from the Phonetrack app on
Nextcloud. This is kind of like a personal &amp;ldquo;Find my iPhone&amp;rdquo;, with the added benefit of logging and backing up &lt;code&gt;gpx&lt;/code&gt; files which can be analyzed for whatever data you please. There
are numerous &lt;code&gt;gpx&lt;/code&gt; editor apps on the store, but PhoneTrack has a great built in filtering system.&lt;/p&gt;
&lt;p&gt;I use the &lt;a href=&#34;https://play.google.com/store/apps/details?id=org.dmfs.tasks&amp;amp;hl=en_US&#34;&gt;OpenTasks&lt;/a&gt; appkhard to synchronize &lt;strong&gt;tasks&lt;/strong&gt; from my Nextcloud server. The Tasks app on Nextcloud
is my primary way of keeping track of assignments and todos, and having it on mobile is great. My only wish was to be able to see due dates for tasks in the calendar application.&lt;/p&gt;
&lt;p&gt;Although I usually prefer neovim as my text editor of choice, I am currently trying the &lt;a href=&#34;https://play.google.com/store/apps/details?id=com.spisoft.quicknote&amp;amp;hl=en_US&#34;&gt;Carnet&lt;/a&gt; app
(also available on Nextcloud store) because it has some nifty notetaking features that I have yet to replicate in neovim.&lt;/p&gt;
&lt;p&gt;Finally, I like to have some extra security for my server. I downloaded and enabled the Two-factor authentication application, and linked it up with &lt;a href=&#34;https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&amp;amp;hl=en_us&#34;&gt;Google
Authenticator&lt;/a&gt; to easily verify my 2FA logins. Most of the applications going forward
will be using &amp;ldquo;App Passwords&amp;rdquo; that can be generated in the &lt;code&gt;Security&lt;/code&gt; section of the Settings. This way you can let certain applications bypass 2FA.&lt;/p&gt;
&lt;p&gt;Both my laptop and desktop are running Arch Linux, so the setup for both of them is essentially the same. Not only this, but the directory structure of each machine is essentially
1:1, so the experience is like browsing one large synchronized filesystem.&lt;/p&gt;
&lt;p&gt;Like with the mobile client, set up the source -&amp;gt; destination connections for the desired folders on your machines. I recommend taking some time to think through a directory
structure you will be happy with in the long term.&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;ul&gt;
&lt;li&gt;Files&lt;/li&gt;
&lt;li&gt;Contacts&lt;/li&gt;
&lt;li&gt;Calendars&lt;/li&gt;
&lt;li&gt;Email&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To manage &lt;strong&gt;Contacts&lt;/strong&gt; and &lt;strong&gt;Calendars&lt;/strong&gt;, I use a program called &lt;a href=&#34;https://aur.archlinux.org/packages/vdirsyncer-git/&#34;&gt;vdirsyncer&lt;/a&gt; to synchronize the necessary contact/calendar
files with the server. The configuration for this tool is quite simple. I will post an example below.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-config&#34; data-lang=&#34;config&#34;&gt;
[general]
status_path = &amp;quot;~/.config/vdirsyncer/status/&amp;quot;

[pair my_contacts]
a = &amp;quot;my_contacts_local&amp;quot;
b = &amp;quot;my_contacts_remote&amp;quot;
collections = [&amp;quot;from a&amp;quot;, &amp;quot;from b&amp;quot;]
conflict_resolution = &amp;quot;b wins&amp;quot;

[storage my_contacts_local]
type = &amp;quot;filesystem&amp;quot;
path = &amp;quot;~/Documents/Contacts/&amp;quot;
fileext = &amp;quot;.vcf&amp;quot;

[storage my_contacts_remote]
type = &amp;quot;carddav&amp;quot;

# We can simplify this URL here as well. In theory it shouldn&#39;t matter.
url = &amp;quot;URL_TO_NEXTCLOUD&amp;quot;
username = &amp;quot;USERNAME&amp;quot;
password = &amp;quot;GENERATED_APP_PASSWORD&amp;quot;

[pair my_calendar]
a = &amp;quot;my_calendar_local&amp;quot;
b = &amp;quot;my_calendar_remote&amp;quot;
collections = [&amp;quot;from a&amp;quot;, &amp;quot;from b&amp;quot;]
conflict_resolution = &amp;quot;b wins&amp;quot;

[storage my_calendar_local]
type = &amp;quot;filesystem&amp;quot;
path = &amp;quot;~/Documents/Calendar/&amp;quot;
fileext = &amp;quot;.ics&amp;quot;

[storage my_calendar_remote]
type = &amp;quot;caldav&amp;quot;

# We can simplify this URL here as well. In theory it shouldn&#39;t matter.
url = &amp;quot;URL_TO_NEXTCLOUD&amp;quot;
username = &amp;quot;USERNAME&amp;quot;
password = &amp;quot;GENERATED_APP_PASSWORD&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Run the commands &lt;code&gt;vdirsyncer discover my_contacts&lt;/code&gt; and &lt;code&gt;vdirsyncer discover my_calendar&lt;/code&gt; to populate the directories. If everything is set up correctly, &lt;code&gt;vdirsyncer sync&lt;/code&gt; should
synchronize any changes made to the local or remote versions of the files.&lt;/p&gt;
&lt;p&gt;Conflict resolution for these files is dependant on the setting defined by &lt;code&gt;conflict_resolution&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But how do we interact with these files?&lt;/p&gt;
&lt;p&gt;Currently, I use the application &lt;a href=&#34;https://github.com/pimutils/khal&#34;&gt;khal&lt;/a&gt;. Run &lt;code&gt;khal --config&lt;/code&gt; to go through the interactive prompt and point it at your calendar files. This
will generate a configuration file &lt;code&gt;.config/khal/config&lt;/code&gt;. To view and edit your calendar, you can use the built in commands or &lt;code&gt;khal interactive&lt;/code&gt; for a more traditional TUI
experience.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/Nextcloud/khal.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;In each calendar folder, you can create a file called &lt;code&gt;color&lt;/code&gt;, and fill it with a single color that you would like to highlight that calendar with. For example, one &lt;code&gt;color&lt;/code&gt; file
could have the line &lt;code&gt;light cyan&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Much like the calendar, contacts are handled &lt;a href=&#34;https://github.com/scheibler/khard&#34;&gt;khard&lt;/a&gt;. run through the interactive configuration with &lt;code&gt;khard --config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now I really don&amp;rsquo;t care about creating contacts on my desktop, because creating them with my phone works well and will propagate to all my devices. You certainly &lt;em&gt;could&lt;/em&gt; create
contacts with khard. As usual, run &lt;code&gt;vdirsyncer sync&lt;/code&gt; to synchronize your files.&lt;/p&gt;
&lt;p&gt;My favorite use for khard is to provide a contact database for my &lt;strong&gt;email client&lt;/strong&gt; &lt;code&gt;neomutt&lt;/code&gt;. The mail application in Nextcloud is pointed at my email server, so this should point
there too (or whatever email server you are using). Configuring neomutt is kind of complex, and will be the topic of another tutorial.&lt;/p&gt;
&lt;p&gt;However if you already have a working neomutt, you can add the line&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set query_command = &amp;quot;khard email --parsable --search-in-source-files &#39;%s&#39;&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;to your &lt;code&gt;~/.config/neomutt/settings&lt;/code&gt; file. This will make neomutt parse your contacts list when composing an email!&lt;/p&gt;
&lt;h1 id=&#34;other-cool-features&#34;&gt;Other cool features&lt;/h1&gt;
&lt;p&gt;While these may not be absolutely essential, they really help bring Nextcloud to the next level; a life dashboard as opposed to simply a file sync service.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;News: The Nextcloud news app and companion &lt;a href=&#34;https://play.google.com/store/apps/details?id=de.luhmer.owncloudnewsreader&amp;amp;hl=en_US&#34;&gt;android app&lt;/a&gt; allow you to subscribe to a number
of RSS/news feeds, viewing them all in one comfy application. Has some limitations, but works great for the most part.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cookbook: The Cookbook app is one of my favorites, you can create your own recipes or import one from a website (assuming they are using a specific JSON format required by the
app). I definitely killed a few hours by building up a hefty recipe bank. App is still in alpha, but suits my needs so far! I really want a treelike directory structure to sort
recipes though.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Maps: I used a free API key for &lt;a href=&#34;https://www.mapbox.com/&#34;&gt;MapBox&lt;/a&gt; (configured in settings) and now I have a nifty map inside Nextcloud! It would be even more powerful with a
dedicated routing server to provide Google Maps like directions. This map will display detected data found on the server, such as GPX tracks, photo location metadata, and contact
addresses.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Keepweb: This application allows you to open and edit Keepass files on your server. Putting these files on your server can be a potential secrity risk, but there are plenty of
encryption options to suit your needs. This synced &lt;code&gt;kdbx&lt;/code&gt; file can be edited on the desktop (I prefer &lt;a href=&#34;https://www.archlinux.org/packages/community/x86_64/keepassxc/&#34;&gt;keepassxc&lt;/a&gt;),
and viewed on the server if you need a password in a pinch.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Talk: Host a chatroom right out of your Nextcloud instance! I haven&amp;rsquo;t used this much, but in theory you can make voice and video calls, send text, and even polls and other chat
features.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;If you set it up right, Nextcloud can be far more versatile than a simple file synchronization service. Through Nextcloud, you can back up and manage contacts, calendars, emails,
and much more. In combination with the ease of deployment docker provides, this setup is a formidable match for the out of the box services provided by larger companies. Let me
know how &lt;em&gt;you&lt;/em&gt; use Nextclud, I&amp;rsquo;m always on the lookout for great ways to integrate it into my workflow.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Controlling Your Cloud: Deploying a Nextcloud Server With Docker</title>
      <link>https://gideonwolfe.com/posts/sysadmin/nextcloud/nextclouddocker/</link>
      <pubDate>Fri, 22 Nov 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/sysadmin/nextcloud/nextclouddocker/</guid>
      <description>&lt;p&gt;I have always loved the convenience and versatility of cloud based services, but never really liked the idea of not &amp;ldquo;owning&amp;rdquo; the files on them. I also found myself becoming
increasingly uneasy with Google over the years, and wanted to migrate away from their platform as soon as possible. In general, I don&amp;rsquo;t really like the idea of getting locked into
a single ecosystem, whether it be Apple/iCloud, Microsoft/O365, or Google/GSuite.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s why I was so excited when I heard about &lt;a href=&#34;https://nextcloud.com/&#34;&gt;Nextcloud&lt;/a&gt;, a self hosted cloud platform that is practically a drop in replacement for the services
mentioned above. In fact in a lot of ways, Nextcloud offers more functionality. Nextcloud is FOSS, anyone can write a useful application and share it with the world. I am able to
do things with Nextcloud that I was never able to achieve through an off the shelf cloud suite.&lt;/p&gt;
&lt;p&gt;There are many ways to use Nextcloud. You could set it up as an organization, and have a self hosted array of cloud servers for your company. Personally, I treat Nextcloud as a &amp;ldquo;life dashboard&amp;rdquo; of sorts. If done right, you can make Nextcloud a one stop shop for productivity, organization, and personal management. Here are some of the things one can use Nextcloud for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Calendar&lt;/li&gt;
&lt;li&gt;Contacts&lt;/li&gt;
&lt;li&gt;Email&lt;/li&gt;
&lt;li&gt;Task Manager&lt;/li&gt;
&lt;li&gt;File Storage&lt;/li&gt;
&lt;li&gt;Real Time Phone Tracking&lt;/li&gt;
&lt;li&gt;SMS Backups&lt;/li&gt;
&lt;li&gt;Recipe Book&lt;/li&gt;
&lt;li&gt;Notes&lt;/li&gt;
&lt;li&gt;Bookmarks&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And much more!&lt;/p&gt;
&lt;p&gt;I have been using Nextcloud for a couple years now, and since then, I have become more familiar with Docker. The first time I set up Nextcloud, I used a pretty sketchy install
script. This worked, but I was never really sure &lt;em&gt;exatcly&lt;/em&gt; how things were set up. If you know me, that&amp;rsquo;s not how I roll. I realized the time had come to redo things with Docker.&lt;/p&gt;
&lt;h1 id=&#34;getting-a-server&#34;&gt;Getting a Server&lt;/h1&gt;
&lt;p&gt;While you could totally host this out of a spare PC in your house, I chose to go with a VPS for a couple reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reliable uptime&lt;/li&gt;
&lt;li&gt;Better up/down speeds&lt;/li&gt;
&lt;li&gt;Automated backups&lt;/li&gt;
&lt;li&gt;Easily transfer to another VPS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I chose to go with an Ubuntu 18.04 VPS from &lt;a href=&#34;http://digitalocean.com&#34;&gt;DigitalOcean&lt;/a&gt;, because they have been fantastic in the past. Theoretically this should work anywhere.&lt;/p&gt;
&lt;p&gt;One might also ask why I chose to use docker in this situation. I had multiple servers at DO all running separate services. With docker, I would be able to downsize to a single
server, and run multiple containerized services side by side, much like with my &lt;a href=&#34;https://gideonwolfe.com/posts/sysadmin/mediaserver/&#34;&gt;Home Media Server&lt;/a&gt; build. This would allow me
to easily deploy this configuration on any machine, and save me the hassle of setting up and reverse-proxying multiple services running on bare metal.&lt;/p&gt;
&lt;h1 id=&#34;setting-up-docker&#34;&gt;Setting up Docker&lt;/h1&gt;
&lt;p&gt;Run the following command to get the docker tools installed on your system. I would recommend making a new user so you don&amp;rsquo;t do the entire tutorial as &lt;code&gt;root&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo apt install docker.io docker-compose&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And give your user permission to execute docker commands without a password (requires you to sign in again)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo usermod -aG docker ${USER}&lt;/code&gt;&lt;/p&gt;
&lt;h1 id=&#34;deploying-the-services&#34;&gt;Deploying the Services&lt;/h1&gt;
&lt;p&gt;First, Let&amp;rsquo;s get our compose file out of the way. Make a new directory that you want to use for your docker services and create a file called &lt;code&gt;docker-compose.yaml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here is my &lt;code&gt;docker-compose.yaml&lt;/code&gt;, where I have declared the &lt;code&gt;traefik&lt;/code&gt;, &lt;code&gt;ncdatabase&lt;/code&gt;, and &lt;code&gt;nextcloud&lt;/code&gt; services. &lt;code&gt;ncdatabase&lt;/code&gt; is a MariaDB that will act as the database used by
Nextcloud. Then, the &lt;code&gt;nextcloud&lt;/code&gt; will host our main Nextcloud instance. Finally, I am using the &lt;code&gt;traefik&lt;/code&gt; provide SSL certificates and reverse proxy incoming connections to the
correct service.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-docker&#34; data-lang=&#34;docker&#34;&gt;version: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;services:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;  traefik:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    image: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik:v2.0.5&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    container_name: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    command:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--log.level=DEBUG&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--api.insecure=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--providers.docker=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--providers.docker.exposedbydefault=false&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--entrypoints.web.address=:80&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--entrypoints.websecure.address=:443&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--certificatesresolvers.myhttpchallenge.acme.httpchallenge=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--certificatesresolvers.myhttpchallenge.acme.httpchallenge.entrypoint=web&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--certificatesresolvers.myhttpchallenge.acme.email=yourname@yourdomain&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--certificatesresolvers.myhttpchallenge.acme.storage=/letsencrypt/acme.json&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    ports:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;80:80&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;443:443&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    volumes:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/var/run/docker.sock:/var/run/docker.sock:ro&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$HOME&lt;span style=&#34;color:#e6db74&#34;&gt;/data/letsencrypt:/letsencrypt&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    networks:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - traefik&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;  ncdatabase:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    image: mariadb&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    command: --transaction-isolation&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;READ-COMMITTED --binlog-format&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;ROW&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    restart: always&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    volumes:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - /home/gideon/data/nextcloud/db:/var/lib/mysql&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    environment:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - MYSQL_ROOT_PASSWORD&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;DECLARE_THIS_VALUE&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - MYSQL_PASSWORD&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;DECLARE_THIS_VALUE&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - MYSQL_DATABASE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;nextcloud&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - MYSQL_USER&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;nextcloud&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    labels:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.enable=false&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    networks:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - traefik&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;  nextcloud:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    image: nextcloud&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    ports:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - 8080:80&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    volumes:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - NEXTCLOUD_DIRECTORY:/var/www/html&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    restart: always&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    labels:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.enable=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.http.routers.nextcloud.rule=Host(`nextcloud.mydomain.com`)&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# This is the domain you want nextcloud to be reached on&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.http.routers.nextcloud.entrypoints=websecure&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.http.routers.nextcloud.tls.certresolver=myhttpchallenge&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.redirect.permanent=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.redirect.regex=https://(.*)/.well-known/(card|cal)dav&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;# These last few labels were added to silence some warnings&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.redirect.replacement=https://&lt;/span&gt;$$&lt;span style=&#34;color:#e6db74&#34;&gt;1/remote.php/dav/&amp;#34;&lt;/span&gt;      &lt;span style=&#34;color:#75715e&#34;&gt;# They may or may not be necessary&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.headers.customResponseHeaders=Strict-Transport-Security:15552000&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    networks:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      - traefik&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;networks:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;  traefik:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    external: true&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: You must make sure you have &lt;code&gt;A&lt;/code&gt; records pointing your chosen domain to the IP address of your server. With DigitalOcean, this can be set up in the Networking dashboard.&lt;/p&gt;
&lt;p&gt;Nextcloud should have generated some files. In the main Nextcloud directory, &lt;code&gt;cd&lt;/code&gt; into &lt;code&gt;config/&lt;/code&gt; and edit the &lt;code&gt;config.php&lt;/code&gt; file. Edit or add the values shown below to reflect
your configuration.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;trusted_domains&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;array&lt;/span&gt; (
  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;nextcloud.mydomain.com&amp;#39;&lt;/span&gt;,
  &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;,
),
&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;trusted_proxies&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;array&lt;/span&gt; (
  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;&amp;lt;IP ADDRESS OF DOCKER&amp;gt;&amp;#39;&lt;/span&gt;,
),
&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;forwarded_for_headers&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;array&lt;/span&gt; (
  &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;HTTP_X_FORWARDED_FOR&amp;#39;&lt;/span&gt;,
),

&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;overwritehost&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;nextcloud.mydomain.com&amp;#39;&lt;/span&gt;,
&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;overwrite.cli.url&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;http://nextcloud.mydomain.com&amp;#39;&lt;/span&gt;,
&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;overwriteprotocol&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;https&amp;#39;&lt;/span&gt;,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;trusted_domains&lt;/code&gt; allows Nextcloud to be reached at your chosen domain. &lt;code&gt;trusted_proxies&lt;/code&gt; allows Nextcloud to properly detect connecting IP addresses that are being reverse-proxied by traefik. &lt;code&gt;forwarded_for_headers&lt;/code&gt; was added to get rid of an error about invalid &lt;code&gt;HSTS&lt;/code&gt; headers. Finally, the last three lines enable &lt;code&gt;HTTPS&lt;/code&gt; redirects. Without these lines, sync clients will be unable to correctly authenticate with the server.&lt;/p&gt;
&lt;p&gt;To bring up the stack, run &lt;code&gt;docker-compose up -d&lt;/code&gt;, or &lt;code&gt;docker-compose up&lt;/code&gt; if you want to see the logs in your terminal. If all goes correctly, you should be able to access your
cloud instance at the domain you selected.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/Nextcloud/wizard.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;h1 id=&#34;setting-up-nextcloud&#34;&gt;Setting up Nextcloud&lt;/h1&gt;
&lt;p&gt;At this point, you should be looking at a stock Nextcloud welcome screen. First things firs, create yourself a non-admin user we can use after we get everything set up. This way we can delegate mission critical tasks to the admin account with a &lt;em&gt;very&lt;/em&gt; strong password, and use our own account without access to admin settings.&lt;/p&gt;
&lt;p&gt;One of the main features of Nextcloud I use is the sync clients. I have one on every device. On Arch linux, you can download the &lt;code&gt;nextcloud-client&lt;/code&gt; package. Open it up and log into
the server using your newly created user account. From here you can select a local folder on your machine and map it to a remote folder on your Nextcloud.&lt;/p&gt;
&lt;p&gt;I tend to keep my Nextcloud folder structure almost a 1 to 1 match with the folders in &lt;code&gt;/home&lt;/code&gt; of my computers. That makes syncing the folders absurdly easy, &lt;code&gt;~/Documents&lt;/code&gt; gets
mapped to &lt;code&gt;Documents&lt;/code&gt;, etc.&lt;/p&gt;
&lt;p&gt;This instant synchronization allows me to edit a file on my laptop in one room, and resume editing the same file moments later on my desktop or phone. It&amp;rsquo;s almost like I have one
&lt;code&gt;/home&lt;/code&gt; directory synced across all my devices. Of course you might not want to sync &lt;em&gt;everything&lt;/em&gt;. I found that nextcloud does not play nice with &lt;code&gt;git&lt;/code&gt; directories, and will mess
with the local branch. I exclude mission critical local repositories from syncing so I can manage them through github.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;This guide showed you how to spin up the bare minimum Nextcloud instance using Docker. In my next guide, I&amp;rsquo;ll show you how to flesh out this instance, and what tools to use to make
your digital life completely seamless.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Creating a pocket pentest platform with P4wnP1: Part 1</title>
      <link>https://gideonwolfe.com/posts/security/p4wnp1/</link>
      <pubDate>Sat, 09 Nov 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/security/p4wnp1/</guid>
      <description>&lt;h1 id=&#34;intro&#34;&gt;Intro&lt;/h1&gt;
&lt;p&gt;Those in the security community are most likely familiar with the &lt;a href=&#34;https://shop.hak5.org/products/usb-rubber-ducky-deluxe&#34;&gt;USB rubber ducky&lt;/a&gt;.
On the off chance that you haven&amp;rsquo;t heard of it, the ducky is a device with the form factor of a standard USB drive. However instead of simply storing files, the rubber ducky can emulate a
Human Interface Device (HID) such as a keyboard and mouse. It can preform any task you would be able to using these devices, except it can type at the speed of a computer.&lt;/p&gt;
&lt;p&gt;This allows an attacker to plug in the ducky, deliver their payload at lightning speed, and get the hell out.&lt;/p&gt;
&lt;p&gt;That being said, the ducky has some limitations. First of all, it is $50 for a single unit, which seems like a lot for a tiny flash drive with a single capability. Secondly, the
default language &amp;ldquo;Duckyscript&amp;rdquo; does not allow for particularly advanced payloads. Payloads can be selected with physical dip switches on the device.&lt;/p&gt;
&lt;p&gt;Then I heard about &lt;a href=&#34;https://github.com/mame82/P4wnP1_aloa&#34;&gt;P4wnP1&lt;/a&gt;, which solves many of the issues mentioned above. P4wnP1 runs on a raspberry pi, a tiny but fully featured linux
computer. This means that on top of the HID injection features of the rubber ducky, there is a lightweight installation of Kali Linux under the hood, ready for you to use as a
malicious AP, pivot box, network sniffer, or whatever else you would do with Kali.&lt;/p&gt;
&lt;h1 id=&#34;required-hardware&#34;&gt;Required hardware:&lt;/h1&gt;
&lt;p&gt;Here is a list of the hardware I used for this project.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&#34;https://www.adafruit.com/product/3400&#34;&gt;Raspberry pi 0W&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&#34;https://www.amazon.com/gp/product/B0756KM7CY/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&amp;amp;psc=1&#34;&gt;GPIO pins&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;$7.97&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&#34;https://www.amazon.com/gp/product/B078D6NXFM/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&amp;amp;psc=1&#34;&gt;OLED display hat&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;$16.95&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&#34;https://www.amazon.com/gp/product/B07R9WN5M6/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&amp;amp;th=1&#34;&gt;Micro SD card(s)&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;$16.98&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&#34;https://www.amazon.com/gp/product/B077W69CD1/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&amp;amp;th=1&#34;&gt;USB A addon board&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;$8.99&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3D printed case&lt;/td&gt;
&lt;td&gt;Free from work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total&lt;/td&gt;
&lt;td&gt;$60.89&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For only $10 more than the ducky, we can expand our feature set by a great amount. Not only this, but many of these items contain duplicates, (multiple SD cards and GPIO pin sets)
so you could make many of these devices, or save money by buying individually packaged.&lt;/p&gt;
&lt;h1 id=&#34;installing-p4wnp1&#34;&gt;Installing P4wnP1&lt;/h1&gt;
&lt;p&gt;Looking at the P4wnP1 &lt;a href=&#34;https://github.com/mame82/P4wnP1_aloa/blob/master/README.md&#34;&gt;readme&lt;/a&gt;, we can see there&amp;rsquo;s options for installing the P4wnP1 service on top of an existing
linux distrobution, or installing the entire image to a fresh SD card.&lt;/p&gt;
&lt;p&gt;Since we have fresh SD cards, this is by far the simplest method. Fire up your favorite image flasher (or use the dd command) and write the &lt;a href=&#34;https://github.com/mame82/P4wnP1_aloa/releases&#34;&gt;latest P4wnP1
image&lt;/a&gt; to your SD card. Most documentation recommends the &lt;a href=&#34;https://aur.archlinux.org/packages/balena-etcher/&#34;&gt;etcher&lt;/a&gt; program to do
this, so I figured I would give it a shot.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/security/p4wnp1/etcher.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Open etcher as root, select your image, select your SD card, and flash away.&lt;/p&gt;
&lt;p&gt;Once this step is complete, you have an SD card containing the P4wnP1 image, ready to roll in your raspberry pi.&lt;/p&gt;
&lt;h1 id=&#34;set-up-p4wnp1&#34;&gt;Set up P4wnP1&lt;/h1&gt;
&lt;p&gt;To set up your P4wnP1 for the first time, we can plug in a Micro USB cable from a PC into the pi.&lt;/p&gt;
&lt;p&gt;Make sure that the correct &amp;ldquo;Data&amp;rdquo; port is being used instead of the power port. Do not interrupt the first boot of the P4wnP1, which can take a few minutes.&lt;/p&gt;
&lt;p&gt;There are a few ways to connect to your pi. My preferred method is to use the PC the pi is connected to and navigate to http://172.16.0.1:8000 in a browser. This should open up the
P4wnP1 web configuration page.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/security/p4wnp1/usbsettings.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;I will delve further into the settings and workflow in another post, as I am mainly focusing on getting the physical device set up here.&lt;/p&gt;
&lt;p&gt;Additionally, you can connect to P4wnP1 by using the web interface to connect it to your WiFi network, and ssh to it with &lt;code&gt;ssh root@172.16.0.1&lt;/code&gt;. Or connect your device to the AP
broadcasted by the P4wnP1, and ssh from that network. There is also a bluetooth configuration option, yet I have never tried it.&lt;/p&gt;
&lt;p&gt;See the &lt;a href=&#34;https://github.com/mame82/P4wnP1_aloa#21-run-a-keystroke-injection-against-a-host-which-has-p4wnp1-attached-via-usb&#34;&gt;readme section&lt;/a&gt; for more info on how to connect to
your P4wnP1.&lt;/p&gt;
&lt;h1 id=&#34;setting-up-the-hardware&#34;&gt;Setting up the hardware&lt;/h1&gt;
&lt;p&gt;Now that we confirmed we have a working raspberry pi, and a valid version of P4wnP1 flashed to our SD card, we can start working on the hardware.&lt;/p&gt;
&lt;p&gt;The first step is to solder the GPIO pins to the raspberry pi. If you don&amp;rsquo;t have a soldering gun or are just a bit lazy, you can opt for a raspbery pi 0W with &lt;a href=&#34;https://www.adafruit.com/product/3708&#34;&gt;pre soldered
pins&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Holding the raspberry pi upright, insert the pins short side down into the pinholes. Moving to the underside of the pi, apply a small drop of solder to each of the pins, so it
makes a connection with the pad at the base of the pin.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/security/p4wnp1/pins.jpg&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Notice the plastic screws poking through the corners of the board. Those are the standoffs for the USB A addon board, which you can proceed to secure with the provided set of
plastic nuts.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/security/p4wnp1/addon.jpg&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;The USB A addon board should make a solid connection with the pads on the bottom of the pi. Test to see if it works by powering the pi over the USB A plug. This addon
board allows us to preform ducky like attacks without carrying an additional micro USB -&amp;gt; USB A converter.&lt;/p&gt;
&lt;p&gt;Finally, we can install the OLED screen hat using the GPIO pins we just soldered to the pi. This may take a bit of force, but the screen should press down over the IO pins.&lt;/p&gt;
&lt;p&gt;I used a bit of the foam that the OLED hat was packaged with to brace the PCB against the 3D printed case.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/security/p4wnp1/screen.jpg&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;h1 id=&#34;setting-up-the-menu&#34;&gt;Setting up the menu:&lt;/h1&gt;
&lt;p&gt;For the OLED menu, we will be using the amazing &lt;a href=&#34;https://github.com/beboxos/P4wnP1_ALOA_OLED_MENU_V2&#34;&gt;menu&lt;/a&gt; by Beboxos. The full tutorial can be found in the readme, but I will
outline the steps here, as it&amp;rsquo;s quite simple.&lt;/p&gt;
&lt;p&gt;To enable the screen to for P4wnP1, we first have to edit the &lt;code&gt;config.txt&lt;/code&gt; located in the boot partition of the SD card.&lt;/p&gt;
&lt;p&gt;In the dtparam section, make sure the following lines are set:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-config&#34; data-lang=&#34;config&#34;&gt;dtparam=i2c_arm=on dtparam=i2c1=on
dtparam=spi=on
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There is a section in the readme that mentions only one of these lines is necessary depending on your display, but I had the display he recommended on the
&lt;a href=&#34;https://www.thingiverse.com/thing:3354621&#34;&gt;Thingiverse&lt;/a&gt; page, so I left all the options on to be safe. Haven&amp;rsquo;t seen any issues so far with that.&lt;/p&gt;
&lt;p&gt;Next, ssh into the pi with &lt;code&gt;ssh root@17.16.0.1&lt;/code&gt;. Connect the pi to the internet through the web interface, and clone the
&lt;a href=&#34;https://github.com/beboxos/P4wnP1_ALOA_OLED_MENU_V2&#34;&gt;repository&lt;/a&gt; for this project. Inside it, you will find a script &lt;code&gt;install.sh&lt;/code&gt; At the time of writing, this script was quite
buggy, and I had to fix it up a bit to get it working. Mostly just messed up filepaths and such.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/sh
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Install Luma.core drivers&amp;#34;&lt;/span&gt;
apt-get install python-dev python-pip libfreetype6-dev libjpeg-dev
pip install --upgrade pip
apt-get purge python-pip
pip install --upgrade luma.oled
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Create directory&amp;#34;&lt;/span&gt;
mkdir /root/BeBoXGui/
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Copying files&amp;#34;&lt;/span&gt;
cp *.py /root/BeBoXGui/
mkdir /root/BeBoXGui/images
cd images
cp * /root/BeBoXGui/images/
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Copying run script in local P4wnP1 script&amp;#34;&lt;/span&gt;
cp scripts/runmenu.sh /usr/local/P4wnP1/scripts/
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;All files are ready&amp;#34;&lt;/span&gt;
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;to run with P4wnP1 boot&amp;#34;&lt;/span&gt;
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Go thru web interface&amp;#34;&lt;/span&gt;
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Go in trigger section&amp;#34;&lt;/span&gt;
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Create new trigger&amp;#34;&lt;/span&gt;
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;on service start :&amp;#34;&lt;/span&gt;
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;run script sh and choose &amp;#34;&lt;/span&gt;
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;runmenu.sh&amp;#34;&lt;/span&gt;
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Enjoy&amp;#34;&lt;/span&gt;
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;by default gui.py use SPI interface&amp;#34;&lt;/span&gt;
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;if you use I2C oled edit gui.py&amp;#34;&lt;/span&gt;
echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;and set I2C_USER = 1&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I would have created a PR for these fixes but there was an outstanding PR addressing the issue which has been ignored for some months now.&lt;/p&gt;
&lt;p&gt;As you can see in the script, the script &lt;code&gt;runmenu.sh&lt;/code&gt; was copied to &lt;code&gt;/usr/local/P4wnP1/scripts/&lt;/code&gt;. As you might have guessed, running this script will in fact run the on screen
menu. The final step is to create a trigger action that runs that script when the P4wnP1 service starts.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/security/p4wnp1/screentrigger.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;We can then store this trigger action set, and create a new &amp;ldquo;master template&amp;rdquo; in the Generic Settings menu that uses this stored trigger actions set.
This master template should inherit all other settings modules from &lt;code&gt;startup&lt;/code&gt; as to not interfere with the process.&lt;/p&gt;
&lt;p&gt;We can then make our newly created master template the default startup template using the field on the righthand side of the screen.&lt;/p&gt;
&lt;p&gt;Now when you reboot the device, you should be greeted by the OLED menu!&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/security/p4wnp1/boot.jpg&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;I replaced the filename at &lt;a href=&#34;https://github.com/beboxos/P4wnP1_ALOA_OLED_MENU_V2/blob/dc50259f90ecf02c07924a6799f97653d0544bcf/gui.py#L222&#34;&gt;this&lt;/a&gt; line with another file from the
&lt;code&gt;images&lt;/code&gt; directory. You could totally make your own, I would love to see some cool ones.&lt;/p&gt;
&lt;p&gt;We can see the main menu offering us a wide range of options.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/security/p4wnp1/mainmenu.jpg&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;The main areas of interest to us are the &lt;code&gt;HID Management&lt;/code&gt; and &lt;code&gt;Templates Features&lt;/code&gt; sections. The &lt;code&gt;HID Management&lt;/code&gt; section allows you to browse your stored HID scripts, and run them
as either a direct or background job.&lt;/p&gt;
&lt;p&gt;
  &lt;img src=&#34;https://gideonwolfe.com/img/security/p4wnp1/hidscripts.jpg&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


In &lt;code&gt;Templates Features&lt;/code&gt;, we can browse and apply any saved settings templates for Network, Bluetooth, Wifi, USB, and Trigger actions. This allows you to easily set up more complex
attacks with complicated configurations without having to set them up via SSH or the web interface&lt;/p&gt;
&lt;p&gt;Any settings applied through the menu should be instantly visible on the web interface.&lt;/p&gt;
&lt;h1 id=&#34;the-case&#34;&gt;The Case&lt;/h1&gt;
&lt;p&gt;I happen to be lucky enough to work an environment where I have a 3D printer at my disposal. However I did not design the case myself, but I found it on &lt;a href=&#34;https://www.thingiverse.com/thing:3354621&#34;&gt;Thingiverse&lt;/a&gt;, and printed out from there.&lt;/p&gt;
&lt;p&gt;Eventually, I would like to modify this design to incorporate some sort of rechargeable battery. However since the screen is occupying the GPIO pins and the USB A addon is
occupying the connection pads, there are limited options when it comes to connecting it.&lt;/p&gt;
&lt;p&gt;One could forgo the USB A capabilities and instead use the connectors for a &lt;a href=&#34;https://hackaday.io/project/164733-pisugar-battery-for-raspberry-pi-zero&#34;&gt;Pisugar&lt;/a&gt;, which provides a
solderless rechargeable battery.&lt;/p&gt;
&lt;p&gt;Or if someone wanted to make a screenless version, they could opt for a LiPo hat that uses multiple PCBs and the GPIO pins. This seems like it would be the bulkiest method.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;In this post, I showed you how to create a pocket sized pentest platform, with HID keystroke capabilities that are more robust than the USB rubber ducky, with the benefits of a
powerful Kali Linux backbone for all your netsec needs.&lt;/p&gt;
&lt;p&gt;In the near future I will elaborate on the effective P4wnP1 workflow, and some nifty examples of the powerful HID interface API.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Alava - A new single by the Dawn Bombs</title>
      <link>https://gideonwolfe.com/posts/music/alava/</link>
      <pubDate>Sat, 12 Oct 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/music/alava/</guid>
      <description>&lt;p&gt;I have been a huge fan of &lt;a href=&#34;https://open.spotify.com/artist/07utP4RAHF10j0QPKAGF7A&#34;&gt;The Dawn Bombs&lt;/a&gt; since I met moved to Bellingham and my previous band &lt;a href=&#34;https://open.spotify.com/artist/2kuNX0E4ysjdL164vTlrpy&#34;&gt;Middle James&lt;/a&gt; started playing shows with them.&lt;/p&gt;
&lt;p&gt;Fast forward a few years, and the band has moved into my apartment. My friend and ex-bassist for the dawn bombs had left to move on to other projects, and I happily stepped in to
fill the void as best I could.&lt;/p&gt;
&lt;p&gt;While I do appear on this recording singing and playing bass, I cannot take credit for this bassline. This was one of the last parts written by my predecessor, and in my opinion
some of his finest work.&lt;/p&gt;
&lt;p&gt;That being said, I thoroughly enjoyed being involved in the production of the rest of the song, from the mixing and mastering to the instrumentation and composition.&lt;/p&gt;
&lt;p&gt;We were also fortunate enough to be provided with some amazing artwork, courtesy of my roommate. You can check out some of her other art &lt;a href=&#34;https://instagram.com/aaaaart_by_sky?igshid=hsfrwf3bkzfu&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Alava is already on &lt;a href=&#34;https://thedawnbombs.bandcamp.com/track/alava&#34;&gt;Bandcamp&lt;/a&gt;, and will appear on Spotify and other streaming platforms later this week.&lt;/p&gt;
&lt;p&gt;You can check our &lt;a href=&#34;https://www.facebook.com/thedawnbombs/&#34;&gt;Facebook&lt;/a&gt; page for information about upcoming shows and releases!&lt;/p&gt;

&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
  &lt;iframe src=&#34;https://www.youtube.com/embed/GJUTlqFZCQg&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; allowfullscreen title=&#34;YouTube Video&#34;&gt;&lt;/iframe&gt;
&lt;/div&gt;

</description>
    </item>
    
    <item>
      <title>vim.reaper: 💀 A Hackable, Fully Featured, Rice Friendly Neovim Configuration </title>
      <link>https://gideonwolfe.com/posts/programming/general/vimreaper/</link>
      <pubDate>Wed, 09 Oct 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/programming/general/vimreaper/</guid>
      <description>&lt;h1 id=&#34;what-is-vimreaper&#34;&gt;What is vim.reaper?&lt;/h1&gt;
&lt;p&gt;Over the years, I have slowly built up a configuration for neovim, adding functionality as the need arises.&lt;/p&gt;
&lt;p&gt;With all my keybindings, plugins, and settings, my &lt;code&gt;init.nvim&lt;/code&gt; file was well over 700 lines long. Debugging and editing settings was a chore.&lt;/p&gt;
&lt;p&gt;With &lt;a href=&#34;https://github.com/GideonWolfe/vim.reaper&#34;&gt;vim.reaper&lt;/a&gt;, I have split that configuration file into multiple modular pieces, that can easily be tweaked to fit the needs of the individual user. Not only that, but I adhere
to my practice of keeping a theme consistent where possible. vim.reaper uses the &lt;code&gt;wal&lt;/code&gt; theme, and will highlight syntax and icons appropriately.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/neovim/reaper/vista.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Additionally, you get sane default keybindings that are easy to learn. Complex functions are available with just a few intuitive keypresses!&lt;/p&gt;
&lt;p&gt;My goal was to create a configuration that is easy to modify, grants access to IDE like features, and can be updated and deployed with ease. As I update this configuration, I will
inch further towards these goals.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/neovim/reaper/nerdtree.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Please feel free to submit a pull request. I would love to make the configuration more robust across all systems, and incorporate features that are wanted by users.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Genetically Engineering Yeast to Bioluminescence: Overview of steps</title>
      <link>https://gideonwolfe.com/posts/bio/yeast/basicsteps/</link>
      <pubDate>Sun, 22 Sep 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/bio/yeast/basicsteps/</guid>
      <description>&lt;h1 id=&#34;contents&#34;&gt;Contents&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gideonwolfe.com/posts/bio/basicsteps/#yeast&#34;&gt;The Yeast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gideonwolfe.com/posts/bio/basicsteps/#plasmid&#34;&gt;The Plasmid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gideonwolfe.com/posts/bio/basicsteps/#equipment&#34;&gt;The Equipment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gideonwolfe.com/posts/bio/basicsteps/#timeline&#34;&gt;The Timeline&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;intro&#34;&gt;Intro&lt;/h1&gt;
&lt;p&gt;In a follow up to my &lt;a href=&#34;https://gideonwolfe.com/posts/bio/yeast/intro/&#34;&gt;previous posts&lt;/a&gt;, I will further explore the tools, steps, and biological processes that enable trivial gene editing using the CRISPR/Cas9 system. Future posts will dive deeper into each topic as I encounter them during my experiments.&lt;/p&gt;
&lt;h1 id=&#34;the-yeast&#34;&gt;The Yeast&lt;/h1&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;In theory, this process should work with almost any strain of yeast. However I have plans for this yeast, which may or may not involve using it to ferment glowing wine and beer 😉.&lt;/p&gt;
&lt;p&gt;Therefore I have opted to use &lt;a href=&#34;https://www.amazon.com/Lalvin-D-47-Wine-Yeast-Pack/dp/B07K19SZXD&#34;&gt;D-47 Wine Yeast&lt;/a&gt;, due to it&amp;rsquo;s low price and ubiquity in brewing.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/bio/yeast/yeast.jpg&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 55%; height: 55%;&#34;  /&gt;


&lt;p&gt;In this experiment, our goal is to inject the &lt;a href=&#34;https://en.wikipedia.org/wiki/Green_fluorescent_protein&#34;&gt;Green Fluorescent Protein&lt;/a&gt; into the genome of yeast, causing them to glow green when exposed to light in the blue to ultraviolet range.&lt;/p&gt;
&lt;h1 id=&#34;the-plasmid&#34;&gt;The Plasmid&lt;/h1&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;We can accomplish this by inserting the GFP genetic code into a &lt;a href=&#34;https://en.wikipedia.org/wiki/Plasmid&#34;&gt;plasmid&lt;/a&gt;. A plasmid is a circular piece of DNA that is separate from the main chromasomal DNA, and can replicate itself independently.&lt;/p&gt;

  &lt;figure class=&#34;center&#34; &gt;
    &lt;img src=&#34;https://gideonwolfe.com/img/bio/yeast/plasmid1.png&#34;   style=&#34;border-radius: 8px; width: 85%; height: 85%;&#34;  /&gt;
    
      &lt;figcaption class=&#34;center&#34; &gt;Plasmid from Wikipedia&lt;/figcaption&gt;
    
  &lt;/figure&gt;


&lt;p&gt;This causes the DNA present inside the plasmid to be translated and expressed within the target organism.&lt;/p&gt;
&lt;p&gt;It can be helpful to think of plasmids as &amp;ldquo;DNA Powerups&amp;rdquo; in the sense that they can provide traits such as antibiotic resistance, which will come in handy later in the process.&lt;/p&gt;
&lt;p&gt;In a future post devoted to plasmids, I will further investigate the characteristics and properties of plasmids, as well the specific GFP pasmid used in this experiment.&lt;/p&gt;
&lt;p&gt;Due to my limited tools and resources, I will be using the provided plasmid in the &lt;a href=&#34;https://www.the-odin.com/bacterial-crispr-and-fluorescent-yeast-combo-kit/&#34;&gt;kit&lt;/a&gt; I am planning on purchasing. It has been optimized for this specific application, and can provide insight on to more general plasmid design principles.&lt;/p&gt;
&lt;h1 id=&#34;the-equipment&#34;&gt;The Equipment&lt;/h1&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;Here I will break down the contents of the kit to better understand the purpose of each individual piece.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/bio/yeast/equipment.jpg&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 85%; height: 85%;&#34;  /&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Containers&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Petri Plates&lt;/li&gt;
&lt;li&gt;Glass bottle for pouring plates&lt;/li&gt;
&lt;li&gt;50mL Tube for measuring&lt;/li&gt;
&lt;li&gt;Microcentrifuge tubes&lt;/li&gt;
&lt;li&gt;Microcentrifuge tube rack&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Misc/Disposable&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nitrile Gloves&lt;/li&gt;
&lt;li&gt;Inoculation loops/Plate spreader&lt;/li&gt;
&lt;li&gt;Pipette tips&lt;/li&gt;
&lt;li&gt;UV Filter sheet and blue light&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Bio/Perishable&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 mL Yeast transformation buffer 40% PEG 8000, 200mM LiAc, 0.1mg/mL Salmon Sperm DNA&lt;/li&gt;
&lt;li&gt;Preengineered strain of Yeast Containing GFP Plasmid in Agar stab&lt;/li&gt;
&lt;li&gt;Saccharomyces cerevisiae Mead Yeast Strain&lt;/li&gt;
&lt;li&gt;Yeast GFP Expression plasmid 100ng/uL&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Experiment Supplies&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;YPD Agar&lt;/li&gt;
&lt;li&gt;YPD Agar containing G418 Antibiotic&lt;/li&gt;
&lt;li&gt;0-100uL professional lab grade variable volume adjustable pipette&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;the-timeline&#34;&gt;The Timeline&lt;/h1&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;Here is a general timeline of the steps for this experiment. I will go into more detail about the procedures when I actually do them.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Preparation&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make Agar plates&lt;/li&gt;
&lt;li&gt;Streak yeast onto plates&lt;/li&gt;
&lt;li&gt;Allow yeast to grow overnight&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Day of experiment&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mix the transformation mix, plasmid, and yeast sample&lt;/li&gt;
&lt;li&gt;Heat shock sample for 60 mins&lt;/li&gt;
&lt;li&gt;add YPD media to cell solution&lt;/li&gt;
&lt;li&gt;incubate overnight at room temp&lt;/li&gt;
&lt;li&gt;Plate 400uL of the yeast solution and let dry&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Incubation&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Incubate at room temp for 48+ hours&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;In my next post, I will look at each part of the plasmid and figure out why it works the way that it does. How can we make smart plasmid design choices?&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Genetically Engineering Yeast to Bioluminescence: Introduction </title>
      <link>https://gideonwolfe.com/posts/bio/yeast/intro/</link>
      <pubDate>Sun, 08 Sep 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/bio/yeast/intro/</guid>
      <description>&lt;h1 id=&#34;background-in-biology&#34;&gt;Background in Biology&lt;/h1&gt;
&lt;p&gt;One of my research interests over the past years have been bioinformatics and genetic science.&lt;/p&gt;
&lt;p&gt;The potential in this field is unprecedented, largely due to novel breakthroughs in accessible gene editing methods such as CRISPR/Cas9, as well as &lt;a href=&#34;https://www.wired.com/story/the-rise-of-dna-data-storage/&#34;&gt;DNA storage drives&lt;/a&gt; and other fascinating applications of the technology.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/bio/yeast/dnacut.gif&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 85%; height: 85%;&#34;  /&gt;


&lt;p&gt;The thing that truly inspired me to dig deeper into this field was the YouTube video by the channel &lt;a href=&#34;https://www.youtube.com/channel/UCV5vCi3jPJdURZwAOO_FNfQ&#34;&gt;The Thought Emporium&lt;/a&gt;, where the host hacks together a &lt;a href=&#34;https://www.youtube.com/watch?v=J3FcbFqSoQY&#34;&gt;DIY cure for lactose intolerance&lt;/a&gt; using CRISPR and the tools available to him at a reasonable price.&lt;/p&gt;
&lt;p&gt;To address the topic of this section, I have an &lt;em&gt;extremely&lt;/em&gt; limited knowledge of biology. The last class I took was over 6 years ago as a sophomore in high school. This presents a unique challenge compared to my CS oriented content, which I can approach with a good amount of background knowledge.&lt;/p&gt;
&lt;p&gt;I suspect my education in chemistry will ease my understanding of certain concepts, but I will be doing most of my research from the ground up.&lt;/p&gt;
&lt;p&gt;I invite you to follow along as I research this project, design experiments, make mistakes, and learn new things.&lt;/p&gt;
&lt;h1 id=&#34;the-goal&#34;&gt;The Goal&lt;/h1&gt;
&lt;p&gt;The overall goal for this project is to develop a strain of yeast that carries the &lt;a href=&#34;https://en.wikipedia.org/wiki/Green_fluorescent_protein&#34;&gt;green fluorescent protein&lt;/a&gt; or GFP, in its DNA. This protein is often used as a biomarker for other experiments, and causes the target organism to glow in the dark.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/bio/yeast/ecoli_glow.jpg&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 65%; height: 65%;&#34;  /&gt;


&lt;p&gt;From what I can tell, a simple project like this is the biology equivalent of a &lt;code&gt;Hello World&lt;/code&gt; program. By going through this process, I hope to become familiar with the following topics and concepts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Proper procedures and use of basic bio lab equipment&lt;/li&gt;
&lt;li&gt;Strategies for designing effective plasmids and DNA sequences&lt;/li&gt;
&lt;li&gt;Streamlined physical lab/experiment workflow&lt;/li&gt;
&lt;li&gt;Industry software and tools&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, there are &lt;a href=&#34;https://www.the-odin.com/bacterial-crispr-and-fluorescent-yeast-combo-kit/&#34;&gt;kits&lt;/a&gt; available that let you accomplish this very task, with all of the research done for you. This may teach me appropriate lab procedures, but I want do as much of the initial plasmid design myself for learning purposes, even if I do end up using a kit due to the convenience of getting all the gear I need.&lt;/p&gt;
&lt;h1 id=&#34;challenges&#34;&gt;Challenges&lt;/h1&gt;
&lt;p&gt;Ideally, I would have my own little home laboratory where I could experiment to my hearts content. Being a student, this is not possible in my current financial reality.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/bio/yeast/equipment.jpg&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 85%; height: 85%;&#34;  /&gt;


&lt;p&gt;Each piece of equipment purchased for this project will be thoroughly researched and evaluated for value and efficacy.&lt;/p&gt;
&lt;p&gt;Unlike a computer where I can simply recompile and try again, a failed bio experiment means depleted resources, lost time, and possibly inconclusive results.&lt;/p&gt;
&lt;p&gt;Multiple failed experiments are pretty much a guarantee in this process, as I will be learning how to properly handle and execute experiments with many moving parts and points of failure.&lt;/p&gt;
&lt;h1 id=&#34;crispr-crash-course&#34;&gt;CRISPR Crash Course&lt;/h1&gt;
&lt;p&gt;If you haven&amp;rsquo;t heard something about CRISPR in the last 5 years, welcome back from your coma. Most people know it as the subject of recent controversy where a Chinese scientist &lt;a href=&#34;https://www.nytimes.com/2018/11/26/health/gene-editing-babies-china.html&#34;&gt;supposedly genetically modified a human embryo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/CRISPR&#34;&gt;CRISPR&lt;/a&gt;, which stands for &lt;strong&gt;C&lt;/strong&gt;lustered &lt;strong&gt;R&lt;/strong&gt;egularly &lt;strong&gt;I&lt;/strong&gt;nterspaced &lt;strong&gt;S&lt;/strong&gt;hort &lt;strong&gt;P&lt;/strong&gt;alindromic &lt;strong&gt;R&lt;/strong&gt;epeats, is a collection of DNA sequences commonly found in bacteria and other prokaryotes.&lt;/p&gt;
&lt;p&gt;When a bacteria survives an attack from another organism such as a &lt;a href=&#34;https://en.wikipedia.org/wiki/Bacteriophage&#34;&gt;bacteriophage&lt;/a&gt;, it can archive sections of the attacking organism&amp;rsquo;s DNA in a database that we can refer to as CRISPR.&lt;/p&gt;
&lt;p&gt;When the same organism attacks the bacteria again, a special protein called &lt;a href=&#34;https://en.wikipedia.org/wiki/Cas9&#34;&gt;Cas9&lt;/a&gt; is activated. Cas9 will scan all DNA, and will surgically remove any DNA that matches the archived virus genome.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/bio/yeast/dnasplice.gif&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 85%; height: 85%;&#34;  /&gt;


&lt;p&gt;While this process provides a fantastic natural defense mechanism, scientists can leverage it in order manipulate the genetic code of practically any organism at will. The flexibility and accessibility of CRISPR has enabled new frontiers of genetic research previously impractical or impossible.&lt;/p&gt;
&lt;p&gt;This is an extremely high level overview of the topic, and we will be going over each step in great deal as I encounter it.&lt;/p&gt;
&lt;h1 id=&#34;overview-of-steps&#34;&gt;Overview of Steps&lt;/h1&gt;
&lt;p&gt;Here, I will present a generalized set of steps I will be taking throughout the course of this project.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Preliminary Research:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;What equipment and materials do I need?&lt;/li&gt;
&lt;li&gt;Best delivery method for GFP?&lt;/li&gt;
&lt;li&gt;Possible experimental roadblocks?&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Experiment Design and Optimization&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;What are the important features in a plasmid?&lt;/li&gt;
&lt;li&gt;Can we build a more effective GFP plasmid?&lt;/li&gt;
&lt;li&gt;Do any strains of yeast promise better results?&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Preform Experiments&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Ensure repeatable procedure&lt;/li&gt;
&lt;li&gt;Take careful notes and record data&lt;/li&gt;
&lt;li&gt;Extrapolate conclusions from data&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;If you have any experience in the field or advice for my experiments, I would love to hear it. This is an undeniably ambitious task, that could take some time to complete.&lt;/p&gt;
&lt;p&gt;Until then, thanks for tuning in! 😄&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Quantum Katas #3: Measurement</title>
      <link>https://gideonwolfe.com/posts/quantum/measurement/</link>
      <pubDate>Sat, 31 Aug 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/quantum/measurement/</guid>
      <description>&lt;h1 id=&#34;intro&#34;&gt;Intro&lt;/h1&gt;

&lt;p&gt;In the previous katas, we learned how to send qubits through quantum gates, and how to prepare them in various states of superposition.&lt;/p&gt;

&lt;p&gt;In this guide, we will be taking a look at measuring qubit states, and what effect measurement has on them.&lt;/p&gt;

&lt;h1 id=&#34;task-11-0-or-1-&#34;&gt;Task 1.1: |0⟩ or |1⟩ ?&lt;/h1&gt;

&lt;p&gt;Here we are tasked with returning &lt;code&gt;true&lt;/code&gt; if the input qubit is &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt; and &lt;code&gt;false&lt;/code&gt; if the qubit is &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;To collapse the superposition and measure a qubit, we need to use the measurement gate &lt;code&gt;M()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;M()&lt;/code&gt; returns &lt;code&gt;One&lt;/code&gt; if the qubit is &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt; and &lt;code&gt;Zero&lt;/code&gt; if it is &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;The simplest way to do this task is to evaluate &lt;code&gt;M(q)&lt;/code&gt; and test that it is equal to &lt;code&gt;One&lt;/code&gt;. The result is a &lt;code&gt;boolean&lt;/code&gt;, which we can then return.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation IsQubitOne (q : Qubit) : Bool {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; (M(q) == One);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-12-set-qubit-to-0-state&#34;&gt;Task 1.2: Set qubit to |0⟩ state&lt;/h1&gt;

&lt;p&gt;In this task we are given a qubit in an arbitrary superposition. Firstly, we can measure the qubit to narrow it down to &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; or &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;We check if it measured to be &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt;, and if so, apply an &lt;code&gt;X()&lt;/code&gt; gate to change it to &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation InitializeQubit (q : Qubit) : Unit {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(M(q) == One){
        X(q);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-13--or--&#34;&gt;Task 1.3: |+⟩ or |-⟩ ?&lt;/h1&gt;

&lt;p&gt;We are now given a qubit which is in the state &lt;span  class=&#34;math&#34;&gt;\(|+\rangle\)&lt;/span&gt; or &lt;span  class=&#34;math&#34;&gt;\(|-\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Let us first recall the mappings of the &lt;code&gt;Hadamard&lt;/code&gt; gate.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\(|0\rangle \rightarrow |+\rangle\)&lt;/span&gt;
&lt;span  class=&#34;math&#34;&gt;\(|1\rangle \rightarrow |-\rangle\)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Also, we can leverage the reversible properties of quantum gates to undo the &lt;code&gt;Hadamard&lt;/code&gt; gate, returning our qubit to it&#39;s original state.&lt;/p&gt;

&lt;p&gt;If the qubit measures to be zero, that means it was just &lt;span  class=&#34;math&#34;&gt;\(|+\rangle\)&lt;/span&gt; state and we can return &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation IsQubitPlus (q : Qubit) : Bool {
    H(q);
    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(M(q) == Zero){
        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;;
    }
    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;{
        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-14-a-or-b-&#34;&gt;Task 1.4: |A⟩ or |B⟩ ?&lt;/h1&gt;

&lt;p&gt;We are given an angle &lt;span  class=&#34;math&#34;&gt;\(\alpha\)&lt;/span&gt; in radians and a qubit which will be in one of the following states:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\( |A\rangle = cos(\alpha)|0\rangle + sin(\alpha)|1\rangle \)&lt;/span&gt;
&lt;span  class=&#34;math&#34;&gt;\( |B\rangle = - sin(\alpha)|0\rangle + cos(\alpha)|1\rangle \)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;If we measure state &lt;span  class=&#34;math&#34;&gt;\(|A\rangle\)&lt;/span&gt; we return &lt;code&gt;true&lt;/code&gt;, and &lt;code&gt;false&lt;/code&gt; if we measure &lt;span  class=&#34;math&#34;&gt;\(|B\rangle\)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;We can think of these states as being some rotation of a qubit by &lt;span  class=&#34;math&#34;&gt;\(\alpha\)&lt;/span&gt; degrees.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation AmplitudeChange_Reference (alpha : Double, q : Qubit) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj+Ctl {
    Ry(&lt;span style=&#34;color:#ae81ff&#34;&gt;2.0&lt;/span&gt; * alpha, q);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-15-00-or-11-&#34;&gt;Task 1.5: |00⟩ or |11⟩ ?&lt;/h1&gt;

&lt;p&gt;Here we are given a two qubit state with equal probability of being in state &lt;span  class=&#34;math&#34;&gt;\(|11\rangle\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(|00\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Since there are no possible mixed states, we only have to measure one of the qubits to determine the state of the other.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation ZeroZeroOrOneOne (qs : Qubit[]) : Int {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(M(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]) == One){
        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
    }
    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;{
        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-16-distinguish-four-basis-states&#34;&gt;Task 1.6: Distinguish four basis states&lt;/h1&gt;

&lt;p&gt;This task is the same as the task above, but we must add an additional check to account for the possibility of mixed states &lt;span  class=&#34;math&#34;&gt;\(|01\rangle\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(|10\rangle\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation BasisStateMeasurement (qs : Qubit[]) : Int {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(M(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]) == One){
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(M(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]) == One){
            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;// |11⟩ 
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        }
        &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;{
            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;// |10⟩ 
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        }
    }
    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;{
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(M(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]) == One){
            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;// |01⟩ 
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        }
        &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;{
            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;// |00⟩ 
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-17-distinguish-two-basis-states-given-by-bit-strings&#34;&gt;Task 1.7: Distinguish two basis states given by bit strings&lt;/h1&gt;

&lt;p&gt;In this task we are given two bit strings, as well as &lt;span  class=&#34;math&#34;&gt;\(N\)&lt;/span&gt; qubits that are in a state described by one of the two bitstrings.&lt;/p&gt;

&lt;p&gt;First, we need to find where the bitstrings diverge. We can reuse our helper function from the last kata to find that index.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;function FindFirstDiff (bits1 : Bool[], bits2 : Bool[]) : Int {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; .. Length(bits1) - &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (bits1[i] != bits2[i]) {
            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; i;
        }
    }
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; -&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then we can measure our qubit array at the &lt;code&gt;FirstDiff&lt;/code&gt; index. We can turn the result of our measurement into a &lt;code&gt;boolean&lt;/code&gt; by testing it&#39;s equality to &lt;code&gt;One&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If our qubit measured &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt;, our variable will be &lt;code&gt;true&lt;/code&gt;. If we measured &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt;, our variable will be &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we can check if the bit we measured belongs to the state describe by the first or second bitstring.&lt;/p&gt;

&lt;p&gt;If the &lt;code&gt;boolean&lt;/code&gt; at &lt;code&gt;bits1[firstDiff]&lt;/code&gt; is the same as our measured value, we know &lt;code&gt;bits1[]&lt;/code&gt; describes our current state and we can return &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation TwoBitstringsMeasurement (qs : Qubit[], bits1 : Bool[], bits2 : Bool[]) : Int {

    &lt;span style=&#34;color:#75715e&#34;&gt;// find the first index at which the bit strings are different
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; firstDiff = FindFirstDiff(bits1, bits2);
    
    &lt;span style=&#34;color:#75715e&#34;&gt;// res = true if the first different qubit measures to be one
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; res = M(qs[firstDiff]) == One;
    
    &lt;span style=&#34;color:#75715e&#34;&gt;// If the measurement aligns with the value in the first bitstring, return 0
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// Otherwise it&amp;#39;s the second state, return false.
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; res == bits1[firstDiff] ? &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; | &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-18-00-state-or-w-state-&#34;&gt;Task 1.8: |0...0⟩ state or W state ?&lt;/h1&gt;

&lt;p&gt;In this task, we must determine if the supplied qubits are in a &lt;span  class=&#34;math&#34;&gt;\(W\)&lt;/span&gt; state or a &lt;span  class=&#34;math&#34;&gt;\(|0..0\rangle\)&lt;/span&gt; state.&lt;/p&gt;

&lt;p&gt;We know from our last kata that the &lt;span  class=&#34;math&#34;&gt;\(W\)&lt;/span&gt; state looks like&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |W_N\rangle = \frac{\overbrace{|100...0\rangle + |010...0\rangle + ... + |00..01\rangle}^{N \text{ states}}}{\sqrt{N}} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Notice how every possible measurement in a &lt;span  class=&#34;math&#34;&gt;\(W\)&lt;/span&gt; state includes a single &lt;span  class=&#34;math&#34;&gt;\(1\)&lt;/span&gt;. If we find even a single one in our measured state, it can no longer be in state &lt;span  class=&#34;math&#34;&gt;\(|0...0\rangle\)&lt;/span&gt; and thus it must be a &lt;span  class=&#34;math&#34;&gt;\(W\)&lt;/span&gt; state.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation AllZerosOrWState (qs : Qubit[]) : Int {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (q &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; .. Length(qs) - &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;){
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt;(M(qs[q]) == One){
            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;// We found a one, it&amp;#39;s W
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        }
    }
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;// it&amp;#39;s |0...0⟩
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-19-ghz-state-or-w-state-&#34;&gt;Task 1.9: GHZ state or W state ?&lt;/h1&gt;

&lt;p&gt;Like the last task, we are given a qubit register and must determine which of two possible states they are in.&lt;/p&gt;

&lt;p&gt;They can either be in a &lt;span  class=&#34;math&#34;&gt;\(W\)&lt;/span&gt; state, or a &lt;span  class=&#34;math&#34;&gt;\(GHZ\)&lt;/span&gt; state. Recall that a &lt;span  class=&#34;math&#34;&gt;\(GHZ\)&lt;/span&gt; state is:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ GHZ_n = \frac{ \overbrace{|0...0\rangle}^{n} + \overbrace{|1...1\rangle}^{n} }{\sqrt{2}} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;If our qubits are in a &lt;span  class=&#34;math&#34;&gt;\(GHZ\)&lt;/span&gt; state, we can expect them to be either all &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; or all &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt;. If we find two of our qubits measure as different values, we can assume they are in the &lt;span  class=&#34;math&#34;&gt;\(W\)&lt;/span&gt; state.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation GHZOrWState (qs : Qubit[]) : Int {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt;(q &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; .. Length(qs) - &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;){
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (M(qs[q-&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]) != M(qs[q])){
            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
        }
    }
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-110-distinguish-four-bell-states&#34;&gt;Task 1.10: Distinguish four Bell states&lt;/h1&gt;

&lt;p&gt;As input we receive an array of two qubits that are guaranteed to be in a Bell state.&lt;/p&gt;

&lt;p&gt;Let us recall the four Bell states, as well as the return values we use to distinguish them in this task.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\( 0: |\Phi^+\rangle = \frac{|00\rangle + |11\rangle}{\sqrt{2}} \)&lt;/span&gt;
&lt;span  class=&#34;math&#34;&gt;\( 1: |\Phi^-\rangle = \frac{|00\rangle - |11\rangle}{\sqrt{2}} \)&lt;/span&gt;
&lt;span  class=&#34;math&#34;&gt;\( 2: |\Psi^+\rangle = \frac{|01\rangle + |10\rangle}{\sqrt{2}} \)&lt;/span&gt;
&lt;span  class=&#34;math&#34;&gt;\( 3: |\Psi^-\rangle = \frac{|01\rangle - |10\rangle}{\sqrt{2}} \)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The first step is to apply the &lt;code&gt;H()&lt;/code&gt; gate to both of our qubits.&lt;/p&gt;

&lt;p&gt;Then, we can reverse our Bell circuit by preforming a &lt;code&gt;CNOT&lt;/code&gt; using the second bit as control, and then applying the &lt;code&gt;H()&lt;/code&gt; gate to it.&lt;/p&gt;

&lt;p&gt;This will change our state to one of the following: &lt;span  class=&#34;math&#34;&gt;\(|00\rangle\)&lt;/span&gt;, &lt;span  class=&#34;math&#34;&gt;\(|01\rangle\)&lt;/span&gt;, &lt;span  class=&#34;math&#34;&gt;\(|10\rangle\)&lt;/span&gt;, &lt;span  class=&#34;math&#34;&gt;\(|11\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;We can then create two &lt;code&gt;integer&lt;/code&gt; variables my measuring each of the qubits and testing their equality to &lt;code&gt;Zero&lt;/code&gt; or &lt;code&gt;One&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can finally compute &lt;code&gt;m2 * 2 + m1&lt;/code&gt; and return it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation BellState (qs : Qubit[]) : Int {
    H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
    H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
    
    CNOT(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;], qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
    H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);

    &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; m1 = M(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]) == Zero ? &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; | &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt;  m2 = M(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]) == Zero ? &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; | &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; m2 * &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; + m1;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/quantum/BellDistinguish.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 100%; height: 100%;&#34;  /&gt;



&lt;p&gt;In this &lt;a href=&#34;https://algassert.com/quirk#circuit={%22cols%22:[[1,%22H%22],[%22X%22,%22%E2%80%A2%22],[%22Amps2%22],[],[%22H%22,%22H%22],[%22%E2%80%A2%22,%22X%22],[%22H%22]],%22init%22:[1,1]}&#34;&gt;Quirk&lt;/a&gt; circuit, we can see that we input the &lt;span  class=&#34;math&#34;&gt;\(|\Psi^-\rangle\)&lt;/span&gt; state, and we received the value &lt;span  class=&#34;math&#34;&gt;\(|11\rangle\)&lt;/span&gt;. &lt;span  class=&#34;math&#34;&gt;\((1 * 2) + 1 = 3\)&lt;/span&gt;, which corresponds to &lt;span  class=&#34;math&#34;&gt;\(|\Psi^-\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;h1 id=&#34;task-111-distinguish-four-orthogonal-2qubit-states&#34;&gt;Task 1.11: Distinguish four orthogonal 2-qubit states&lt;/h1&gt;

&lt;p&gt;We have the four following states, one of which represents the state of the supplied qubits:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\( |S_0\rangle = \frac{|00\rangle + |01\rangle + |10\rangle + |11\rangle}{2} \)&lt;/span&gt;
&lt;span  class=&#34;math&#34;&gt;\( |S_1\rangle = \frac{|00\rangle - |01\rangle + |10\rangle - |11\rangle}{2} \)&lt;/span&gt;
&lt;span  class=&#34;math&#34;&gt;\( |S_2\rangle = \frac{|00\rangle + |01\rangle - |10\rangle - |11\rangle}{2} \)&lt;/span&gt;
&lt;span  class=&#34;math&#34;&gt;\( |S_3\rangle = \frac{|00\rangle - |01\rangle - |10\rangle + |11\rangle}{2} \)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;We can again apply the &lt;code&gt;Hadamard&lt;/code&gt; gate to both our qubits to collapse them into one of the two qubit basis states &lt;span  class=&#34;math&#34;&gt;\(|00\rangle\)&lt;/span&gt;, &lt;span  class=&#34;math&#34;&gt;\(|01\rangle\)&lt;/span&gt;, &lt;span  class=&#34;math&#34;&gt;\(|10\rangle\)&lt;/span&gt;, or &lt;span  class=&#34;math&#34;&gt;\(|11\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Then we can use the solution from task 1.6 to identify the correct basis state.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation TwoQubitState (qs : Qubit[]) : Int {
    H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
    H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; BasisStateMeasurement(qs);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-112-distinguish-four-orthogonal-2qubit-states-part-two&#34;&gt;Task 1.12: Distinguish four orthogonal 2-qubit states, part two&lt;/h1&gt;

&lt;p&gt;The trick to this task is applying the &lt;code&gt;Hadamard&lt;/code&gt; gate to transform the four orthogonal states into the Bell states.&lt;/p&gt;

&lt;p&gt;After this is achieved, we can implement code similar to task 1.10 to determine what the bell state is.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation TwoQubitStatePartTwo (qs : Qubit[]) : Int {
    H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
    
    CNOT(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;], qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
    H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);

    &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; m1 = M(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]) == One ? &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; | &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; m2 = M(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]) == One ? &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; | &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; m2 * &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; + m1;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-113-distinguish-two-orthogonal-states-on-three-qubits&#34;&gt;Task 1.13: Distinguish two orthogonal states on three qubits&lt;/h1&gt;

&lt;p&gt;As input, we are given three qubits stored in an array. The array is guaranteed to be in one of the following states:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\( \frac{|100\rangle + \omega|010\rangle + \omega^2|001\rangle }{\sqrt{3}} \)&lt;/span&gt;
&lt;span  class=&#34;math&#34;&gt;\( \frac{|100\rangle + \omega^2|010\rangle + \omega|001\rangle }{\sqrt{3}}\)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;where &lt;span  class=&#34;math&#34;&gt;\(\omega = \text{exp}(2\pi \frac{i}{3})\)&lt;/span&gt;. We are to output &lt;code&gt;0&lt;/code&gt; if we find our qubits in the first state, &lt;code&gt;1&lt;/code&gt; if we find them in the second.&lt;/p&gt;

&lt;p&gt;In order to solve this, we must map our first state to a &lt;span  class=&#34;math&#34;&gt;\(W\)&lt;/span&gt; state, and our second state to the first.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \frac{|100\rangle + \omega|010\rangle + \omega^2|001\rangle }{\sqrt{3}} \rightarrow \frac{|100\rangle + |010\rangle + |001\rangle }{\sqrt{3}} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \frac{|100\rangle + \omega^2|010\rangle + \omega|001\rangle }{\sqrt{3}} \rightarrow \frac{|100\rangle + \omega|010\rangle + \omega^2|001\rangle }{\sqrt{3}} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;We can achieve this by applying a unitary operation of the form &lt;span  class=&#34;math&#34;&gt;\(I_2 \otimes R \otimes R^2\)&lt;/span&gt;&lt;/p&gt;

&lt;div&gt;
$$

\begin{bmatrix}
1 &amp; 0\\
0 &amp; 1\\
\end{bmatrix}

\otimes

\begin{bmatrix}
1 &amp; 0\\
0 &amp; \omega^2\\
\end{bmatrix}

\otimes

\begin{bmatrix}
1 &amp; 0\\
0 &amp; \omega\\
\end{bmatrix}

$$
&lt;/div&gt;

&lt;p&gt;Now we can take the new &lt;span  class=&#34;math&#34;&gt;\(W\)&lt;/span&gt; state and undo it into the state &lt;span  class=&#34;math&#34;&gt;\(|000\rangle\)&lt;/span&gt;, by utilizing the &lt;code&gt;Adjoint&lt;/code&gt; if the operation that let us prepare the &lt;span  class=&#34;math&#34;&gt;\(W\)&lt;/span&gt; state in the last kata.&lt;/p&gt;

&lt;p&gt;Our second state will then be mapped to some state guaranteed to be perpendicular to &lt;span  class=&#34;math&#34;&gt;\(|000\rangle\)&lt;/span&gt;. In simple terms, the second state will never be measured to be &lt;span  class=&#34;math&#34;&gt;\(|000\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Now we can measure our state, which is either &lt;span  class=&#34;math&#34;&gt;\(|000\rangle\)&lt;/span&gt; (state 1) or something else (state 2). To measure this, I prefer to implement the alternate solution provided in the solutions file.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation ThreeQubitMeasurement (qs : Qubit[]) : Int {
    &lt;span style=&#34;color:#75715e&#34;&gt;// map the first state to 000 state and the second one to something orthogonal to it
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// (as described in reference solution)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    R1(-&lt;span style=&#34;color:#ae81ff&#34;&gt;2.0&lt;/span&gt; * PI() / &lt;span style=&#34;color:#ae81ff&#34;&gt;3.0&lt;/span&gt;, qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
    R1(-&lt;span style=&#34;color:#ae81ff&#34;&gt;4.0&lt;/span&gt; * PI() / &lt;span style=&#34;color:#ae81ff&#34;&gt;3.0&lt;/span&gt;, qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;]);
    Adjoint WState_Arbitrary_Reference(qs);

    &lt;span style=&#34;color:#75715e&#34;&gt;// measure all qubits: if all of them are 0, we have the first state,
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;// if at least one of them is 1, we have the second state
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; MeasureInteger(LittleEndian(qs)) == &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; ? &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; | &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;I decided to omit part two of this kata as a challenge to readers. Anywas, the descriptions given in the solution are far better than I could write.&lt;/p&gt;

&lt;p&gt;Again, thanks for reading and giving me feedback about my work 😄.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Quantum Katas #2: Superposition</title>
      <link>https://gideonwolfe.com/posts/quantum/superposition/</link>
      <pubDate>Wed, 28 Aug 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/quantum/superposition/</guid>
      <description>&lt;h1 id=&#34;intro&#34;&gt;Intro&lt;/h1&gt;

&lt;p&gt;If you read my last guide on &lt;a href=&#34;https://gideonwolfe.com/posts/quantum/basicgates/&#34;&gt;basic quantum gates&lt;/a&gt;, you are familiar with the concept of superposition.&lt;/p&gt;

&lt;p&gt;If not, let me briefly explain. A classical computer calculates on a system of binary &amp;quot;bits&amp;quot; that can either occupy the state &lt;span  class=&#34;math&#34;&gt;\(0\)&lt;/span&gt; or &lt;span  class=&#34;math&#34;&gt;\(1\)&lt;/span&gt;, on or off.&lt;/p&gt;

&lt;p&gt;A quantum computer on the other hand, uses qubits, or quantum bits which can occupy infinitely many states in between &lt;span  class=&#34;math&#34;&gt;\(0\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(1\)&lt;/span&gt;. When a qubit is in one of these &amp;quot;hybrid&amp;quot; states, we say that it is in &lt;code&gt;superposition&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Consider the Bloch sphere below, which provides a visual reference for the state of a qubit.&lt;/p&gt;


  &lt;img src=&#34;https://gideonwolfe.com/img/quantum/BlochSphereWhite2.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 50%; height: 50%;&#34;  /&gt;



&lt;p&gt;Like a classical bit, the qubit can take states &lt;span  class=&#34;math&#34;&gt;\(0\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(1\)&lt;/span&gt;, which are usually referred to as &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt; when describing qubits.&lt;/p&gt;

&lt;p&gt;We also see states &lt;span  class=&#34;math&#34;&gt;\(|+\rangle\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(|-\rangle\)&lt;/span&gt;, which represent a superposition halfway in between &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Finally we see the state vector &lt;span  class=&#34;math&#34;&gt;\(|\Psi\rangle\)&lt;/span&gt;, which can point to an arbitrary state on the surface of the bloch sphere. These arbitrary states are represented by angles &lt;span  class=&#34;math&#34;&gt;\(\theta\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(\phi\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;The following programming challenges will have you manipulate qubits into various states of superposition. If you have not set up a Q# development environment, I suggest you take a look at my &lt;a href=&#34;https://gideonwolfe.com/posts/quantum/basicgates/&#34;&gt;last post&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id=&#34;task-1-plus-state&#34;&gt;Task 1: Plus state&lt;/h1&gt;

&lt;p&gt;As input, we are given a qubit in the &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; state, and we need to output a qubit in the &lt;span  class=&#34;math&#34;&gt;\(|+\rangle\)&lt;/span&gt; state.&lt;/p&gt;

&lt;p&gt;Recall that the &lt;code&gt;Hadamard&lt;/code&gt; gate maps qubits like so:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\(|0\rangle \rightarrow |+\rangle\)&lt;/span&gt;
&lt;span  class=&#34;math&#34;&gt;\(|1\rangle \rightarrow |-\rangle\)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Since we are only given qubits in the &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; state, we can convert them to &lt;span  class=&#34;math&#34;&gt;\(|+\rangle\)&lt;/span&gt; by simply applying the &lt;code&gt;H()&lt;/code&gt; operation.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation PlusState (q : Qubit) : Unit {
    H(q);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-2-minus-state&#34;&gt;Task 2: Minus state&lt;/h1&gt;

&lt;p&gt;Like the previous task, we are given a qubit in the &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; state, but now we must map it to the &lt;span  class=&#34;math&#34;&gt;\(|-\rangle\)&lt;/span&gt; state.&lt;/p&gt;

&lt;p&gt;Looking at the mappings for the &lt;code&gt;Hadamard&lt;/code&gt; gate, we can see that applying &lt;code&gt;H()&lt;/code&gt; to a qubit in the &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt; state will result in the &lt;span  class=&#34;math&#34;&gt;\(|-\rangle\)&lt;/span&gt; state. We need to make use of the &lt;code&gt;Pauli X&lt;/code&gt; gate to turn our &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; states into &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation MinusState (q : Qubit) : Unit {
    X(q);    
    H(q);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-3-unequal-superposition&#34;&gt;Task 3: Unequal superposition&lt;/h1&gt;

&lt;p&gt;As I mentioned in the intro, the angles &lt;span  class=&#34;math&#34;&gt;\(\phi\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(\theta\)&lt;/span&gt; on the Bloch sphere translate into an arbitrary superposition.&lt;/p&gt;

&lt;p&gt;Let us consider the fact that we are trying to change the probability state of the qubit, which is represented by angle &lt;span  class=&#34;math&#34;&gt;\(\theta\)&lt;/span&gt; between the &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt; state and the state vector &lt;span  class=&#34;math&#34;&gt;\(|\Psi\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Here we are tasked with putting the qubit into a superposition given by the angle &lt;span  class=&#34;math&#34;&gt;\(\alpha\)&lt;/span&gt;.
A hint given in the comments reads:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Experiment with rotation gates from the Microsoft.Quantum.Intrinsic namespace.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since we know that the probability state can be changed by rotating our state vector about the &lt;span  class=&#34;math&#34;&gt;\(Y\)&lt;/span&gt; axis, we can leverage the &lt;code&gt;Ry()&lt;/code&gt; operation.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation UnequalSuperposition (q : Qubit, alpha : Double) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {        

    Ry(&lt;span style=&#34;color:#ae81ff&#34;&gt;2.0&lt;/span&gt; * alpha, q);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-4-superposition-of-all-basis-vectors-on-two-qubits&#34;&gt;Task 4: Superposition of all basis vectors on two qubits&lt;/h1&gt;

&lt;p&gt;We finally reached our first 2-qubit gate of this kata.&lt;/p&gt;

&lt;p&gt;Our goal is to take two qubits in state &lt;span  class=&#34;math&#34;&gt;\(|00\rangle\)&lt;/span&gt; and convert them into the state&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \frac{|00\rangle + |01\rangle + |10\rangle + |11\rangle }{2}\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Which is an equal probability of all possible outcomes of measurement.&lt;/p&gt;

&lt;p&gt;This state is also represented by the tensor product of the two states&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |+\rangle \otimes |+\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Since this superposition of qubits is represented by the tensor product of the qubits, we can simply use the &lt;code&gt;H()&lt;/code&gt; gate to change both our qubits to the &lt;span  class=&#34;math&#34;&gt;\(|+\rangle\)&lt;/span&gt; state.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation AllBasisVectors_TwoQubits (qs : Qubit[]) : Unit {
    H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
    H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-5-superposition-of-basis-vectors-with-phases&#34;&gt;Task 5: Superposition of basis vectors with phases&lt;/h1&gt;

&lt;p&gt;Our goal in this task is to take two qubits in the &lt;span  class=&#34;math&#34;&gt;\(|00\rangle\)&lt;/span&gt; state and convert them to the state&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \frac{|00\rangle + i|01\rangle - |10\rangle - i|11\rangle}{2} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;This is another example of a &lt;span  class=&#34;math&#34;&gt;\(n\)&lt;/span&gt; qubit state that can be broken down into the tensor product of &lt;span  class=&#34;math&#34;&gt;\(n\)&lt;/span&gt; discreet states. In this case, the state above can be rewritten as&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \frac{|0\rangle - |1\rangle}{\sqrt{2}} \otimes \frac{|0\rangle + i|1\rangle}{\sqrt{2}} = |-\rangle \otimes |i\rangle\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;We already know how to put our qubits in these states! Take another look at the Bloch sphere to orient yourself. We are aiming for the &lt;span  class=&#34;math&#34;&gt;\(|-\rangle\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(|i\rangle\)&lt;/span&gt; states, which both lie along the &lt;span  class=&#34;math&#34;&gt;\(XY\)&lt;/span&gt; plane.&lt;/p&gt;

&lt;p&gt;We can use the &lt;code&gt;Hadamard&lt;/code&gt; gate to move our state vector to the &lt;span  class=&#34;math&#34;&gt;\(|+\rangle\)&lt;/span&gt; state, and then use various rotations to get to the final states.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation AllBasisVectorsWithPhases_TwoQubits (qs : Qubit[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
            
        &lt;span style=&#34;color:#75715e&#34;&gt;// Qubit 0 is taken into |+⟩ and then z-rotated into |-⟩.
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
        Z(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
            
        &lt;span style=&#34;color:#75715e&#34;&gt;// Qubit 1 is taken into |+⟩ and then z-rotated into |i⟩.
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
        S(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-6-bell-state&#34;&gt;Task 6: Bell state&lt;/h1&gt;

&lt;p&gt;Again, we are getting an input of two qubits &lt;span  class=&#34;math&#34;&gt;\(|00\rangle\)&lt;/span&gt;. Our task is to create the bell state &lt;span  class=&#34;math&#34;&gt;\(|\Phi^+\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;If you need a refresher on Bell states, please refer to my last post, where I explain the concept in &lt;a href=&#34;https://gideonwolfe.com/posts/quantum/basicgates/#bell&#34;&gt;more detail&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For now, we can simply recall that the &lt;span  class=&#34;math&#34;&gt;\(|\Phi^+\rangle\)&lt;/span&gt; can be prepared by giving &lt;span  class=&#34;math&#34;&gt;\(|00\rangle\)&lt;/span&gt; as an input to the Bell preparation circuit &lt;span  class=&#34;math&#34;&gt;\(\beta\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |\beta_{00}\rangle \rightarrow |\Phi^+\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Since we are already given the qubits in state &lt;span  class=&#34;math&#34;&gt;\(|00\rangle\)&lt;/span&gt;, we can easily prepare the desired bell state.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation BellState (qs : Qubit[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {        
    H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
    CNOT(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;], qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-7-all-bell-states&#34;&gt;Task 7: All Bell states&lt;/h1&gt;

&lt;p&gt;Here the input is the same as the last few tasks. This time however, we are also given an &lt;code&gt;index&lt;/code&gt;, that corresponds to one of the four Bell states.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\( 0: |\Phi^+\rangle = \frac{|00\rangle + |11\rangle}{\sqrt{2}} \)&lt;/span&gt;
&lt;span  class=&#34;math&#34;&gt;\( 1: |\Phi^-\rangle = \frac{|00\rangle - |11\rangle}{\sqrt{2}} \)&lt;/span&gt;
&lt;span  class=&#34;math&#34;&gt;\( 2: |\Psi^+\rangle = \frac{|01\rangle + |10\rangle}{\sqrt{2}} \)&lt;/span&gt;
&lt;span  class=&#34;math&#34;&gt;\( 3: |\Psi^-\rangle = \frac{|01\rangle - |10\rangle}{\sqrt{2}} \)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;We are given an input of &lt;span  class=&#34;math&#34;&gt;\(|00\rangle\)&lt;/span&gt;, so unless the input is 0, we will have to alter our qubits after preparing a bell state.&lt;/p&gt;

&lt;p&gt;First let&#39;s consider the sign of the Bell state. If the index supplied is 1 or 3, it means we are preparing &lt;span  class=&#34;math&#34;&gt;\(|\Psi^-\rangle\)&lt;/span&gt; or &lt;span  class=&#34;math&#34;&gt;\(|\Phi^-\rangle\)&lt;/span&gt;. Since our input &lt;span  class=&#34;math&#34;&gt;\( |00\rangle\rightarrow |\Phi^+\rangle\)&lt;/span&gt;, we need to flip the sign.&lt;/p&gt;

&lt;p&gt;If you remember &lt;a href=&#34;https://gideonwolfe.com/posts/quantum/basicgates/#bellchange1&#34;&gt;task 1.7&lt;/a&gt; from my last post, this can be accomplished with the &lt;code&gt;Z()&lt;/code&gt; operation.&lt;/p&gt;

&lt;p&gt;The only thing left to check for now is if we need to go from &lt;span  class=&#34;math&#34;&gt;\(|\Phi^{\pm}\rangle\)&lt;/span&gt; to  &lt;span  class=&#34;math&#34;&gt;\(|\Psi^{\pm}\rangle\)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Fill in the operation like so to complete the task.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation AllBellStates (qs : Qubit[], index : Int) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
    
    H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
    CNOT(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;], qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
        
    &lt;span style=&#34;color:#75715e&#34;&gt;// now we have |00⟩ + |11⟩ - modify it based on index arg
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (index % &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; == &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
        &lt;span style=&#34;color:#75715e&#34;&gt;// negative phase
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        Z(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
    }
    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (index / &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; == &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
        X(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-8-greenbergerhornezeilinger-state&#34;&gt;Task 8: Greenberger–Horne–Zeilinger state&lt;/h1&gt;

&lt;p&gt;The Greenberger–Horne–Zeilinger state, or &lt;a href=&#34;https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state&#34;&gt;GHZ state&lt;/a&gt;, is a special, maximally entangled case of 3 or more qubits.&lt;/p&gt;

&lt;p&gt;It takes the following form:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ GHZ_n = \frac{ \overbrace{|0...0\rangle}^{n} + \overbrace{|1...1\rangle}^{n} }{\sqrt{2}} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;For example, a three qubit GHZ state is as follows&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ GHZ_3 = \frac{|000\rangle + |111\rangle}{\sqrt{2}} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The observant may notice the similarity to the two qubit Bell state &lt;span  class=&#34;math&#34;&gt;\(|\Phi^+\rangle\)&lt;/span&gt;. In fact, the GHZ state can be prepared in a similar way.&lt;/p&gt;

&lt;p&gt;Instead of preforming a &lt;code&gt;Controlled NOT&lt;/code&gt; with the only two qubits, we can use the first qubit as the control and &lt;code&gt;CNOT&lt;/code&gt; every additional qubit with it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation GHZ_State (qs : Qubit[]) : Unit {
    H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
    
    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt;(i &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; .. Length(qs) - &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;){
        CNOT(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;], qs[i]);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In &lt;code&gt;Q#&lt;/code&gt;, you can use the &lt;code&gt;Rest()&lt;/code&gt; operation, which creates a copy of the input list removing the first element. This is the method shown in the solution, but you will have to add&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;open Microsoft.Quantum.Arrays;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;to the top of your &lt;code&gt;Tasks.qs&lt;/code&gt; file.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation GHZ_State (qs : Qubit[]) : Unit {
    H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
    
    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt;(qubit &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; Rest(qs)){
        CNOT(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;], qubit);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-9-superposition-of-all-basis-vectors&#34;&gt;Task 9: Superposition of all basis vectors&lt;/h1&gt;

&lt;p&gt;In this task, we need to create an equal superposition of &lt;span  class=&#34;math&#34;&gt;\(n\)&lt;/span&gt; vectors. That will look like&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \overbrace{\frac{|0...0\rangle + ... + |1...1\rangle}{\sqrt{2^n}} }^{2^n \text{ permutations}} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ n =3 \rightarrow \frac{|000\rangle + |001\rangle + |010\rangle + |011\rangle + |100\rangle + |101\rangle + |110\rangle + |111\rangle}{\sqrt{2^3}} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;This can be achieved by simply applying the &lt;code&gt;Hadamard&lt;/code&gt; gate to every qubit. This is the same process we did for task 1.4, except with &lt;span  class=&#34;math&#34;&gt;\(n\)&lt;/span&gt; qubits.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation AllBasisVectorsSuperposition (qs : Qubit[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (q &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; qs) {
        H(q);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-10-00--01--10-state&#34;&gt;Task 10. |00⟩ + |01⟩ + |10⟩ state&lt;/h1&gt;

&lt;p&gt;Here we are tasked with putting two qubits into the state&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |\Psi\rangle = \frac{|00\rangle + |01\rangle + |10\rangle}{\sqrt{3}} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;This means our 2 qubit state has a &lt;span  class=&#34;math&#34;&gt;\(\frac{1}{3}\)&lt;/span&gt; chance of collapsing into each of the states &lt;span  class=&#34;math&#34;&gt;\(|00\rangle, |01\rangle, |10\rangle\)&lt;/span&gt;, with no chance of being in the state &lt;span  class=&#34;math&#34;&gt;\(|11\rangle\)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;I recommend taking a look at the stack exchange &lt;a href=&#34;https://quantumcomputing.stackexchange.com/questions/2310/how-can-i-build-a-circuit-to-generate-an-equal-superposition-of-3-outcomes-for-2/2313#2313&#34;&gt;solution&lt;/a&gt; for more detail, but I will explain briefly here.&lt;/p&gt;

&lt;p&gt;The first qubit in our input can be considered a control bit. For example, if our input is &lt;span  class=&#34;math&#34;&gt;\(|10\rangle\)&lt;/span&gt;, no action is needed and the state will measure &lt;span  class=&#34;math&#34;&gt;\(|10\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;If the first qubit is &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt;, we need to put our second qubit into the &lt;span  class=&#34;math&#34;&gt;\(|+\rangle\)&lt;/span&gt; state, which will give an equal probability  of measuring &lt;span  class=&#34;math&#34;&gt;\(|00\rangle\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(|01\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Now we can think of our qubit in the following form:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |\Psi\rangle = \frac{\sqrt{2}}{\sqrt{3}}|0\rangle|+\rangle + \frac{1}{\sqrt{3}}|1\rangle|0\rangle\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Which gives it a 66% chance of giving the plus state (which covers &lt;span  class=&#34;math&#34;&gt;\(|01\rangle\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(|00\rangle)\)&lt;/span&gt; and a 33% chance of going straight to &lt;span  class=&#34;math&#34;&gt;\(|10\rangle\)&lt;/span&gt;. This neatly gives us our &lt;span  class=&#34;math&#34;&gt;\(\frac{1}{3}\)&lt;/span&gt; chance of measuring any of the states.&lt;/p&gt;

&lt;p&gt;How do we replicate this probability with our qubits? Well we want our first qubit to be in the &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; state &lt;span  class=&#34;math&#34;&gt;\(\frac{2}{3}\)&lt;/span&gt; of the time, so we have to adjust our probability amplitude.&lt;/p&gt;

&lt;p&gt;Then for our conditional logic, we can use a &amp;quot;reverse controlled Hadamard&amp;quot;, which will put the second qubit in the &lt;span  class=&#34;math&#34;&gt;\(|+\rangle\)&lt;/span&gt; state if the first qubit is 0.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation ThreeStates_TwoQubits (qs : Qubit[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
    
    &lt;span style=&#34;color:#75715e&#34;&gt;// Follow Niel&amp;#39;s answer at https://quantumcomputing.stackexchange.com/a/2313/
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        
    &lt;span style=&#34;color:#75715e&#34;&gt;// Rotate first qubit to (sqrt(2) |0⟩ + |1⟩) / sqrt(3) (task 1.4 from BasicGates kata)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; theta = ArcSin(&lt;span style=&#34;color:#ae81ff&#34;&gt;1.0&lt;/span&gt; / Sqrt(&lt;span style=&#34;color:#ae81ff&#34;&gt;3.0&lt;/span&gt;));
    Ry(&lt;span style=&#34;color:#ae81ff&#34;&gt;2.0&lt;/span&gt; * theta, qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
        
    &lt;span style=&#34;color:#75715e&#34;&gt;// Split the state sqrt(2) |0⟩ ⊗ |0⟩ into |00⟩ + |01⟩
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    (ControlledOnInt(&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, H))([qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]], qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-11-superposition-of-00-and-given-bit-string&#34;&gt;Task 11: Superposition of |0...0⟩ and given bit string&lt;/h1&gt;

&lt;p&gt;In this task, we must create a superposition of &lt;span  class=&#34;math&#34;&gt;\(|0...0\rangle\)&lt;/span&gt; and an input given by a bit string.&lt;/p&gt;

&lt;p&gt;The bit string:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Has the same length as the qubit register&lt;/li&gt;
&lt;li&gt;Is guaranteed to start with a &lt;code&gt;1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, if the bit string was &lt;code&gt;[true, false]&lt;/code&gt;, the state we want to create would be&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \frac{|00\rangle + |10\rangle}{\sqrt{2}} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Here is a circuit that illustrates this on the input &lt;code&gt;[true, false, true]&lt;/code&gt;.&lt;/p&gt;


  &lt;img src=&#34;https://gideonwolfe.com/img/quantum/BitString1.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 70%; height: 70%;&#34;  /&gt;



&lt;p&gt;We apply the &lt;code&gt;Hadamard&lt;/code&gt; gate to the first qubit, starting the superposition. For each following qubit, the &lt;code&gt;CNOT&lt;/code&gt; gate is applied if the corresponding entry in the bit string is &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The first qubit has a 50%  chance of being &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; or &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt;. If it is zero, no more operations are applied, so the state &lt;span  class=&#34;math&#34;&gt;\(|000\rangle\)&lt;/span&gt; is measured.&lt;/p&gt;

&lt;p&gt;If the state of the first qubit (&lt;code&gt;qs[0]&lt;/code&gt;) is one, all possible states that start with &lt;span  class=&#34;math&#34;&gt;\(|0..\rangle\)&lt;/span&gt; are no longer possible.&lt;/p&gt;

&lt;p&gt;In our above example, the second bit was false, meaning it will never get a &lt;code&gt;NOT&lt;/code&gt; and will remain &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt;. Hence, any state &lt;span  class=&#34;math&#34;&gt;\(|.1.\rangle\)&lt;/span&gt; with &lt;code&gt;1&lt;/code&gt; in the middle are not possible.&lt;/p&gt;

&lt;p&gt;Similarly, a measurement of &lt;span  class=&#34;math&#34;&gt;\(|100\rangle\)&lt;/span&gt; would be impossible since if the first qubit was &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt;, the third qubit would have the &lt;code&gt;NOT&lt;/code&gt; gate applied.&lt;/p&gt;

&lt;p&gt;After eliminating the impossible measurements, the probability matrix gives us an equally probable output of &lt;span  class=&#34;math&#34;&gt;\(|000\rangle\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(|101\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Here I used the &lt;code&gt;Length()&lt;/code&gt; function in a ranged &lt;code&gt;for&lt;/code&gt; loop to check the value of the &lt;span  class=&#34;math&#34;&gt;\(i^{th}\)&lt;/span&gt; bit in the input and apply &lt;code&gt;CNOT&lt;/code&gt; accordingly.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation ZeroAndBitstringSuperposition(qs : Qubit[], bits : Bool[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj{
        
    &lt;span style=&#34;color:#75715e&#34;&gt;// Hadamard first qubit
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    H(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
        
    &lt;span style=&#34;color:#75715e&#34;&gt;// iterate through the bit string and CNOT to qubits corresponding to true bits
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; .. Length(qs) - &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (bits[i]) {
            CNOT(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;], qs[i]);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-12-superposition-of-two-bit-strings&#34;&gt;Task 12: Superposition of two bit strings&lt;/h1&gt;

&lt;p&gt;In this task, we are given two arbitrary bit strings of length &lt;span  class=&#34;math&#34;&gt;\(n\)&lt;/span&gt;. For example if we had two input strings &lt;code&gt;[false, true, false]&lt;/code&gt; and &lt;code&gt;[false, false, true]&lt;/code&gt;, we would create an equal superposition of like this:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \frac{|010\rangle + |001\rangle}{\sqrt{2}} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The first step in completing this task is to find the spot where the two bitstrings &amp;quot;diverge&amp;quot;.&lt;/p&gt;

&lt;p&gt;By putting this bit into superposition, we splits our state into two distinct possible outcomes. Here is a helper function that returns the index of the first differing qubit:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;function FindFirstDiff (bits1 : Bool[], bits2 : Bool[]) : Int {
    mutable firstDiff = -&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; .. Length(bits1) - &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (bits1[i] != bits2[i] and firstDiff == -&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
            &lt;span style=&#34;color:#66d9ef&#34;&gt;set&lt;/span&gt; firstDiff = i;
        }
    }
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; firstDiff;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once we found where the strings diverge, we can apply the &lt;code&gt;H()&lt;/code&gt; gate to it to create superposition. Next, we have to iterate through our bitstrings and put the qubits in their final state.&lt;/p&gt;

&lt;p&gt;If the bit in both strings at index &lt;span  class=&#34;math&#34;&gt;\(i\)&lt;/span&gt; are the same, we have two possibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They are both &lt;code&gt;false&lt;/code&gt;, meaning no action is needed.&lt;/li&gt;
&lt;li&gt;They are both &lt;code&gt;true&lt;/code&gt;, and we need to &lt;code&gt;NOT&lt;/code&gt; our qubit register at index &lt;span  class=&#34;math&#34;&gt;\(i\)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the bit in both strings at index &lt;span  class=&#34;math&#34;&gt;\(i\)&lt;/span&gt; are different, we use the first different bit as a control, and &lt;code&gt;CNOT&lt;/code&gt; the qubit at index &lt;span  class=&#34;math&#34;&gt;\(i\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;If the first differing qubit measures as &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt;, then the &lt;span  class=&#34;math&#34;&gt;\(i^{th}\)&lt;/span&gt; qubit is flipped to &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Then, if the first bitstring at index &lt;span  class=&#34;math&#34;&gt;\(i\)&lt;/span&gt; is not equal to the value of the first different bit from the first string, we &lt;code&gt;NOT&lt;/code&gt; the qubit at index &lt;span  class=&#34;math&#34;&gt;\(i\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;The pseudocode above can be realized with the following operation:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation TwoBitstringSuperposition (qs : Qubit[], bits1 : Bool[], bits2 : Bool[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
    
    &lt;span style=&#34;color:#75715e&#34;&gt;// find the index of the first bit at which the bit strings are different
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; firstDiff = FindFirstDiff (bits1, bits2);
        
    &lt;span style=&#34;color:#75715e&#34;&gt;// Hadamard corresponding qubit to create superposition
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    H(qs[firstDiff]);
        
    &lt;span style=&#34;color:#75715e&#34;&gt;// iterate through the bit strings again setting the final state of qubits
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; .. Length(qs) - &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (bits1[i] == bits2[i]) {
            &lt;span style=&#34;color:#75715e&#34;&gt;// if two bits are the same apply X or nothing
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (bits1[i]) {
                X(qs[i]);
            }
        } &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
            &lt;span style=&#34;color:#75715e&#34;&gt;// if two bits are different, set their difference using CNOT
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (i &amp;gt; firstDiff) {
                CNOT(qs[firstDiff], qs[i]);
                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (bits1[i] != bits1[firstDiff]) {
                    X(qs[i]);
                }
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-13-superposition-of-four-bit-strings&#34;&gt;Task 13: Superposition of four bit strings&lt;/h1&gt;

&lt;p&gt;This task is like the one above, except we must deal with 4 bitstrings, with &lt;span  class=&#34;math&#34;&gt;\(N\)&lt;/span&gt; elements each.&lt;/p&gt;

&lt;p&gt;Elements can be accessed like &lt;code&gt;bits[i][j]&lt;/code&gt; where &lt;span  class=&#34;math&#34;&gt;\(0 \lt i \lt 3\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(0 \lt j \lt N - 1 \)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;First we can use the &lt;code&gt;ApplyToEach()&lt;/code&gt; function to apply the &lt;code&gt;Hadamard&lt;/code&gt; gate to each of the ancilla qubits to put them in the &lt;span  class=&#34;math&#34;&gt;\(|+\rangle\)&lt;/span&gt; state.&lt;/p&gt;

&lt;p&gt;Then we iterate through the rows and columns of our 2D array, touching each qubit. If &lt;code&gt;bits[i][j]&lt;/code&gt; is true, we preform the following operation: &lt;code&gt;(ControlledOnInt(i, X))(anc, qs[j]);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then we have to iterate through each bitstring. If we are on &lt;code&gt;bits[i]&lt;/code&gt; and &lt;span  class=&#34;math&#34;&gt;\(i\)&lt;/span&gt; is odd, we do&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(ControlledOnBitString(bits[i], X))(qs, anc[0]);&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If it&#39;s even, we do&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(ControlledOnBitString(bits[i], X))(qs, anc[1]);&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here is the implementation.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation FourBitstringSuperposition (qs : Qubit[], bits : Bool[][]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
    &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; N = Length(qs);
        
    &lt;span style=&#34;color:#66d9ef&#34;&gt;using&lt;/span&gt; (anc = Qubit[&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;]) {
        &lt;span style=&#34;color:#75715e&#34;&gt;// Put two ancillas into equal superposition of 2-qubit basis states
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        ApplyToEachA(H, anc);
            
        &lt;span style=&#34;color:#75715e&#34;&gt;// Set up the right pattern on the main qubits with control on ancillas
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; .. &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;) {
            &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (j &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; .. N - &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; ((bits[i])[j]) {
                    (ControlledOnInt(i, X))(anc, qs[j]);
                }
            }
        }
            
        &lt;span style=&#34;color:#75715e&#34;&gt;// Uncompute the ancillas, using patterns on main qubits as control
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; .. &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;) {
            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (i % &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; == &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
                (ControlledOnBitString(bits[i], X))(qs, anc[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
            }
            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (i / &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; == &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
                (ControlledOnBitString(bits[i], X))(qs, anc[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-14-w-state-on-2ᵏ-qubits&#34;&gt;Task 14: W state on 2ᵏ qubits&lt;/h1&gt;

&lt;p&gt;A W state is a state of &lt;span  class=&#34;math&#34;&gt;\(N\)&lt;/span&gt; qubits that takes the following form:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |W_N\rangle = \frac{\overbrace{|100...0\rangle + |010...0\rangle + ... + |00..01\rangle}^{N \text{ states}}}{\sqrt{N}} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;In this task, we are challenged with creating the state &lt;span  class=&#34;math&#34;&gt;\(|W_N\rangle\)&lt;/span&gt; where &lt;span  class=&#34;math&#34;&gt;\(N = 2^k\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;We will implement a recursive operation to create the &lt;span  class=&#34;math&#34;&gt;\(W\)&lt;/span&gt; state.&lt;/p&gt;

&lt;p&gt;In this operation, our base case is when &lt;span  class=&#34;math&#34;&gt;\(N = 1\)&lt;/span&gt;, where the &lt;span  class=&#34;math&#34;&gt;\(W\)&lt;/span&gt; state is trivially prepared. If we are in this state, we can apply &lt;code&gt;X(qs[0])&lt;/code&gt; and return.&lt;/p&gt;

&lt;p&gt;If not, we must preform the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create new variable &lt;span  class=&#34;math&#34;&gt;\(K = \frac{N}{2} \)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Recursively call the function passing it &lt;code&gt;qs[0 .. K - 1]&lt;/code&gt; as input&lt;/li&gt;
&lt;li&gt;Create an ancilla qubit and apply &lt;code&gt;H()&lt;/code&gt; to it&lt;/li&gt;
&lt;li&gt;For every qubit from 0 to K - 1, do a controlled swap using the ancilla, &lt;code&gt;qs[i]&lt;/code&gt;, and &lt;code&gt;qs[i + K]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;For every qubit from 0 to N - 1, preform a &lt;code&gt;CNOT&lt;/code&gt; with &lt;code&gt;qs[i]&lt;/code&gt; and the ancilla.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation WState_PowerOfTwo (qs : Qubit[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
        
        &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; N = Length(qs);
            
        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (N == &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
            &lt;span style=&#34;color:#75715e&#34;&gt;// base of recursion: |1⟩
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;            X(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
        } 

        &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
            &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; K = N / &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;;
                
            &lt;span style=&#34;color:#75715e&#34;&gt;// create W state on the first K qubits
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;            WState_PowerOfTwo (qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; .. K - &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
                
            &lt;span style=&#34;color:#75715e&#34;&gt;// the next K qubits are in |0...0⟩ state
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#75715e&#34;&gt;// allocate ancilla in |+⟩ state
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;using&lt;/span&gt; (anc = Qubit()) {
                H(anc);
                    
                &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; .. K - &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
                    Controlled SWAP([anc], (qs[i], qs[i + K]));
                }
                &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; (i &lt;span style=&#34;color:#66d9ef&#34;&gt;in&lt;/span&gt; K .. N - &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
                    CNOT(qs[i], anc);
                }
            }
        }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-15-w-state-on-arbitrary-number-of-qubits&#34;&gt;Task 15: W state on arbitrary number of qubits&lt;/h1&gt;

&lt;p&gt;Our task here is the same as in the previous, except now we cannot assume that &lt;span  class=&#34;math&#34;&gt;\(N = 2^k\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;Again, we find the length of are qubit register using the &lt;code&gt;Length()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Our base case for this recursive function is when &lt;span  class=&#34;math&#34;&gt;\(N = 1\)&lt;/span&gt;, where we can again preform &lt;code&gt;X(qs[0])&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we aren&#39;t at the base case, we want to preform a rotation on the first qubit to put it into the following state:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \sqrt{\frac{N-1}{N}}|0\rangle + \frac{1}{\sqrt{N}}|1\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;We can accomplish this with an &lt;code&gt;Ry()&lt;/code&gt; operation on the first qubit, rotating by &lt;span  class=&#34;math&#34;&gt;\(2\theta\)&lt;/span&gt;, where&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \theta = sin^{-1}\left(\frac{1}{\sqrt{N}}\right) \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Then we preform a zero controlled recursive call of the same function. A zero controlled gate can be preformed by applying a standard controlled gate to a qubit who&#39;s state has been flipped.&lt;/p&gt;

&lt;p&gt;This recursive loop will continue until we are at the base state, and where we will preform &lt;code&gt;X(qs[0])&lt;/code&gt; and reach our target state.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation WState_Arbitrary (qs : Qubit[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj + Ctl {
    
    &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; N = Length(qs);
        
    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (N == &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
        &lt;span style=&#34;color:#75715e&#34;&gt;// base case of recursion: |1⟩
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        X(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
    } 

    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; {
        &lt;span style=&#34;color:#75715e&#34;&gt;// |W_N⟩ = |0⟩|W_(N-1)⟩ + |1⟩|0...0⟩
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;// do a rotation on the first qubit to split it into |0⟩ and |1⟩ with proper weights
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#75715e&#34;&gt;// |0⟩ -&amp;gt; sqrt((N-1)/N) |0⟩ + 1/sqrt(N) |1⟩
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; theta = ArcSin(&lt;span style=&#34;color:#ae81ff&#34;&gt;1.0&lt;/span&gt; / Sqrt(IntAsDouble(N)));
        Ry(&lt;span style=&#34;color:#ae81ff&#34;&gt;2.0&lt;/span&gt; * theta, qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
            
        &lt;span style=&#34;color:#75715e&#34;&gt;// do a zero-controlled W-state generation for qubits 1..N-1
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;        X(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
        Controlled WState_Arbitrary (qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; .. &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;], qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; .. N - &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
        X(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;In this kata, we learned about the various special states and properties of quantum  superposition, as well as some nontrivial implementations of these states with Q#.&lt;/p&gt;

&lt;p&gt;As always, feel free to reach out with questions or feedback 😄&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Quantum Katas #1: Basic Quantum Gates</title>
      <link>https://gideonwolfe.com/posts/quantum/basicgates/</link>
      <pubDate>Wed, 21 Aug 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/quantum/basicgates/</guid>
      <description>&lt;p&gt;I have been fascinated with quantum computing since the day I learned of its existence.&lt;/p&gt;

&lt;p&gt;I picked up the Microsoft &lt;a href=&#34;https://www.microsoft.com/en-us/quantum/development-kit&#34;&gt;Quantum Development Kit&lt;/a&gt; as soon as it was released, but being far from a quantum physicist, I was understandably lost.&lt;/p&gt;

&lt;p&gt;Since then, I have done a fair bit of research on the subject, and Microsoft has released a set of tutorials called &lt;a href=&#34;https://github.com/Microsoft/QuantumKatas&#34;&gt;Quantum Katas&lt;/a&gt; to help developers get their feet wet in the world of quantum computing.&lt;/p&gt;

&lt;p&gt;Using these Katas, I hope to introduce you to some fundamental concepts in quantum computing and quantum mechanics.&lt;/p&gt;

&lt;h1 id=&#34;getting-ready-to-write-quantum-code&#34;&gt;Getting ready to write quantum code&lt;/h1&gt;

&lt;p&gt;In order to work with Quantum programs, you need to have your quantum development environment set up. This is as easy as installing Visual Studio or VS Code and installing the Microsoft Quantum Development Kit extension with the included extension manager.&lt;/p&gt;

&lt;p&gt;In addition to this, you will need to have the dotnet runtime and development kit available to your system. On Arch Linux, this can be accomplished with&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo pacman -Syu dotnet-runtime dotnet-sdk code&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If everything went well, you should be able to run the quantum examples that come with the QDK.&lt;/p&gt;

&lt;h1 id=&#34;getting-the-katas&#34;&gt;Getting the Katas&lt;/h1&gt;

&lt;p&gt;The Katas can be acquired from their github &lt;a href=&#34;https://github.com/Microsoft/QuantumKatas&#34;&gt;repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Usually I would do my development in Neovim, but I opted to stick with VS Code for this project because it is better integrated with the language (also being a Microsoft product). Syntax highlighting and other hints are nice to have when working with an unfamiliar language.&lt;/p&gt;

&lt;p&gt;The Katas assume a test driven workflow, so you can track your progress through each tutorial. In the &lt;code&gt;BasicGates&lt;/code&gt; folder, run the &lt;code&gt;dotnet test&lt;/code&gt; command to run the &lt;code&gt;Tests.qs&lt;/code&gt; file and test your solutions.&lt;/p&gt;

&lt;p&gt;Before starting this guide, I recommend checking Microsoft&#39;s readings on &lt;a href=&#34;https://docs.microsoft.com/en-us/quantum/concepts/the-qubit?view=qsharp-preview&#34;&gt;the qubit&lt;/a&gt;, which goes over some of the mathematical and visual representations I will be using in this tutorial.&lt;/p&gt;

&lt;h1 id=&#34;task-11-state-flip&#34;&gt;Task 1.1: State flip&lt;/h1&gt;

&lt;p&gt;This is possibly the most basic quantum gate, with a counterpart in classical computation. Analogous to the classical &lt;strong&gt;NOT&lt;/strong&gt; gate, the &lt;strong&gt;Pauli X&lt;/strong&gt; gate takes a single qubit and flips its state.&lt;/p&gt;

&lt;p&gt;That is, a qubit in state &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; will be flipped to state &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt; and vice versa. This operation can be represented with the following linear transformations.&lt;/p&gt;

&lt;div&gt;
$$   \begin{bmatrix}
0 &amp; 1 \\
1 &amp; 0
\end{bmatrix} 
\cdot
\begin{bmatrix}
1  \\
0 
\end{bmatrix}
= 
\begin{bmatrix}
0  \\
1 
\end{bmatrix}
 $$
&lt;/div&gt;

&lt;div&gt;
$$   \begin{bmatrix}
0 &amp; 1 \\
1 &amp; 0
\end{bmatrix} 
\cdot
\begin{bmatrix}
0  \\
1 
\end{bmatrix}
= 
\begin{bmatrix}
1  \\
0 
\end{bmatrix}
 $$
&lt;/div&gt;

&lt;p&gt;To generalize, the effect of the &lt;span  class=&#34;math&#34;&gt;\(X\)&lt;/span&gt; gate on an arbitrary qubit is as follows:&lt;/p&gt;

&lt;div&gt;
$$   \begin{bmatrix}
0 &amp; 1 \\
1 &amp; 0
\end{bmatrix} 
\cdot
\begin{bmatrix}
\alpha  \\
\beta 
\end{bmatrix}
= 
\begin{bmatrix}
\beta  \\
\alpha 
\end{bmatrix}
 $$
&lt;/div&gt;

&lt;p&gt;Where &lt;span  class=&#34;math&#34;&gt;\(\alpha\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(\beta\)&lt;/span&gt; are complex numbers that represent the probability of measuring the qubit in state &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt; respectively.
Simply fill the code in like so to complete this task.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation StateFlip (q : Qubit) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
    X(q);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Quantum gates have the unique property of being reversible. For every unitary transformation &lt;span  class=&#34;math&#34;&gt;\( U \)&lt;/span&gt;, there exists an adjoint transformation &lt;span  class=&#34;math&#34;&gt;\( U^\dagger \)&lt;/span&gt; that reverses the operation, such that&lt;/p&gt;

&lt;div&gt;
$$
U^\dagger
\cdot
U
= 
\begin{bmatrix}
1 &amp; 0  \\
0 &amp; 1
\end{bmatrix}
 $$
&lt;/div&gt;

&lt;p&gt;Like the classical NOT gate, the Pauli X gate has the property of being self-adjoint, meaning it is its own inverse. Applying the operation twice will result in the initial state. Multiple quantum operations can be represented as the matrix product of all the transformations.&lt;/p&gt;

&lt;div&gt;
$$   \begin{bmatrix}
0 &amp; 1 \\
1 &amp; 0
\end{bmatrix} 
\cdot
\begin{bmatrix}
0 &amp; 1 \\
1 &amp; 0
\end{bmatrix}
= 
\begin{bmatrix}
1 &amp; 0 \\
0 &amp; 1
\end{bmatrix}
 $$
&lt;/div&gt;

&lt;p&gt;Here we can see applying the X gate twice results in the identity matrix, meaning no transformation occurred.&lt;/p&gt;

&lt;h1 id=&#34;task-12-basis-change&#34;&gt;Task 1.2: Basis change&lt;/h1&gt;

&lt;p&gt;This is the first truly quantum gate we have encountered in this tutorial. This task requires the use of the &lt;strong&gt;Hadamard&lt;/strong&gt; gate, which can be represented by the following unitary matrix.&lt;/p&gt;

&lt;div&gt;
$$
H = 
\frac{1}{\sqrt{2}}
\begin{bmatrix}
1 &amp; 1 \\
1 &amp; -1
\end{bmatrix} 
 $$
&lt;/div&gt;

&lt;p&gt;In &lt;a href=&#34;https://en.wikipedia.org/wiki/Bra%E2%80%93ket_notation&#34;&gt;ket notation&lt;/a&gt;, the Hadamard gate looks like this.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ H(|0\rangle) = \frac{|0\rangle + |1\rangle}{\sqrt{2}} = |+\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ H(|1\rangle) = \frac{|0\rangle - |1\rangle}{\sqrt{2}} = |-\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;And in matrix notation&lt;/p&gt;

&lt;div&gt;
$$
H(|0\rangle) = 
\frac{1}{\sqrt{2}}
\begin{bmatrix}
1 &amp; 1 \\
1 &amp; -1
\end{bmatrix} 
\cdot
\begin{bmatrix}
1 \\
0
\end{bmatrix}
=
\frac{1}{\sqrt{2}}
\begin{bmatrix}
1 \\
1
\end{bmatrix}
=
\frac{|0\rangle + |1\rangle}{\sqrt{2}}
$$
&lt;/div&gt;
&lt;div&gt;
$$
H(|1\rangle) = 
\frac{1}{\sqrt{2}}
\begin{bmatrix}
1 &amp; 1 \\
1 &amp; -1
\end{bmatrix} 
\cdot
\begin{bmatrix}
0 \\
1
\end{bmatrix}
=
\frac{1}{\sqrt{2}}
\begin{bmatrix}
1 \\
-1
\end{bmatrix}
=
\frac{|0\rangle - |1\rangle}{\sqrt{2}}
$$
&lt;/div&gt;

&lt;p&gt;This transformation takes the qubit from the computational basis &lt;span  class=&#34;math&#34;&gt;\((|0\rangle |1\rangle)\)&lt;/span&gt; to the polar basis &lt;span  class=&#34;math&#34;&gt;\((|+\rangle |-\rangle)\)&lt;/span&gt;.
To see the effect on the state of a qubit, let us consider the following qubit state&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[|\Psi \rangle = \alpha |0\rangle + \beta |1\rangle\]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;where &lt;span  class=&#34;math&#34;&gt;\(\alpha\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(\beta\)&lt;/span&gt; again represent the normalized &lt;a href=&#34;https://en.wikipedia.org/wiki/Probability_amplitude&#34;&gt;probability amplitudes&lt;/a&gt; of the quantum state. By applying the Hadamard gate to this state, we can reduce the quantum state like so.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[H(|\Psi \rangle) = H(\alpha |0\rangle + \beta |1\rangle) =
\alpha \left(\frac{|0\rangle + |1\rangle}{\sqrt{2}}\right) + 
\beta \left(\frac{|0\rangle - |1\rangle}{\sqrt{2}}\right) = 
\frac{\alpha + \beta}{\sqrt{2}}|0\rangle + \frac{\alpha - \beta}{\sqrt{2}}|1\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;This transformation alters the probability amplitudes of the state. Like the X gate, the Hadamard gate is self adjoint.&lt;/p&gt;

&lt;p&gt;To complete task two, fill in the operation like so&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation BasisChange (q : Qubit) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
    H(q);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-13-sign-flip&#34;&gt;Task 1.3: Sign flip&lt;/h1&gt;

&lt;p&gt;The objective in this task is to take a qubit in the &lt;span  class=&#34;math&#34;&gt;\(|+\rangle\)&lt;/span&gt; state and flip it to &lt;span  class=&#34;math&#34;&gt;\(|-\rangle\)&lt;/span&gt;, and vice versa.&lt;/p&gt;

&lt;p&gt;By looking at the &lt;a href=&#34;https://en.wikipedia.org/wiki/Bloch_sphere&#34;&gt;Bloch sphere&lt;/a&gt;, we can see that the state &lt;span  class=&#34;math&#34;&gt;\(|+\rangle\)&lt;/span&gt; or &lt;span  class=&#34;math&#34;&gt;\(\frac{|0\rangle + |1\rangle}{\sqrt{2}}\)&lt;/span&gt; is represented by a vector pointing directly along the x axis in the positive direction. To negate this, we must make our quantum state vector point along the x axis in the negative direction.&lt;/p&gt;


  &lt;img src=&#34;https://gideonwolfe.com/img/quantum/BlochSphereWhite2.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;



&lt;p&gt;This can be accomplished by rotating out vector &lt;span  class=&#34;math&#34;&gt;\(\pi\)&lt;/span&gt; radians or &lt;span  class=&#34;math&#34;&gt;\(180^\circ\)&lt;/span&gt; about the &lt;span  class=&#34;math&#34;&gt;\(Z\)&lt;/span&gt; axis. Like the Pauli X gate rotated our state vector about the &lt;span  class=&#34;math&#34;&gt;\(X\)&lt;/span&gt; axis, the &lt;strong&gt;Pauli Z&lt;/strong&gt; gate will rotate our vector about the &lt;span  class=&#34;math&#34;&gt;\(Z\)&lt;/span&gt; axis.&lt;/p&gt;

&lt;p&gt;Like all of the Pauli gates, Pauli Z is self adjoint.&lt;/p&gt;

&lt;p&gt;The effect of this quantum gate looks like this:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ Z(|\Psi\rangle) = Z(\alpha|0\rangle + \beta|1\rangle) = \alpha|0\rangle - \beta|1\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Although &lt;span  class=&#34;math&#34;&gt;\(\beta \rightarrow -\beta\)&lt;/span&gt;, &lt;span  class=&#34;math&#34;&gt;\(|-\beta|^2 + |\alpha|^2 = 1\)&lt;/span&gt; so normalization holds.&lt;/p&gt;

&lt;p&gt;Fill in the operation like so to complete the task.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation SignFlip (q : Qubit) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
    Z(q);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-14-amplitude-change&#34;&gt;Task 1.4: Amplitude change&lt;/h1&gt;

&lt;p&gt;In this section, our task is to change the amplitude of our qubit.&lt;/p&gt;

&lt;p&gt;Looking at the Bloch sphere, we see that amplitude is represented by the angle &lt;span  class=&#34;math&#34;&gt;\(\theta\)&lt;/span&gt;, the angle measured between our state vector &lt;span  class=&#34;math&#34;&gt;\(\Psi\)&lt;/span&gt; and the &lt;span  class=&#34;math&#34;&gt;\(Z\)&lt;/span&gt; axis.&lt;/p&gt;

&lt;p&gt;To change this angle, we must rotate out state vector about the &lt;span  class=&#34;math&#34;&gt;\(Y\)&lt;/span&gt; axis. Looking at the &lt;a href=&#34;https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.ry?view=qsharp-preview&#34;&gt;documentation&lt;/a&gt; on the &lt;span  class=&#34;math&#34;&gt;\(R_y\)&lt;/span&gt; operation, we can see it takes the form of the following unitary matrix.&lt;/p&gt;

&lt;div&gt;
$$
\begin{bmatrix}
cos \frac{\theta}{2} &amp; -sin \frac{\theta}{2}\\
sin \frac{\theta}{2} &amp; cos \frac{\theta}{2}\\
\end{bmatrix}
$$
&lt;/div&gt;

&lt;p&gt;The comments above this task provide the following hints:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;If the qubit is in state |0⟩, change its state to cos(alpha)*|0⟩ + sin(alpha)*|1⟩. 
If the qubit is in state |1⟩, change its state to -sin(alpha)*|0⟩ + cos(alpha)*|1⟩. 
If the qubit is in superposition, change its state according to the effect on basis vectors. &lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation AmplitudeChange (alpha : Double, q : Qubit) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj+Ctl {
    Ry(&lt;span style=&#34;color:#ae81ff&#34;&gt;2.0&lt;/span&gt; * alpha, q);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-15-phase-flip&#34;&gt;Task 1.5: Phase Flip&lt;/h1&gt;

&lt;p&gt;Our goal in this task is to take a qubit in the state &lt;span  class=&#34;math&#34;&gt;\(|\Psi\rangle = \alpha|0\rangle + \beta|1\rangle\)&lt;/span&gt; and change it to state &lt;span  class=&#34;math&#34;&gt;\(|\Psi\rangle = \alpha|0\rangle + i\beta|1\rangle\)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;On the Bloch sphere, this would map our qubit&#39;s state from &lt;span  class=&#34;math&#34;&gt;\(|X\rangle\)&lt;/span&gt; to &lt;span  class=&#34;math&#34;&gt;\(|Y\rangle\)&lt;/span&gt;, introducing an imaginary component to our &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt; term.&lt;/p&gt;

&lt;p&gt;The perceptive may have noticed that this is simply a rotation about the &lt;span  class=&#34;math&#34;&gt;\(Z\)&lt;/span&gt; axis by &lt;span  class=&#34;math&#34;&gt;\(90^\circ\)&lt;/span&gt; or &lt;span  class=&#34;math&#34;&gt;\(\frac{\pi}{2}\)&lt;/span&gt; radians. In fact, &lt;a href=&#34;https://www.quantum-inspire.com/kbase/s-gate/&#34;&gt;Quantum Inspire&lt;/a&gt;&#39;s page about the S gate explicitly says&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The S gate is also known as the phase gate or the Z90 gate, because it represents a 90 degree rotation around the z-axis.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In physical terms, this changes the angle &lt;span  class=&#34;math&#34;&gt;\(\Phi\)&lt;/span&gt; without altering &lt;span  class=&#34;math&#34;&gt;\(\theta\)&lt;/span&gt;, the angle between the vector and the &lt;span  class=&#34;math&#34;&gt;\(Z\)&lt;/span&gt; axis.&lt;/p&gt;

&lt;p&gt;In mathematical terms, we introduce an imaginary element into our &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; component.&lt;/p&gt;

&lt;div&gt;
$$
\begin{bmatrix}
\frac{1}{\sqrt{2}} \\
\frac{1}{\sqrt{2}}
\end{bmatrix}
\rightarrow
\begin{bmatrix}
\frac{1}{\sqrt{2}} \\
\frac{i}{\sqrt{2}}
\end{bmatrix}
$$
&lt;/div&gt;

&lt;p&gt;The &lt;span  class=&#34;math&#34;&gt;\(S\)&lt;/span&gt; gate can be represented by the following matrix:&lt;/p&gt;

&lt;div&gt;
$$
S =
\begin{bmatrix}
1 &amp; 0\\
0 &amp; i
\end{bmatrix}
$$
&lt;/div&gt;

&lt;p&gt;Fill in the following code to complete the operation:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation PhaseFlip (q : Qubit) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj+Ctl {
    S(q);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-16-phase-change&#34;&gt;Task 1.6: Phase change&lt;/h1&gt;

&lt;p&gt;Let us remember that the phase of a qubit is represented by the angle &lt;span  class=&#34;math&#34;&gt;\(\Phi\)&lt;/span&gt; on the bloch sphere. This is the angle made between the &lt;span  class=&#34;math&#34;&gt;\(X\)&lt;/span&gt; axis and the projection of our state vector on the &lt;span  class=&#34;math&#34;&gt;\(XY\)&lt;/span&gt; plane.&lt;/p&gt;

&lt;p&gt;To alter this angle, we must rotate our state vector about the &lt;span  class=&#34;math&#34;&gt;\(Z\)&lt;/span&gt; axis by &lt;span  class=&#34;math&#34;&gt;\(\alpha\)&lt;/span&gt; degrees.&lt;/p&gt;

&lt;p&gt;Using the knowledge we have gained so far, one might assume the &lt;span  class=&#34;math&#34;&gt;\(\sigma_z\)&lt;/span&gt; or &lt;span  class=&#34;math&#34;&gt;\(Z\)&lt;/span&gt; rotation gate could accomplish this. However, the following snippet will result in the test failing.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation PhaseChange (alpha : Double, q : Qubit) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj+Ctl {
    Rz(alpha, q);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Looking at the solutions file, we see that the intended solution is the &lt;span  class=&#34;math&#34;&gt;\(R1\)&lt;/span&gt; operation. This operation rotates the vector about the &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt; state.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation PhaseChange (alpha : Double, q : Qubit) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj+Ctl {
    R1(alpha, q);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To be completely truthful, I am unsure why this is the case. The &lt;a href=&#34;https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.r1?view=qsharp-preview&#34;&gt;documentation&lt;/a&gt; for the &lt;span  class=&#34;math&#34;&gt;\(R1\)&lt;/span&gt; operation says that it equivalent to &lt;code&gt;R(PauliZ, theta, qubit);&lt;/code&gt;, or a rotation about the &lt;span  class=&#34;math&#34;&gt;\(Z\)&lt;/span&gt; axis by theta degrees.&lt;/p&gt;

&lt;p&gt;However, the test will fail if &lt;code&gt;Rz&lt;/code&gt; or &lt;code&gt;R&lt;/code&gt; operations are used. If anyone knows the reason behind this, please do enlighten me.&lt;/p&gt;

&lt;p&gt;&lt;a name=&#34;bell&#34;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&#34;bell-states&#34;&gt;Bell States&lt;/h1&gt;

&lt;p&gt;Before we continue to the next task, let us briefly unpack an important concept in quantum information.&lt;/p&gt;

&lt;p&gt;To put it simply, a &lt;a href=&#34;https://en.wikipedia.org/wiki/Bell_state&#34;&gt;Bell state&lt;/a&gt; or EPR pair is a pair of maximally entangled qubits. The four Bell states are as follows.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |\Psi^+\rangle = \frac{|01\rangle + |10\rangle }{\sqrt{2}} = |\beta_{01}\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |\Psi^-\rangle = \frac{|01\rangle - |10\rangle }{\sqrt{2}} = |\beta_{11}\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |\Phi^+\rangle = \frac{|00\rangle + |11\rangle }{\sqrt{2}} = |\beta_{00}\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |\Phi^-\rangle = \frac{|00\rangle - |11\rangle }{\sqrt{2}} = |\beta_{10}\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The arbitrary Bell state &lt;span  class=&#34;math&#34;&gt;\(|\beta_{xy}\rangle\)&lt;/span&gt; can be prepared with the following quantum circuit.&lt;/p&gt;


  &lt;figure class=&#34;center&#34; &gt;
    &lt;img src=&#34;https://gideonwolfe.com/img/quantum/bellCircuit.png&#34;   style=&#34;border-radius: 8px;&#34;  /&gt;
    
      &lt;figcaption class=&#34;center&#34; &gt;Diagram made with LaTex and Qcircuit&lt;/figcaption&gt;
    
  &lt;/figure&gt;



&lt;p&gt;This diagram shows qubit &lt;span  class=&#34;math&#34;&gt;\(x\)&lt;/span&gt; being put into the hadamard gate, which gives it a &lt;span  class=&#34;math&#34;&gt;\(\frac{1}{2}\)&lt;/span&gt; chance of being found in the 0 and 1 position. Then, this qubit is used as the control in a &lt;code&gt;CNOT&lt;/code&gt; gate. The state of qubit &lt;span  class=&#34;math&#34;&gt;\(y\)&lt;/span&gt; will only be flipped if qubit &lt;span  class=&#34;math&#34;&gt;\(x\)&lt;/span&gt; is in state &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;To see how this works in detail, check out this &lt;a href=&#34;https://algassert.com/quirk#circuit={%22cols%22:[[%22H%22],[%22%E2%80%A2%22,%22X%22]],%22init%22:[0,1]}&#34;&gt;quantum circuit tool&lt;/a&gt;. Here I have prepared the &lt;span  class=&#34;math&#34;&gt;\(|\Psi^+\rangle\)&lt;/span&gt; Bell state. Mess around with the inputs to generate the different states.&lt;/p&gt;

&lt;p&gt;&lt;a name=&#34;bellchange1&#34;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&#34;task-17-bell-state-change-1&#34;&gt;Task 1.7: Bell State Change 1&lt;/h1&gt;

&lt;p&gt;Our goal in this task is to take two qubits prepared in the bell state &lt;span  class=&#34;math&#34;&gt;\(|\Phi^+\rangle\)&lt;/span&gt; and transform them to the bell state &lt;span  class=&#34;math&#34;&gt;\(|\Phi^-\rangle\)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;We recall from task 1.3 that a sign flip of a single qubit state can be accomplished with the &lt;strong&gt;Pauli Z&lt;/strong&gt; gate.&lt;/p&gt;

&lt;p&gt;Can we extrapolate this to work on a multi-qubit state?&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation BellStateChange1 (qs : Qubit[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj+Ctl {
    Z(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
    &lt;span style=&#34;color:#75715e&#34;&gt;// alternatively Z(qs[1]);
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Indeed we can. Applying the &lt;code&gt;Z&lt;/code&gt; gate to either of the qubits will change them to the &lt;span  class=&#34;math&#34;&gt;\(|\Phi^-\rangle\)&lt;/span&gt; state.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;Q#&lt;/code&gt;, a quantum register is treated like an array. Elements within the register can be indexed and operated upon for multi-qubit states and operations.&lt;/p&gt;

&lt;h1 id=&#34;task-18-bell-state-change-2&#34;&gt;Task 1.8: Bell State Change 2&lt;/h1&gt;

&lt;p&gt;In this task, we take the Bell state &lt;span  class=&#34;math&#34;&gt;\(|\Phi^+\rangle\)&lt;/span&gt; to the state &lt;span  class=&#34;math&#34;&gt;\(|\Psi^+\rangle\)&lt;/span&gt;.
Applying the &lt;strong&gt;Pauli X&lt;/strong&gt; gate to one qubit in a Bell state will keep the sign the same but alter the possible measured values.&lt;/p&gt;

&lt;p&gt;In simple terms, this would take &lt;span  class=&#34;math&#34;&gt;\(|\Phi^\pm\rangle \rightarrow |\Psi^\pm\rangle\)&lt;/span&gt; and vice versa.&lt;/p&gt;


  &lt;figure class=&#34;center&#34; &gt;
    &lt;img src=&#34;https://gideonwolfe.com/img/quantum/bellChange2_1.png&#34;   style=&#34;border-radius: 8px;&#34;  /&gt;
    
      &lt;figcaption class=&#34;center&#34; &gt;The $$|\Phi^&amp;#43;\rangle$$ Bell state&lt;/figcaption&gt;
    
  &lt;/figure&gt;




  &lt;figure class=&#34;center&#34; &gt;
    &lt;img src=&#34;https://gideonwolfe.com/img/quantum/bellChange2_2.png&#34;   style=&#34;border-radius: 8px;&#34;  /&gt;
    
      &lt;figcaption class=&#34;center&#34; &gt;Applying the X gate gives us the $$|\Psi^&amp;#43;\rangle$$ state&lt;/figcaption&gt;
    
  &lt;/figure&gt;



&lt;p&gt;Fill in the operation like so to complete the task:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation BellStateChange2 (qs : Qubit[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj+Ctl {
    X(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
    &lt;span style=&#34;color:#75715e&#34;&gt;// alternatively X(qs[1]);
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-19-bell-state-change-3&#34;&gt;Task 1.9: Bell State Change 3&lt;/h1&gt;

&lt;p&gt;In our final Bell state task, we must combine the things we have learned so far to transform &lt;span  class=&#34;math&#34;&gt;\(|\Phi^+\rangle\)&lt;/span&gt; to &lt;span  class=&#34;math&#34;&gt;\(|\Psi^-\rangle\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;As you may have guessed, we can combine the &lt;code&gt;X&lt;/code&gt; and &lt;code&gt;Z&lt;/code&gt; gates to change the basis and sign.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation BellStateChange3 (qs : Qubit[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj+Ctl {
    X(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
    Z(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As the comment in the code mentions, this operation is not equivalent to &lt;code&gt;Y(qs[0])&lt;/code&gt;, because the Y gate adds a global phase that the &lt;code&gt;X&lt;/code&gt; and &lt;code&gt;Z&lt;/code&gt; gates do not.&lt;/p&gt;

&lt;h1 id=&#34;task-21-twoqubit-gate--1&#34;&gt;Task 2.1: Two-qubit gate - 1&lt;/h1&gt;

&lt;p&gt;Let&#39;s closely examine the spec for this task to isolate what the true goal is here.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Goal:  Change the two-qubit state to α |00⟩ + β |11⟩.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The keen eyed might recognize the measurement basis of &lt;span  class=&#34;math&#34;&gt;\(|00\rangle\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(|11\rangle\)&lt;/span&gt; being the same as the Bell states &lt;span  class=&#34;math&#34;&gt;\(|\Phi^\pm\rangle\)&lt;/span&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The first qubit will be in state |ψ⟩ = α |0⟩ + β |1⟩, the second in state |0⟩&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since our first qubit is already in superposition, there is no need to apply the &lt;code&gt;H&lt;/code&gt; gate. All that is left to do is apply a &lt;code&gt;CNOT&lt;/code&gt; gate, using our first qubit as a control.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation TwoQubitGate1 (qs : Qubit[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
    CNOT(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;], qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We have just created a pair of entangled qubits. Unlike the Bell states, these qubits are not necessarily maximally entangled, with amplitudes &lt;span  class=&#34;math&#34;&gt;\(\frac{1}{\sqrt{2}}\)&lt;/span&gt;. The amplitudes &lt;span  class=&#34;math&#34;&gt;\(\alpha\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(\beta\)&lt;/span&gt; can represent any complex normalized probability amplitude.&lt;/p&gt;

&lt;h1 id=&#34;task-22-twoqubit-gate--2&#34;&gt;Task 2.2: Two-qubit gate - 2&lt;/h1&gt;

&lt;p&gt;We have been given two qubits prepared in the &lt;span  class=&#34;math&#34;&gt;\(|+\rangle\)&lt;/span&gt; state. Recall that&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |+\rangle = \frac{|0\rangle + |1\rangle}{\sqrt{2}} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Since all of our &lt;span  class=&#34;math&#34;&gt;\(n\)&lt;/span&gt; qubits are in a superposition of &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt;, it makes sense that measuring our qubits would result in &lt;span  class=&#34;math&#34;&gt;\(2^n\)&lt;/span&gt; possible outcomes.&lt;/p&gt;

&lt;p&gt;What&#39;s more, the &lt;span  class=&#34;math&#34;&gt;\(|+\rangle\)&lt;/span&gt; state represents an exact superposition between &lt;span  class=&#34;math&#34;&gt;\(|0\rangle\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt;, with a &lt;span  class=&#34;math&#34;&gt;\(\frac{1}{2}\)&lt;/span&gt; chance of being measured in either state.&lt;/p&gt;


  &lt;figure class=&#34;center&#34; &gt;
    &lt;img src=&#34;https://gideonwolfe.com/img/quantum/multiqubit2_2.png&#34;   style=&#34;border-radius: 8px;&#34;  /&gt;
    
      &lt;figcaption class=&#34;center&#34; &gt;A probability of 25% for all states&lt;/figcaption&gt;
    
  &lt;/figure&gt;



&lt;p&gt;Simple statistics tell us that the probability of measuring any of the states would be &lt;span  class=&#34;math&#34;&gt;\(\frac{1}{2}^n\)&lt;/span&gt;, which in this case is &lt;span  class=&#34;math&#34;&gt;\(\frac{1}{4}\)&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;The goal of this task is to change our state like so:&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \frac{|00\rangle + |01\rangle + |10\rangle + |11\rangle}{2} \rightarrow \frac{|00\rangle + |01\rangle + |10\rangle - |11\rangle}{2} \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Looking at the circuit above, this is the same thing as negating the &lt;code&gt;val:&lt;/code&gt; field for the amplitude of &lt;span  class=&#34;math&#34;&gt;\(|11\rangle\)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;As we learned in task 1.7, changing the sign of the state can be accomplished with the &lt;code&gt;Z&lt;/code&gt; gate. Let&#39;s see what happens when we apply the &lt;code&gt;Z&lt;/code&gt; gate to our qubit.&lt;/p&gt;

&lt;p&gt;
  &lt;img src=&#34;https://gideonwolfe.com/img/quantum/multiqubit2_3.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;



  &lt;img src=&#34;https://gideonwolfe.com/img/quantum/multiqubit2_4.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;

&lt;/p&gt;

&lt;p&gt;Placing the &lt;code&gt;Z&lt;/code&gt; gate on first and second qubit negated the value of the second column and second row respectively. However, we just want to isolate the &lt;span  class=&#34;math&#34;&gt;\(|11\rangle\)&lt;/span&gt; state.&lt;/p&gt;

&lt;p&gt;This can be done with a &lt;strong&gt;Controlled Z&lt;/strong&gt; gate. Similar to &lt;code&gt;CNOT&lt;/code&gt; gate, &lt;code&gt;CZ(x, y)&lt;/code&gt; preforms a &lt;code&gt;Z&lt;/code&gt; operation on qubit &lt;span  class=&#34;math&#34;&gt;\(y\)&lt;/span&gt; if qubit &lt;span  class=&#34;math&#34;&gt;\(x\)&lt;/span&gt; is in the &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt; state.&lt;/p&gt;

&lt;p&gt;To understand this, let&#39;s look at the matrix representation of all possible inputs.
If we represent our two-qubit state as a 4-dimensional vector &lt;span  class=&#34;math&#34;&gt;\(|\Psi\rangle\)&lt;/span&gt;, where&lt;/p&gt;

&lt;div&gt;
$$ |\Psi\rangle = 
\begin{bmatrix}
\alpha_{00} \\
\alpha_{01} \\
\alpha_{10} \\
\alpha_{11} \\
\end{bmatrix}
$$
&lt;/div&gt;

&lt;p&gt;and &lt;span  class=&#34;math&#34;&gt;\(\alpha_{xy}\)&lt;/span&gt; is the normalized probability amplitude of measuring our qubits in the state &lt;span  class=&#34;math&#34;&gt;\(|XY\rangle\)&lt;/span&gt;, we can see the effect of the &lt;code&gt;Controlled Z&lt;/code&gt; gate on all our possible basic inputs.&lt;/p&gt;

&lt;div&gt;
$$
\begin{bmatrix}
1 &amp; 0 &amp; 0 &amp; 0 \\
0 &amp; 1 &amp; 0 &amp; 0 \\
0 &amp; 0 &amp; 1 &amp; 0 \\
0 &amp; 0 &amp; 0 &amp; -1 \\
\end{bmatrix} 
\cdot
\begin{bmatrix}
1 \\
0 \\
0 \\
0 \\
\end{bmatrix}
=
\begin{bmatrix}
1 \\
0 \\
0 \\
0 \\
\end{bmatrix}
$$
&lt;/div&gt;

&lt;div&gt;
$$
\begin{bmatrix}
1 &amp; 0 &amp; 0 &amp; 0 \\
0 &amp; 1 &amp; 0 &amp; 0 \\
0 &amp; 0 &amp; 1 &amp; 0 \\
0 &amp; 0 &amp; 0 &amp; -1 \\
\end{bmatrix} 
\cdot
\begin{bmatrix}
0 \\
1 \\
0 \\
0 \\
\end{bmatrix}
=
\begin{bmatrix}
0 \\
1 \\
0 \\
0 \\
\end{bmatrix}
$$
&lt;/div&gt;

&lt;div&gt;
$$
\begin{bmatrix}
1 &amp; 0 &amp; 0 &amp; 0 \\
0 &amp; 1 &amp; 0 &amp; 0 \\
0 &amp; 0 &amp; 1 &amp; 0 \\
0 &amp; 0 &amp; 0 &amp; -1 \\
\end{bmatrix} 
\cdot
\begin{bmatrix}
0 \\
0 \\
1 \\
0 \\
\end{bmatrix}
=
\begin{bmatrix}
0 \\
0 \\
1 \\
0 \\
\end{bmatrix}
$$
&lt;/div&gt;

&lt;div&gt;
$$
\begin{bmatrix}
1 &amp; 0 &amp; 0 &amp; 0 \\
0 &amp; 1 &amp; 0 &amp; 0 \\
0 &amp; 0 &amp; 1 &amp; 0 \\
0 &amp; 0 &amp; 0 &amp; -1 \\
\end{bmatrix} 
\cdot
\begin{bmatrix}
0 \\
0 \\
0 \\
1 \\
\end{bmatrix}
=
\begin{bmatrix}
0 \\
0 \\
0 \\
-1 \\
\end{bmatrix}
$$
&lt;/div&gt;

&lt;p&gt;We can see that only the &lt;span  class=&#34;math&#34;&gt;\(|11\rangle\)&lt;/span&gt; state was changed, just as intended.&lt;/p&gt;


  &lt;img src=&#34;https://gideonwolfe.com/img/quantum/multiqubit2_5.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;



&lt;p&gt;Fill in the operation as shown below. You can use the intrinsic &lt;code&gt;CZ&lt;/code&gt; gate or the &lt;code&gt;Z&lt;/code&gt; gate with the &lt;code&gt;Controlled&lt;/code&gt; modifier.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation TwoQubitGate2 (qs : Qubit[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
    Controlled Z([qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]], qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
    &lt;span style=&#34;color:#75715e&#34;&gt;// alternatively: CZ(qs[0], qs[1]);
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-23-twoqubit-gate--3&#34;&gt;Task 2.3: Two-qubit gate - 3&lt;/h1&gt;

&lt;p&gt;Again, we are given an array of two qubits, this time in some arbitrary state&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |\Psi\rangle = \alpha|00\rangle + \beta|01\rangle + \gamma|10\rangle + \delta|11\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;And we are tasked with transforming it to the state&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |\Psi&#39;\rangle = \alpha|00\rangle + \gamma|01\rangle + \beta|10\rangle + \delta|11\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Which effectively swaps the probability of finding our qubits in state &lt;span  class=&#34;math&#34;&gt;\(|01\rangle\)&lt;/span&gt; and &lt;span  class=&#34;math&#34;&gt;\(|10\rangle\)&lt;/span&gt;. In vector form, this can re represented like this:&lt;/p&gt;

&lt;div&gt;
$$ 
\begin{bmatrix}
\alpha_{00} \\
\alpha_{01} \\
\alpha_{10} \\
\alpha_{11} \\
\end{bmatrix}

\rightarrow

\begin{bmatrix}
\alpha_{00} \\
\alpha_{10} \\
\alpha_{01} \\
\alpha_{11} \\
\end{bmatrix}
$$
&lt;/div&gt;

&lt;p&gt;If you recently took a linear algebra course, you may have been able to derive the matrix to achieve this transformation. This is the matrix representation of the &lt;code&gt;SWAP&lt;/code&gt; gate.&lt;/p&gt;

&lt;div&gt;
$$ 
\begin{bmatrix}
1 &amp; 0 &amp; 0 &amp; 0 \\
0 &amp; 0 &amp; 1 &amp; 0 \\
0 &amp; 1 &amp; 0 &amp; 0 \\
0 &amp; 0 &amp; 0 &amp; 1 \\
\end{bmatrix} 
$$
&lt;/div&gt;

&lt;p&gt;The task also hints that this test can be passed with &amp;quot;several (possibly controlled) Pauli gates&amp;quot;. Much like the classical &lt;code&gt;SWAP&lt;/code&gt; gate, a quantum &lt;code&gt;SWAP&lt;/code&gt; gate can be expressed with &lt;code&gt;CNOT&lt;/code&gt; gates.&lt;/p&gt;


  &lt;figure class=&#34;center&#34; &gt;
    &lt;img src=&#34;https://gideonwolfe.com/img/quantum/multiqubit3_1.png&#34;   style=&#34;border-radius: 8px;&#34;  /&gt;
    
      &lt;figcaption class=&#34;center&#34; &gt;Diagram from &amp;#39;Quantum Computation and Quantum Information&amp;#39;&lt;/figcaption&gt;
    
  &lt;/figure&gt;



&lt;p&gt;Write the operation like so to pass the test.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation TwoQubitGate3 (qs : Qubit[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
    CNOT(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;], qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
    CNOT(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;], qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]);
    CNOT(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;], qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;]);
    &lt;span style=&#34;color:#75715e&#34;&gt;// alternatively: SWAP(qs[0], qs[1]);
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-24-toffoli-gate&#34;&gt;Task 2.4: Toffoli Gate&lt;/h1&gt;

&lt;p&gt;For this task, we have been given a generous three qubit state &lt;span  class=&#34;math&#34;&gt;\(|\Psi\rangle\)&lt;/span&gt; to work with.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |\Psi\rangle = \alpha|000\rangle + \beta|001\rangle + \delta|011\rangle + \epsilon|100\rangle + \zeta|101\rangle + \eta|110\rangle + \theta|111\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The goal is as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Flip the state of the third qubit if the state of the first two is |11⟩&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This means changing the state to&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |\Psi\rangle = \alpha|000\rangle + \beta|001\rangle + \delta|011\rangle + \epsilon|100\rangle + \zeta|101\rangle + \theta|110\rangle + \eta|111\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;In previous tasks, we have used &lt;code&gt;Controlled&lt;/code&gt; gates to implement condition based operations. How might we add another conditional layer? By simply adding another control bit!&lt;/p&gt;

&lt;p&gt;This is the &lt;code&gt;Toffoli&lt;/code&gt; gate, a universal gate in both classical and quantum computing.&lt;/p&gt;


  &lt;figure class=&#34;center&#34; &gt;
    &lt;img src=&#34;https://gideonwolfe.com/img/quantum/toffoli.png&#34;   style=&#34;border-radius: 8px;&#34;  /&gt;
    
      &lt;figcaption class=&#34;center&#34; &gt;Diagram from &amp;#39;Quantum Computation and Quantum Information&amp;#39;&lt;/figcaption&gt;
    
  &lt;/figure&gt;



&lt;p&gt;The Toffoli gate negates the third qubit if and only if the first two qubits are in the &lt;span  class=&#34;math&#34;&gt;\(|11\rangle\)&lt;/span&gt; state.&lt;/p&gt;

&lt;p&gt;Here is the correct code for the task:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation ToffoliGate (qs : Qubit[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
    CCNOT(qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;], qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;], qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;]);
    &lt;span style=&#34;color:#75715e&#34;&gt;// alternatively (Controlled X)(qs[0..1], qs[2]);
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;task-25-fredkin-gate&#34;&gt;Task 2.5. Fredkin gate&lt;/h1&gt;

&lt;p&gt;Like the Toffoli gate from the last task, the Fredkin gate is a universal gate in classical and quantum computing.&lt;/p&gt;

&lt;p&gt;The Fredkin gate, also known as the &lt;code&gt;Controlled Swap&lt;/code&gt;, swaps the 2nd and 3rd qubit only if the first qubit is in the &lt;span  class=&#34;math&#34;&gt;\(|1\rangle\)&lt;/span&gt; state.&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |\Psi\rangle = \alpha|000\rangle + \beta|001\rangle + \delta|011\rangle + \epsilon|100\rangle + \zeta|101\rangle + \eta|110\rangle + \theta|111\rangle \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ \downarrow \]&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span  class=&#34;math&#34;&gt;\[ |\Psi&#39;\rangle = \alpha|000\rangle + \beta|001\rangle + \delta|011\rangle + \epsilon|100\rangle + \eta|101\rangle + \zeta|110\rangle + \theta|111\rangle \]&lt;/span&gt;&lt;/p&gt;


  &lt;figure class=&#34;center&#34; &gt;
    &lt;img src=&#34;https://gideonwolfe.com/img/quantum/fredkin.png&#34;   style=&#34;border-radius: 8px;&#34;  /&gt;
    
      &lt;figcaption class=&#34;center&#34; &gt;Fredkin circuit with matrix representation&lt;/figcaption&gt;
    
  &lt;/figure&gt;



&lt;p&gt;Although the &lt;code&gt;Fredkin&lt;/code&gt; gate is extremely common in larger quantum circuits, the easiest way to express it here is with the following code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;operation FredkinGate (qs : Qubit[]) : Unit &lt;span style=&#34;color:#66d9ef&#34;&gt;is&lt;/span&gt; Adj {
    Controlled SWAP([qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]], (qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;], qs[&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;]));
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;In this article, I covered some of the fundamental concepts of quantum mechanics by using example problems from Microsoft&#39;s &lt;code&gt;Q#&lt;/code&gt; Quantum Katas.&lt;/p&gt;

&lt;p&gt;I went over some of the basic quantum gates and how they can be applied to your quantum programs.&lt;/p&gt;

&lt;p&gt;I am still new to this field, so please do not hesitate to contact me with questions or corrections.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Setting Up An Automated Home Media Server With Docker</title>
      <link>https://gideonwolfe.com/posts/sysadmin/mediaserver/</link>
      <pubDate>Tue, 13 Aug 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/sysadmin/mediaserver/</guid>
      <description>&lt;p&gt;With streaming services becoming more fragmented, getting access to all your favorite content has become almost as inconvenient and expensive as it was in the days of cable packages.&lt;/p&gt;
&lt;p&gt;Even if you happen to find your favorite content on a streaming platform, there&amp;rsquo;s no guarantee it will be around forever. A single discontinued licensing contract could mean losing access to countless pieces of media!&lt;/p&gt;
&lt;p&gt;For these reasons, I have built up a fairly large music collection on my hard drive. I recently realized I needed a proper backup solution for my music and other important files.&lt;/p&gt;
&lt;p&gt;I figured while I was at it, I would make my music collection streamable, because there&amp;rsquo;s lots of stuff Spotify and others don&amp;rsquo;t have. Then I figured since I was hosting music, I might as well start building a collection of movies and television for when I inevitably tire of paying for Netflix and Hulu.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a breakdown of the server I built:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://pcpartpicker.com/list/RqmCBb&#34;&gt;PCPartPicker Part List&lt;/a&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&#34;text-align:left&#34;&gt;Type&lt;/th&gt;
&lt;th style=&#34;text-align:left&#34;&gt;Item&lt;/th&gt;
&lt;th style=&#34;text-align:left&#34;&gt;Price&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;strong&gt;CPU&lt;/strong&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;a href=&#34;https://pcpartpicker.com/product/RkJtt6/amd-ryzen-3-2200g-35ghz-quad-core-processor-yd2200c5fbbox&#34;&gt;AMD Ryzen 3 2200G 3.5 GHz Quad-Core Processor&lt;/a&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:left&#34;&gt;$79.89 @ OutletPC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;strong&gt;Motherboard&lt;/strong&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;a href=&#34;https://pcpartpicker.com/product/hpRzK8/gigabyte-b450m-ds3h-micro-atx-am4-motherboard-b450m-ds3h&#34;&gt;Gigabyte B450M DS3H Micro ATX AM4 Motherboard&lt;/a&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:left&#34;&gt;$73.99 @ Amazon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;strong&gt;Memory&lt;/strong&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;a href=&#34;https://pcpartpicker.com/product/sMbkcf/corsair-memory-cmk8gx4m1a2400c16&#34;&gt;Corsair Vengeance LPX 8 GB (1 x 8 GB) DDR4-2400 Memory&lt;/a&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:left&#34;&gt;$39.99 @ Amazon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;strong&gt;Storage&lt;/strong&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;a href=&#34;https://pcpartpicker.com/product/m4Nv6h/toshiba-x300-8tb-35-7200rpm-internal-hard-drive-hdwf180xzsta&#34;&gt;Toshiba X300 8 TB 3.5&amp;quot; 7200RPM Internal Hard Drive&lt;/a&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:left&#34;&gt;$167.99 @ Amazon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;strong&gt;Case&lt;/strong&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;a href=&#34;https://pcpartpicker.com/product/3MPfrH/deepcool-case-tesseractsw&#34;&gt;Deepcool TESSERACT BF ATX Mid Tower Case&lt;/a&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:left&#34;&gt;$49.99 @ B&amp;amp;H&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;strong&gt;Power Supply&lt;/strong&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;a href=&#34;https://pcpartpicker.com/product/9qTmP6/silverstone-power-supply-st30sf&#34;&gt;Silverstone 300 W 80+ Bronze Certified SFX Power Supply&lt;/a&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:left&#34;&gt;$61.99 @ Amazon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;em&gt;Prices include shipping, taxes, rebates, and discounts&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td style=&#34;text-align:left&#34;&gt;&lt;strong&gt;$473.84&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&#34;text-align:left&#34;&gt;Generated by &lt;a href=&#34;https://pcpartpicker.com&#34;&gt;PCPartPicker&lt;/a&gt; 2019-08-13 13:51 EDT-0400&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;I went cheap for this build, because all it needs to do is reliably store media files. I gave it a decent CPU and 8GB of memory so streaming this media to a couple clients should be no problem.&lt;/p&gt;
&lt;h1 id=&#34;software-stack&#34;&gt;Software Stack&lt;/h1&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/MediaServer/diagram2.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 400px; height: 400px;&#34;  /&gt;


&lt;p&gt;This diagram should give an overview of how our software talks to each other. Basically;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All programs are run in docker for portability and convenience&lt;/li&gt;
&lt;li&gt;Sonarr watches usenet for TV shows I want&lt;/li&gt;
&lt;li&gt;Couchpotato watches usenet for movies I want&lt;/li&gt;
&lt;li&gt;SABnzbd downloads the NZBs found by Sonarr and Couchpotato&lt;/li&gt;
&lt;li&gt;Jellyfin serves these media files with a pretty interface&lt;/li&gt;
&lt;li&gt;Traefik generates SSL certs for the desired containers&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;step-1-setting-up-docker&#34;&gt;Step 1: Setting up Docker&lt;/h1&gt;
&lt;p&gt;In this tutorial I will assume you are a docker novice. If you already have some familiarity with docker, you can probably skip to the next section.&lt;/p&gt;
&lt;p&gt;Since I am running my machine with Ubuntu Server, I am going to install the necessary packages with the following command:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt install docker.io docker-compose
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;docker&lt;/code&gt; is a program that runs applications in containers. These containers share the kernelspace with the host machine, but isolate their own dependencies and runtime environments. This is great for application security and portability.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker-compose&lt;/code&gt; is a functionality within docker that allows a series of containers to be preconfigured, so they can all be launched, maintained, and updated easily and conveniently.&lt;/p&gt;
&lt;p&gt;I set up my &amp;ldquo;programs&amp;rdquo; folder with a &lt;code&gt;docker-compose.yaml&lt;/code&gt; file, along with subfolders for every application to store configurations and metadata.&lt;/p&gt;
&lt;h1 id=&#34;step-2-setting-up-traefik&#34;&gt;Step 2: Setting up Traefik&lt;/h1&gt;
&lt;p&gt;Traefik is a reverse proxy that integrates with Let&amp;rsquo;sEncrypt to dynamically provide SSL certificates to running applications. It will be able to securely direct HTTP requests to our server to the correct container.&lt;/p&gt;
&lt;p&gt;If you aren&amp;rsquo;t planning on using these services outside your home network, it&amp;rsquo;s safe to skip this step. If you own a domain and wish to access your media anywhere, read on.&lt;/p&gt;
&lt;p&gt;Traefik needs two files to work correctly. The Traefik configuration file, &lt;code&gt;traefik.toml&lt;/code&gt;, and the configuration defining the container behaivior in &lt;code&gt;docker-compose.yaml&lt;/code&gt;. Let&amp;rsquo;s take a look at that first.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-docker&#34; data-lang=&#34;docker&#34;&gt;version: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;services:      &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;   reverse-proxy:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      image: traefik:latest&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      restart: always&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      container_name: traefik&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      ports: &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - 80:80&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - 443:443&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - 8081:8081&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      expose:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#ae81ff&#34;&gt;8080&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      networks:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - traefik&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      environment:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - DO_AUTH_TOKEN&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&amp;lt;or another DNS provider &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; you use one&amp;gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      volumes:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /var/run/docker.sock:/var/run/docker.sock&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - ./Traefik/traefik.toml:/traefik.toml&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - ./Traefik/acme.json:/acme.json&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      labels: &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.backend=traefik&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.docker.network=traefik&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.enable=false&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.rule=Host:Host:monitor.mydomain.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.port=8080&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.headers.forceSTSHeader=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.headers.STSSeconds=315360000&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.headers.STSIncludeSubdomains=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.headers.STSPreload=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Some things to take away:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We need to bind ports &lt;code&gt;80&lt;/code&gt; and &lt;code&gt;443&lt;/code&gt; to receive HTTP/S traffic. These ports must be forwarded to your server from your router.&lt;/li&gt;
&lt;li&gt;We mount our docker node to the traefik container so it can see our other containers&lt;/li&gt;
&lt;li&gt;We mount &lt;code&gt;traefik.toml&lt;/code&gt; and &lt;code&gt;acme.json&lt;/code&gt;, the file used to store our SSL configurations.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;traefik.enable&lt;/code&gt; is set to false because I don&amp;rsquo;t need to use it outside my network.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then we have to define some more settings in &lt;code&gt;traefik.toml&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;defaultEntryPoints&lt;/span&gt; = [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;http&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;]
&lt;span style=&#34;color:#a6e22e&#34;&gt;logLevel&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;DEBUG&amp;#34;&lt;/span&gt;

[&lt;span style=&#34;color:#a6e22e&#34;&gt;entryPoints&lt;/span&gt;]
  [&lt;span style=&#34;color:#a6e22e&#34;&gt;entryPoints&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;dashboard&lt;/span&gt;]
    &lt;span style=&#34;color:#a6e22e&#34;&gt;address&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;:8081&amp;#34;&lt;/span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# I changed from 8080 because SAB uses it&lt;/span&gt;
  [&lt;span style=&#34;color:#a6e22e&#34;&gt;entryPoints&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;http&lt;/span&gt;]
    &lt;span style=&#34;color:#a6e22e&#34;&gt;address&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;:80&amp;#34;&lt;/span&gt;
      [&lt;span style=&#34;color:#a6e22e&#34;&gt;entryPoints&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;http&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;redirect&lt;/span&gt;]
        &lt;span style=&#34;color:#a6e22e&#34;&gt;entryPoint&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;
  [&lt;span style=&#34;color:#a6e22e&#34;&gt;entryPoints&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;https&lt;/span&gt;]
    &lt;span style=&#34;color:#a6e22e&#34;&gt;address&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;:443&amp;#34;&lt;/span&gt;
      [&lt;span style=&#34;color:#a6e22e&#34;&gt;entryPoints&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;https&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;tls&lt;/span&gt;]

[&lt;span style=&#34;color:#a6e22e&#34;&gt;api&lt;/span&gt;]
&lt;span style=&#34;color:#a6e22e&#34;&gt;entrypoint&lt;/span&gt;=&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;dashboard&amp;#34;&lt;/span&gt;

[&lt;span style=&#34;color:#a6e22e&#34;&gt;acme&lt;/span&gt;]
   &lt;span style=&#34;color:#a6e22e&#34;&gt;email&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;me@mydomain.com&amp;#34;&lt;/span&gt;
   &lt;span style=&#34;color:#a6e22e&#34;&gt;storage&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;acme.json&amp;#34;&lt;/span&gt;   
   &lt;span style=&#34;color:#a6e22e&#34;&gt;onHostRule&lt;/span&gt; = &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
   &lt;span style=&#34;color:#a6e22e&#34;&gt;entryPoint&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;

   [&lt;span style=&#34;color:#a6e22e&#34;&gt;acme&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;dnsChallenge&lt;/span&gt;]
      &lt;span style=&#34;color:#a6e22e&#34;&gt;provider&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;digitalocean&amp;#34;&lt;/span&gt;
      &lt;span style=&#34;color:#a6e22e&#34;&gt;delayBeforeCheck&lt;/span&gt; = &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;   

   [[&lt;span style=&#34;color:#a6e22e&#34;&gt;acme&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;domains&lt;/span&gt;]]
      &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;*.mydomain.com&amp;#34;&lt;/span&gt;
     
[&lt;span style=&#34;color:#a6e22e&#34;&gt;docker&lt;/span&gt;]
&lt;span style=&#34;color:#a6e22e&#34;&gt;domain&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;mydomain.com&amp;#34;&lt;/span&gt;
&lt;span style=&#34;color:#a6e22e&#34;&gt;watch&lt;/span&gt; = &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
&lt;span style=&#34;color:#a6e22e&#34;&gt;network&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik&amp;#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;The entrypoints section forces HTTPS and enables the dashboard on &lt;code&gt;locahlhost:8081&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;acme&lt;/code&gt; section defines the settings for Let&amp;rsquo;sEncrypt, which may need to be tweaked for your &lt;a href=&#34;https://docs.traefik.io/user-guide/examples/&#34;&gt;setup&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The above file must be created:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;touch acme.json &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; chmod &lt;span style=&#34;color:#ae81ff&#34;&gt;600&lt;/span&gt; acme.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To test out what we have so far, go to the root of your docker directory and run &lt;code&gt;docker-compose up&lt;/code&gt;. Traefik was the hardest for me to configure, so read the output carefully for errors. If everything went OK, we should see our dashboard at &lt;code&gt;localhost:8081&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&#34;step-3-docker-configurations&#34;&gt;Step 3: Docker Configurations&lt;/h1&gt;
&lt;p&gt;The other applications in this setup are mostly controlled through web interfaces. That means that after the container is up and running, you can change the settings via your web browser just how you like them.&lt;/p&gt;
&lt;p&gt;I will go over the basic steps to get things running, but after that it&amp;rsquo;s up to you!&lt;/p&gt;
&lt;p&gt;Here is the &lt;strong&gt;full&lt;/strong&gt; docker compose file for my current setup&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-docker&#34; data-lang=&#34;docker&#34;&gt;version: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;services:      &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;   reverse-proxy:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      image: traefik:latest&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      restart: always&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      container_name: traefik&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      ports: &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - 80:80&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - 443:443&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - 8081:8081&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      expose:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#ae81ff&#34;&gt;8080&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      networks:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - traefik&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      environment:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - DO_AUTH_TOKEN&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      volumes:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /var/run/docker.sock:/var/run/docker.sock&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - ./Traefik/traefik.toml:/traefik.toml&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - ./Traefik/acme.json:/acme.json&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      labels: &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.backend=traefik&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.docker.network=traefik&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.enable=false&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.rule=Host:Host:monitor.gideonwolfe.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.port=8080&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.headers.forceSTSHeader=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.headers.STSSeconds=315360000&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.headers.STSIncludeSubdomains=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.headers.STSPreload=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;   jellyfin:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      image: linuxserver/jellyfin&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      container_name: jellyfin&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      environment:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - PUID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - PGID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - TZ&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;America/Los_Angeles&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      volumes:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /home/gideon/Data/Programs/Docker/Jellyfin/ProgramData/:/config&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /home/gideon/Data/Media/TV/:/data/tvshows&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /home/gideon/Data/Media/Movies/:/data/movies&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /home/gideon/Data/Music/:/data/music  &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      ports:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - 8096:8096&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      labels:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.enable=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.port=8096&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.rule=Host:server.gideonwolfe.com&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.backend=JellyFin&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.entryPoints=https&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.headers.forceSTSHeader=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.headers.STSSeconds=315360000&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.headers.STSIncludeSubdomains=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.frontend.headers.STSPreload=true&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.docker.network=traefik&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      networks:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - traefik&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      restart: unless-stopped&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;   couchpotato:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      image: linuxserver/couchpotato&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      container_name: couchpotato&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      environment:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - PUID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - PGID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - TZ&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;America/Los_Angeles&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - UMASK_SET&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;022&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      volumes:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /home/gideon/Data/Programs/Docker/CouchPotato/config:/config&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /home/gideon/Data/Programs/Docker/CouchPotato/Downloads:/downloads&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /home/gideon/Data/Media/Movies:/movies &lt;span style=&#34;color:#75715e&#34;&gt;# Where movies end up&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      ports:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - 5050:5050&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      restart: unless-stopped&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      labels:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.enable=false&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;   sabnzbd:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      image: linuxserver/sabnzbd&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      container_name: sabnzbd&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      environment:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - PUID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - PGID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - TZ&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;America/Los_Angeles&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      volumes:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /home/gideon/Data/Programs/Docker/Sabnzbd/config:/config&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /home/gideon/Data/Media/:/downloads&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      ports:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - 8080:8080&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - 9090:9090&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      restart: unless-stopped&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      labels:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.enable=false&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;   sonarr:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      image: linuxserver/sonarr&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      container_name: sonarr&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      environment:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - PUID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - PGID&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1000&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - TZ&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;America/Los_Angeles&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - UMASK_SET&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;022&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;#optional&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      volumes:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /home/gideon/Data/Programs/Docker/Sonarr/config:/config&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /home/gideon/Data/Media/TV:/tv &lt;span style=&#34;color:#75715e&#34;&gt;# Final folder where shows end up&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - /home/gideon/Data/Media/:/downloads &lt;span style=&#34;color:#75715e&#34;&gt;# Same as SAB downloads&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      ports:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - 8989:8989&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      restart: unless-stopped&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;      labels:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;         - &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;traefik.enable=false&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;networks:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;  traefik:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;    external: true   &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;  internal:&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Each &lt;code&gt;service&lt;/code&gt; level represents a containerized docker application.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;image&lt;/code&gt; level tells docker where to pull the image from.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;environment&lt;/code&gt; level allows you to pass variables into the container.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;volumes&lt;/code&gt; level mounts directories from the host into docker containers. This allows for persistant settings and access to media locations.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ports&lt;/code&gt; defines the port to access the services&lt;/li&gt;
&lt;li&gt;&lt;code&gt;labels&lt;/code&gt; allow us to define additional settings, such as disabling SSL certs with traefik.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I would recommend creating a seperate &lt;code&gt;docker-compose.yaml&lt;/code&gt; for each sevice, and testing them ony by one before combining them into a master compose file.&lt;/p&gt;
&lt;h1 id=&#34;step-4-web-configuration&#34;&gt;Step 4: Web configuration&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Jellyfin: &lt;code&gt;localhost:8096&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As long as your desired media is mounted in &lt;code&gt;docker-compose.yaml&lt;/code&gt;, You can use the dashboard page to set up libraries with these folders. Piece of cake.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SABnzbd: &lt;code&gt;localhost:8080&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You need to connect SAB with a usenet &lt;a href=&#34;https://www.techradar.com/news/the-best-usenet-providers&#34;&gt;provider&lt;/a&gt; using your account credentials and API key sent by your provider. This is done in the &amp;ldquo;Servers&amp;rdquo; settings tab.&lt;/li&gt;
&lt;li&gt;Set up the Categories tab to sort downloads into appropriate folders. For example, tv goes to &lt;code&gt;./TV&lt;/code&gt;, movies to &lt;code&gt;./Movies&lt;/code&gt;. These puts them in the folders Jellyfin looks in.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sonarr: &lt;code&gt;localhost:8989&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allow Sonarr to rename episodes under &amp;lsquo;Media Management&amp;rsquo;&lt;/li&gt;
&lt;li&gt;Under the &amp;ldquo;Indexers&amp;rdquo; tab, enter the url and API key from any &lt;a href=&#34;https://www.reddit.com/r/usenet/wiki/indexers&#34;&gt;indexers&lt;/a&gt; you have accounts for. Sign up for as many as possible for maximum success finding media.&lt;/li&gt;
&lt;li&gt;Under &amp;ldquo;Download Client&amp;rdquo; tab, add SAB. You will need the local IP address of your SAB server as well as the API key found in the &amp;ldquo;General&amp;rdquo; section of the SAB settings.&lt;/li&gt;
&lt;li&gt;Optionally enable metadata fetching&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CouchPotato: &lt;code&gt;localhost:5050&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add your indexers in the &amp;ldquo;Searchers&amp;rdquo; tab&lt;/li&gt;
&lt;li&gt;Add SAB in the &amp;ldquo;Downloaders&amp;rdquo; tab&lt;/li&gt;
&lt;li&gt;Allow Movie Renaming&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After all this is set up, we should be able to test it with some media.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Try finding a single TV episode through Sonarr using the magnifying glass.&lt;/li&gt;
&lt;li&gt;This should be sent to SABnzbd to download&lt;/li&gt;
&lt;li&gt;It should be in your media directory &lt;code&gt;TV/Series/Season #/Episode&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Refresh Jellyfin and view the media&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once this pipeline is working correctly, add all the shows you want, and set up monitors so new episodes are automatically downloaded.&lt;/p&gt;
&lt;p&gt;For CouchPotato, try adding a movie and seeing if the same behavior happens. Are your movies showing up in Jellyfin?&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;In this guide, I detailed the steps for setting up an end to end automated pipeline for downloading and streaming your favorite media. Although the initial setup can be tricky at times, the portability and convenience offered by docker makes this setup awesome!&lt;/p&gt;
&lt;p&gt;Containers and services can easily be added to the configuration, such as Syncthing or Nextcloud for file backups and sharing.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Automating Linux Desktop Theming With Chameleon</title>
      <link>https://gideonwolfe.com/posts/workflow/chameleon/</link>
      <pubDate>Tue, 30 Jul 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/workflow/chameleon/</guid>
      <description>&lt;p&gt;In my previous posts, I have mentioned my use of tools like &lt;a href=&#34;https://github.com/dylanaraps/pywal&#34;&gt;pywal&lt;/a&gt; to automatically generate colorschemes for my terminal based programs.&lt;/p&gt;
&lt;p&gt;Since then, I have developed a couple &lt;a href=&#34;https://github.com/GideonWolfe&#34;&gt;scripts&lt;/a&gt; that extend these colorschemes to programs I use regularly.&lt;/p&gt;
&lt;p&gt;At that time, my solution to dynamic configuration generartion was to replace the program executable with my own executable, which would generate a configuration on the fly and then launch the intended program.&lt;/p&gt;
&lt;p&gt;However, after gathering enough wal plugins, I realized I no longer had a one command solution to theme my system. Wal worked as intended, but I would manually generate GTK themes with oomox, and run commands to generate new skins for programs like Steam and Spotify.&lt;/p&gt;
&lt;p&gt;I finally caved and decided it was time for a script to handle all this tedium. &lt;a href=&#34;https://github.com/GideonWolfe/Chameleon&#34;&gt;Chameleon&lt;/a&gt; is that script.&lt;/p&gt;
&lt;p&gt;Chameleon works by putting the desired desktop background through &lt;code&gt;wal&lt;/code&gt;, and then using the palette generated by wal, creates themes and colorschemes for all supported programs detected on the users system.&lt;/p&gt;
&lt;p&gt;For example, if the user has installed &lt;a href=&#34;https://github.com/GideonWolfe/Zathura-Pywal&#34;&gt;Zathura-Pywal&lt;/a&gt;, A new zathura configuration file will be generated for this colorscheme. This means the user can run the &lt;code&gt;zathura&lt;/code&gt; command to launch the program, instead of the &lt;code&gt;zth&lt;/code&gt; command I had previously implemented to hook into the colorschemes.&lt;/p&gt;
&lt;p&gt;While not every plugin works seamlessly to theme their intended programs, (see issues I have opened in various repos) My script detects if you are trying to use them (with some configuration required) and runs the appropriate commands.&lt;/p&gt;
&lt;p&gt;For a full and up to date list of supported programs, see the github &lt;a href=&#34;https://github.com/GideonWolfe/Chameleon&#34;&gt;repo&lt;/a&gt;. In the mean time, feel free to submit a feature request (or even better, a pull request 😄)&lt;/p&gt;
&lt;p&gt;Here is some sample output of the script running&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#######################
# Running Wal On Image#
#######################
[I] image: Using image acastro_190117_dekstop_wallpaper.0.jpg.
[I] theme: Set theme to _home_gideon_Wallpapers_acastro_190117_dekstop_wallpaper_0_jpg_dark_None_None_1.1.0.json.
[I] colors: Found cached colorscheme.
[I] wallpaper: Set the new wallpaper.
[I] sequences: Set terminal colors.

[I] export: Exported all files.
[I] export: Exported all user files.
[I] reload: Reloaded environment.

##########################
# Updating Zathura Color #
##########################
Zathura Theme Set

##########################
# Updating Gnuplot Color #
##########################
Gnuplot Theme Set

##########################
# Updating GTK theme     #
##########################

Building theme at /home/gideon/.themes/oomox-xresources-dark

rm -rf &amp;quot;gtk-3.0/dist&amp;quot;
rm -f &amp;quot;gtk-3.0/gtk.gresource&amp;quot;
rm -rf &amp;quot;gtk-3.20/dist&amp;quot;
rm -f &amp;quot;gtk-3.20/gtk.gresource&amp;quot;
rm -rf &amp;quot;/home/gideon/.themes/oomox-xresources-dark/dist&amp;quot;
mkdir -p gtk-3.0/dist
sassc -I &amp;quot;gtk-3.0/scss&amp;quot; &amp;quot;gtk-3.0/scss/gtk.scss&amp;quot; &amp;quot;gtk-3.0/dist/gtk.css&amp;quot;
sassc -I &amp;quot;gtk-3.0/scss&amp;quot; &amp;quot;gtk-3.0/scss/gtk-dark.scss&amp;quot; &amp;quot;gtk-3.0/dist/gtk-dark.css&amp;quot;
glib-compile-resources --sourcedir=&amp;quot;gtk-3.0&amp;quot; &amp;quot;gtk-3.0/gtk.gresource.xml&amp;quot;
mkdir -p gtk-3.20/dist
sassc -I &amp;quot;gtk-3.20/scss&amp;quot; &amp;quot;gtk-3.20/scss/gtk.scss&amp;quot; &amp;quot;gtk-3.20/dist/gtk.css&amp;quot;
sassc -I &amp;quot;gtk-3.20/scss&amp;quot; &amp;quot;gtk-3.20/scss/gtk-dark.scss&amp;quot; &amp;quot;gtk-3.20/dist/gtk-dark.css&amp;quot;
glib-compile-resources --sourcedir=&amp;quot;gtk-3.20&amp;quot; &amp;quot;gtk-3.20/gtk.gresource.xml&amp;quot;
mkdir -p cinnamon
sassc -I &amp;quot;cinnamon/scss&amp;quot; &amp;quot;cinnamon/scss/cinnamon.scss&amp;quot; &amp;quot;cinnamon/cinnamon.css&amp;quot;

#######################
# Updating Icon theme #
#######################
== Template was copied to /home/gideon/.icons/oomox-xresources-dark-flat
== Theme was generated
Icon Theme Generated

##########################
# Updating Telegram Skin #
##########################
:: Palette generated succesfully.

#######################
# Updating Steam Skin #
#######################
Wal Steam cache found
Wal Steam config found
Wal Steam skin found
Reading colors
Patching new colors
No file to remove
Wal colors are now patched and ready to go
If this is your first run you may have to
enable Metro Wal Mod skin in steam then
simply restart steam!

###########################
# Updating Keyboard Color #
###########################
Keyboard Color Set

##########################
# Updating Spotify Color #
##########################
about.spa
artist.spa
browse.spa
buddy-list.spa
chart.spa
collection-album.spa
collection-artist.spa
collection-songs.spa
collection.spa
concert.spa
concerts.spa
error.spa
findfriends.spa
full-screen-modal.spa
genre.spa
glue-resources.spa
hub.spa
licenses.spa
login.spa
lyrics.spa
playlist-folder.spa
playlist.spa
profile.spa
queue.spa
search.spa
settings.spa
show.spa
station.spa
stations.spa
zlink.spa
[sudo] password for gideon: 
Spotify Theme Set

##################################
# Updating IntelliJ Color Scheme #
##################################
IntelliJ Theme Set
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Deploying a static Hugo site with NGINX</title>
      <link>https://gideonwolfe.com/posts/sysadmin/hugo/hugonginx/</link>
      <pubDate>Mon, 01 Jul 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/sysadmin/hugo/hugonginx/</guid>
      <description>&lt;p&gt;Many people (such as myself) try to avoid web development as much as humanly possible. I find myself less frustrated staring down 1000 lines of assembly than I do trying to center some text on a website.&lt;/p&gt;
&lt;p&gt;In the past, I have used Squarespace and the like to build nice sites for my non tech related projects. This may be an easy &amp;ldquo;it just works&amp;rdquo; solution, but for my personal website I wanted to do things myself.&lt;/p&gt;
&lt;p&gt;That being said, I don&amp;rsquo;t have time to spend fiddling with a LAMP stack and making a complicated site when all I really needed was a platform to post and share projects. That&amp;rsquo;s where &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt; comes in.  With Hugo, you can write simple markdown files and dynamically generate a static html based site, like this one.&lt;/p&gt;
&lt;h1 id=&#34;prerequisites&#34;&gt;Prerequisites:&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Linux OS: I recommend a dedicated system just for hosting if this is going to production. Either a system you aren&amp;rsquo;t using or a VPS on a provider such as &lt;a href=&#34;https://www.digitalocean.com/&#34;&gt;Digital Ocean&lt;/a&gt; or &lt;a href=&#34;https://www.linode.com/&#34;&gt;Linode&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A domain: You can&amp;rsquo;t really expect to run a website without one. There are plenty of good registrars out there, but I personally like &lt;a href=&#34;https://www.namecheap.com/&#34;&gt;NameCheap&lt;/a&gt; because you can host email for your domain without hosting the site itself.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;installing-hugo&#34;&gt;Installing Hugo&lt;/h1&gt;
&lt;p&gt;Visit the &lt;a href=&#34;https://gohugo.io/getting-started/installing/#debian-and-ubuntu&#34;&gt;Hugo quickstart guide&lt;/a&gt; for distro specific information. I was able to install hugo on my Ubuntu Server system with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt install hugo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and on Arch with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo pacman -Syu hugo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If Hugo is not in your distro&amp;rsquo;s repositories, you can always download it with the &lt;a href=&#34;https://gohugo.io/getting-started/installing/#install-hugo-from-tarball&#34;&gt;tarball&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;making-a-quick-site&#34;&gt;Making a quick site&lt;/h1&gt;
&lt;p&gt;Find a directory where you want to store your site, and run&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;hugo new site &amp;lt;site name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;where site name is the name of the folder your site will be created in.&lt;/p&gt;
&lt;h2 id=&#34;adding-a-theme&#34;&gt;Adding a theme&lt;/h2&gt;
&lt;p&gt;Browse this extensive list of &lt;a href=&#34;https://themes.gohugo.io/&#34;&gt;Hugo themes&lt;/a&gt; until you find one you like.
Find it on github, and simply clone it into your themes directory. Here, I chose the m10c theme.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cd mysite
git clone https://github.com/vaga/hugo-theme-m10c themes/m10c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then add the following line to your &lt;code&gt;config.toml&lt;/code&gt; file in your website&amp;rsquo;s root folder&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-config&#34; data-lang=&#34;config&#34;&gt;theme = &amp;quot;m10c&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;adding-a-post&#34;&gt;Adding a post&lt;/h2&gt;
&lt;p&gt;To create a new post, simply run&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;hugo new posts/my-first-post.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will create a post called &lt;code&gt;my-first-post&lt;/code&gt; in the &lt;code&gt;content/posts&lt;/code&gt; folder. Edit this as you please.&lt;/p&gt;
&lt;p&gt;Finally, we need to run the site. Change directory into the projects root and run&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;hugo server -t m10c -D
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Finally, visit &lt;code&gt;localhost:1313&lt;/code&gt; to see the site.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/sysadmin/HugoNginx/newsite.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;h1 id=&#34;configuring-nginx&#34;&gt;Configuring NGINX&lt;/h1&gt;
&lt;p&gt;Firstly, make sure you have installed &lt;a href=&#34;https://www.nginx.com/&#34;&gt;NGINX&lt;/a&gt;, which is available on pretty much every default repository.&lt;/p&gt;
&lt;p&gt;Now we are going to create and edit a configuration file for our site.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;cd /etc/nginx/sites-available/
cp default mysite
vim mysite
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There are a lot of comments, but your server configuration should look something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-nginx&#34; data-lang=&#34;nginx&#34;&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;server&lt;/span&gt; {
       &lt;span style=&#34;color:#f92672&#34;&gt;listen&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;;
       &lt;span style=&#34;color:#f92672&#34;&gt;listen&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;[::]:80&lt;/span&gt;;

       &lt;span style=&#34;color:#f92672&#34;&gt;server_name&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;mysite.com&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;www.mysite.com&lt;/span&gt;;

       &lt;span style=&#34;color:#f92672&#34;&gt;root&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;/home/username/mysite/public/&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;#Absolute path to where your hugo site is
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;       &lt;span style=&#34;color:#f92672&#34;&gt;index&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;index.html&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;# Hugo generates HTML
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;
       &lt;span style=&#34;color:#f92672&#34;&gt;location&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;/&lt;/span&gt; {
               &lt;span style=&#34;color:#f92672&#34;&gt;try_files&lt;/span&gt; $uri $uri/ =&lt;span style=&#34;color:#ae81ff&#34;&gt;404&lt;/span&gt;;
               &lt;span style=&#34;color:#f92672&#34;&gt;add_header&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Access-Control-Allow-Origin&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;*&amp;#39;&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;# Allow access to resources (for www and non www)
&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;       }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To enable this site, we need to create a symlink from your site into &lt;code&gt;sites-enabled&lt;/code&gt;. Use absolute filepaths to avoid symlink confusion.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo rm /etc/nginx/sites-enabled/default
sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/mysite
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can run and enable NGINX with the following commands:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo systemctl start nginx
sudo systemctl enable nginx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;quick-checks&#34;&gt;Quick Checks&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Did you set your registrars nameservers to point at the server you&amp;rsquo;re using to host?&lt;/li&gt;
&lt;li&gt;Did you create A records with your hosting provider to direct requests to the correct server? (add a separate A record for the www subdomain)&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;adding-ssl&#34;&gt;Adding SSL&lt;/h1&gt;
&lt;p&gt;SSL is a must these days, and it&amp;rsquo;s never been easier to implement. I went with &lt;a href=&#34;https://certbot.eff.org/&#34;&gt;Certbot&lt;/a&gt;, because it&amp;rsquo;s easy to use and hey, who doesn&amp;rsquo;t love the EFF?&lt;/p&gt;
&lt;p&gt;Visit the certbot site to get customized instructions based on your setup, but here is the process for NGINX running on Ubuntu 18.04:&lt;/p&gt;
&lt;p&gt;First we add the certbot PPA:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then we install certbot itself&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo apt-get install certbot python-certbot-nginx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And finally we run the setup script:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;sudo certbot --nginx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and go through the steps.&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Assuming you have set things up correctly, you should have an easy to use site built by hugo, but running with the powerful NGINX suite.&lt;/p&gt;
&lt;p&gt;To update the site, simply write more markdown files and run &lt;code&gt;hugo&lt;/code&gt; from the site root to rebuild the site.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Using Lambda Functions in Python λ</title>
      <link>https://gideonwolfe.com/posts/programming/python/lambda/lambdapython/</link>
      <pubDate>Thu, 20 Jun 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/programming/python/lambda/lambdapython/</guid>
      <description>&lt;h1 id=&#34;what-are-lambda-functions&#34;&gt;What are lambda functions?&lt;/h1&gt;
&lt;p&gt;In Python, lambda functions are a syntax that allows the use of &lt;a href=&#34;https://en.wikipedia.org/wiki/Anonymous_function&#34;&gt;anonymous functions&lt;/a&gt; in ones code.&lt;/p&gt;
&lt;p&gt;Lambda functions take any number of inputs, perform some computation on these inputs, and return the result of this computation.&lt;/p&gt;
&lt;p&gt;To best illustrate the uses of lambda functions, let&amp;rsquo;s first examine a normal function which takes in two numbers, &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;, multiplies them, and returns the result.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Function that multiplies two numbers&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;multiplyTwoNumbers&lt;/span&gt;(x, y):
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; x&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;y
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now let&amp;rsquo;s see how this looks as a lambda function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; g &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;lambda&lt;/span&gt; x, y: x&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;y
&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt;(g(&lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;))
&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;18&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Lambda functions contain an implicit return call&lt;/li&gt;
&lt;li&gt;Lambda functions contain only one expression&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;why-use-lambda-functions&#34;&gt;Why use lambda functions?&lt;/h1&gt;
&lt;p&gt;Lambda functions work best when a computation needs to be done but does not necessitate a separate function.&lt;/p&gt;
&lt;p&gt;In our last example we only saved one line of code. Let&amp;rsquo;s showcase the true strengths of anonymous functions.&lt;/p&gt;
&lt;p&gt;For our example, say we need to find the value of &lt;code&gt;x % 10&lt;/code&gt; for every element &lt;code&gt;x&lt;/code&gt; in a list. Using traditional code, it may look something like this.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# This code preforms modulus 10 on every element in a list&lt;/span&gt;

&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;getMod&lt;/span&gt;(x):
    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;(x&lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;)

myList &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#ae81ff&#34;&gt;44&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;98&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;34&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;17&lt;/span&gt;]                              
newList &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; []

&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; myList:
    newList[i] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; getMod(i)

&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt;(newList)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This gives us &lt;code&gt;[4, 2, 8, 4, 7]&lt;/code&gt;. Let&amp;rsquo;s clean this up with a lambda expression.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# This code preforms modulus 10 on every element in a list&lt;/span&gt;

myList &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#ae81ff&#34;&gt;44&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;98&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;34&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;17&lt;/span&gt;]
newList &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; list(map(&lt;span style=&#34;color:#66d9ef&#34;&gt;lambda&lt;/span&gt; x: x&lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;, myList))
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt;(newList)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The result is &lt;code&gt;[4, 2, 8, 4, 7]&lt;/code&gt;, just as expected.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;map&lt;/code&gt; function takes two inputs: A function, and a list of arguments to pass to it.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;map&lt;/code&gt; returns a &lt;code&gt;map object&lt;/code&gt;, so we cast it to a list in order to read it.&lt;/li&gt;
&lt;li&gt;Lambda functions can declared inline and thrown away. No declaration or variable assignment required.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;lambda-functions-and-filter&#34;&gt;Lambda functions and &lt;code&gt;filter()&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;Here is an example of the &lt;code&gt;filter()&lt;/code&gt; function in python. &lt;code&gt;filter()&lt;/code&gt; takes in two arguments:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A function object, (in this case a lambda function) which returns a boolean&lt;/li&gt;
&lt;li&gt;Iterable list of aguments&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;filter()&lt;/code&gt; works similarly to &lt;code&gt;map()&lt;/code&gt; except only the values for which our lambda function returns &lt;code&gt;True&lt;/code&gt; are added to the list&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s say we wanted to filter out numbers that are &lt;em&gt;not&lt;/em&gt; a multiple of three.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;myList &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#ae81ff&#34;&gt;44&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;12&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;98&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;34&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;17&lt;/span&gt;]
newList &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;list(filter(&lt;span style=&#34;color:#66d9ef&#34;&gt;lambda&lt;/span&gt; x: x&lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, myList))
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt;(newList)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This returns &lt;code&gt;[12]&lt;/code&gt;, which makes sense because it is the only multiple of three in our list. This is certainly better than a for loop with a traditionally defined function!&lt;/p&gt;
&lt;h1 id=&#34;lambda-functions-and-reduce&#34;&gt;Lambda functions and &lt;code&gt;reduce()&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;The reduce function is used when one wishes to perform a rolling computation on an iterable. For example, let&amp;rsquo;s say you wanted to find the product of numbers in a list. Using traditional python, it might look something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# code to find the product of all elements in a list&lt;/span&gt;

myList &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt;]                                            
total &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; myList:
	total &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; total&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;i
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt;(total)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The output here is &lt;code&gt;720&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The same process using a lambda expression and &lt;code&gt;reduce()&lt;/code&gt; looks something like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; functools &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; reduce  
myList &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt;]                                            
&lt;span style=&#34;color:#66d9ef&#34;&gt;print&lt;/span&gt;(reduce(&lt;span style=&#34;color:#66d9ef&#34;&gt;lambda&lt;/span&gt; x,y: x&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;y , myList))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Again, the output is &lt;code&gt;720&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Basically, the reduce function is performing the following operation:&lt;/p&gt;
&lt;p&gt;$$ ((((2 * 3) * 4 ) * 5) * 6)  $$&lt;/p&gt;
&lt;p&gt;Pretty nifty, huh? 😄&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Lambda functions. Used by CS students trying to flex on their classmates? Indeed. Valuable and useful tool to optimize quick calculations? Hell yes.&lt;/p&gt;
&lt;p&gt;We learned how to leverage lambda expressions with the &lt;code&gt;map()&lt;/code&gt;, &lt;code&gt;reduce()&lt;/code&gt;, and &lt;code&gt;filter()&lt;/code&gt; functions to make quick data processing a breeze. These are some pretty trivial examples but the concept can be extrapolated to fit real world applications.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Theming gnuplot</title>
      <link>https://gideonwolfe.com/posts/gnuplot/theming/</link>
      <pubDate>Tue, 18 Jun 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/gnuplot/theming/</guid>
      <description>&lt;h1 id=&#34;overview&#34;&gt;Overview&lt;/h1&gt;
&lt;p&gt;If you have read any of my other posts, you know how important it is to have a cohesive looking system. I recently developed &lt;a href=&#34;https://github.com/GideonWolfe/Zathura-Pywal&#34;&gt;Zathura-Pywal&lt;/a&gt;, a tool that recolors PDFs in zathura based on your colorscheme.&lt;/p&gt;
&lt;p&gt;In that same vein, I have whipped up a set of scripts to do the same thing for gnuplot. If you haven&amp;rsquo;t heard of gnuplot, check out my short tutorial &lt;a href=&#34;http://gideonwolfe.com/posts/gnuplot/intro/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;how-to-install&#34;&gt;How to install&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;git clone https://github.com/GideonWolfe/Gnuplot-Pywal&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cd Gnuplot-Pywal&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo ./install.sh&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now here&amp;rsquo;s the thing to remember. Instead of running &lt;code&gt;gnuplot&lt;/code&gt;, you now have to run &lt;code&gt;gplot&lt;/code&gt; to get the freshly themed config. You can mess with the aliases however you like, but the config generation script must be called.&lt;/p&gt;
&lt;p&gt;
  &lt;img src=&#34;https://gideonwolfe.com/img/gnuplot/theming/1.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


$$ \frac{sin(x^2 + y^2)}{x^2 + y^2} $$&lt;/p&gt;
&lt;h1 id=&#34;how-it-works&#34;&gt;How it works&lt;/h1&gt;
&lt;p&gt;These are pretty short scripts, so I&amp;rsquo;ll be brief. When the command &lt;code&gt;gplot&lt;/code&gt; is run, it  immediately calls another program &lt;code&gt;gengnuplotconfig&lt;/code&gt;. Aside from some optional tinkering, you should never have to interact with this program.&lt;/p&gt;
&lt;p&gt;When &lt;code&gt;gengnuplotconfig&lt;/code&gt; is called, it imports colors from a cache created by pywal. It then pipes out a gnuplot configuration, using color values from your colorscheme. These can be tweaked to your preference.&lt;/p&gt;
&lt;p&gt;in &lt;code&gt;gplot&lt;/code&gt;, the output of &lt;code&gt;gengnuplotconfig&lt;/code&gt; is being redirected into the file &lt;code&gt;~/.gnuplot&lt;/code&gt;, which is the default configuration file used by gnuplot.&lt;/p&gt;
&lt;p&gt;Finally with this new configuration in place, gnuplot is launched. The delay is imperceptible and the colorscheme usually comes out looking pretty good.&lt;/p&gt;
&lt;p&gt;
  &lt;img src=&#34;https://gideonwolfe.com/img/gnuplot/theming/2.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


$$ (sin(x) * cos(y)) - tan(y^2)$$&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Could this have been done better? Probably 😄. But that&amp;rsquo;s what happens when you do an entire project between one and three in the morning.&lt;/p&gt;
&lt;p&gt;Do not hesitate to contact me with any ideas for projects you would like to see!&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/gnuplot/theming/3.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;$$ cos(u) * (cos(v)+3), sin(u) * (cos(v)+3), sin(v) $$&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Introduction to gnuplot</title>
      <link>https://gideonwolfe.com/posts/gnuplot/intro/</link>
      <pubDate>Sat, 15 Jun 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/gnuplot/intro/</guid>
      <description>&lt;p&gt;Have you ever been frustrated in math classes due to lack of visual examples of abstract topics? Have you ever wanted to quickly visualize a dataset without going through cumbersome software like Excel?&lt;/p&gt;
&lt;p&gt;If so, you should know about &lt;a href=&#34;http://www.gnuplot.info/&#34;&gt;gnuplot&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Gnuplot is a command line based graphing and plotting utility. In this post, I&amp;rsquo;ll outline some practical applications of gnuplot as well as some tips.&lt;/p&gt;
&lt;h1 id=&#34;install-gnuplot&#34;&gt;Install gnuplot&lt;/h1&gt;
&lt;p&gt;Most distos should have gnuplot in their repositories. I installed gnuplot on Arch linux by running &lt;code&gt;sudo pacman -Syu gnuplot&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;To start using gnuplot, fire up your favorite terminal and run &lt;code&gt;gnuplot&lt;/code&gt;. You should be faced with a prompt like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;	G N U P L O T
	Version 5.2 patchlevel 7    last modified 2019-05-29 

	Copyright (C) 1986-1993, 1998, 2004, 2007-2018
	Thomas Williams, Colin Kelley and many others

	gnuplot home:     http://www.gnuplot.info
	faq, bugs, etc:   type &amp;quot;help FAQ&amp;quot;
	immediate help:   type &amp;quot;help&amp;quot;  (plot window: hit &#39;h&#39;)

Terminal type is now &#39;qt&#39;
gnuplot&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;2d-plotting&#34;&gt;2D Plotting&lt;/h1&gt;
&lt;p&gt;Now we are ready to start graphing. Let&amp;rsquo;s start with the simple function.&lt;/p&gt;
&lt;p&gt;To plot this in gnuplot, simply enter the following into your prompt:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;plot x**3 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;\mathring{g}&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/gnuplot/intro/1.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;This looks pretty much like we would expect it to. If we want to plot multiple functions to compare, we can simply add it to the plot command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;plot sin(x), cos(x)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;
  &lt;img src=&#34;https://gideonwolfe.com/img/gnuplot/intro/2.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


$$f(x) = sin(x)$$&lt;/p&gt;
&lt;p&gt;$$g(x) = cos(x)$$&lt;/p&gt;
&lt;h1 id=&#34;3d-plotting&#34;&gt;3D plotting&lt;/h1&gt;
&lt;p&gt;Plotting functions in two dimensions is great, but what about three dimensional functions?
Let&amp;rsquo;s see what&lt;/p&gt;
&lt;p&gt;$$ f(x) = sin(x)*cos(y) $$&lt;/p&gt;
&lt;p&gt;looks like in 3D. Enter the following into gnuplot:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set isosamples 50
set hidden3d
splot [0:2*pi] [0:2*pi] sin(x)*cos(y)
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;set hidden3d&lt;/code&gt; command disables the wireframe, making it easier to see the contours of the 3D objects. Try it both ways with the &lt;code&gt;unset hidden3d&lt;/code&gt; command, use whichever you prefer.&lt;/li&gt;
&lt;li&gt;Setting our isosamples to 50 gives us a much smoother plot.&lt;/li&gt;
&lt;li&gt;In gnuplot, the &lt;code&gt;splot&lt;/code&gt;is identical to the &lt;code&gt;plot&lt;/code&gt; command, except it will make a 3-dimensional plot.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;[0:2*pi] [0:2*pi]&lt;/code&gt; section specifies a domain for each of these functions, which is zero to 2π (the period of the cosine and sine functions)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After running these commands, we get&lt;/p&gt;
&lt;p&gt;
  &lt;img src=&#34;https://gideonwolfe.com/img/gnuplot/intro/3.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


$$ f(x) = sin(x)*cos(y) $$&lt;/p&gt;
&lt;p&gt;I would recommend checking out the gnuplot &lt;a href=&#34;http://gnuplot.sourceforge.net/demo/&#34;&gt;demos page&lt;/a&gt;, which has tons of functions and scripts to play around with. There are many more features than I could ever hope to cover here, so this is a great place to explore.&lt;/p&gt;
&lt;h1 id=&#34;plotting-data&#34;&gt;Plotting data&lt;/h1&gt;
&lt;p&gt;Say that we ran some experiments and we wanted to quickly plot the results. To keep things simple, let&amp;rsquo;s start out with a 2D graph that might be commonplace on homework assignments and research projects.
First, we need our data file. Data files in gnuplot use the &lt;code&gt;.d&lt;/code&gt; extension by default. In the case of 2 dimensions, there will be two space-separated columns for our points, with two line breaks signifying a new data block.&lt;/p&gt;
&lt;p&gt;For this example, I using a classic classroom experiment of tracking the growth of plants over time. The left column represents the day, and the right hand is the height in inches.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;# Flower number one
1 1.3
2 1.8
3 2.1
4 2.4
5 2.4
6 2.9
7 3.2


# Flower number two
1 1.0
2 1.1
3 1.6
4 2.1
5 2.6
6 3.0
7 3.3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To plot this data, we can simply run&lt;/p&gt;
&lt;p&gt;&lt;code&gt;plot &#39;flowers.d&#39;&lt;/code&gt;&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/gnuplot/intro/4.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;This looks OK, but it doesn&amp;rsquo;t really tell the whole story and it certainly isn&amp;rsquo;t up to research (or even science fair) standards. Let&amp;rsquo;s spruce this plot up a bit!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set title font &amp;quot;Helvetica,14&amp;quot;
set title &#39;Flower Growth Over Seven Days&#39;
set xlabel &#39;Time (Days Elapsed)&#39;
set ylabel &amp;quot;Height (Inches)&amp;quot;
plot &#39;flowers.d&#39; index 0 w lp lw 3 title &#39;Flower 1&#39;, &#39;flowers.d&#39; index 1 w lp lw 3 title &#39;Flower 2&#39;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;index&lt;/code&gt; chooses the block from the dataset to plot (each block is separated by two blank lines)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;w lp&lt;/code&gt;: short for &lt;code&gt;with linepoints&lt;/code&gt;, which styles the lines&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lw&lt;/code&gt;: short for &lt;code&gt;line width&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;title&lt;/code&gt; sets the key label for the corresponding data block&lt;/li&gt;
&lt;/ul&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/gnuplot/intro/5.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Looks much better!&lt;/p&gt;
&lt;h1 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;We learned how to use gnuplot to quickly create a graph out of experimental data, as well as plot equations in two and three dimensions. I have barely scratched the surface of this program, and I will share my knowledge with you as I continue to learn. In the future, I want to explore more advanced gnuplot features such as parametric equations and data fitting. I also hope to develop an automatic gnuplot theming script, that would act like my &lt;a href=&#34;https://github.com/GideonWolfe/Zathura-Pywal&#34;&gt;Zathura-Pywal&lt;/a&gt; utility and automatically color gnuplot based on the system colors. Keep an eye out for updates!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Workflow Optimization Part 4: Theming Your System</title>
      <link>https://gideonwolfe.com/posts/workflow/theming/</link>
      <pubDate>Mon, 03 Jun 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/workflow/theming/</guid>
      <description>&lt;h1 id=&#34;why-care-about-themes&#34;&gt;Why care about themes?&lt;/h1&gt;
&lt;p&gt;Why spend so much time theming your system when you could actually be getting work done? I get this question a lot, and I&amp;rsquo;ll attempt to explain my reasoning.&lt;/p&gt;
&lt;p&gt;When you look at a typical system doing many tasks, you can see a mosaic of different programs floating around and cluttering your desktop. Each of these programs has their own UI, colorscheme, and style. Just take a look at all of the right click context menus in stock Windows 10. If you can&amp;rsquo;t unify design within a single OS, how do you expect to get an entire system looking cohesive?&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/theming/Win10.jpg&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px;&#34;  /&gt;


&lt;p&gt;Windows 10 is a particularly egregious example of bad UI/UX consistency in software, and I&amp;rsquo;ll leave it at that before I launch into an involuntary anti-Windows rant.&lt;/p&gt;
&lt;p&gt;My point is, that having a system that looks like the result of a long list of poor design choices makes the system feel worse to use. Sure, it may not effect raw speed, but it makes the overall system feel unpolished. Imagine I had a Toyota, with the bumpers of a Corolla, the dashboard of a Prius, the bed of a Tacoma, and the interior of a Rav 4. Sure it may run fine, but it&amp;rsquo;s going to be hell to work on. Even though they are part of the same &amp;ldquo;system&amp;rdquo;, none of the parts fit together quite right. Nothing feels natural, because you can&amp;rsquo;t rely on anything working the same way twice.&lt;/p&gt;
&lt;h1 id=&#34;as-linux-users-how-can-we-do-better&#34;&gt;As Linux users, how can we do better?&lt;/h1&gt;
&lt;p&gt;Good news on that front. I can&amp;rsquo;t think of a single mainstream distro that does a worse job at UI/UX than Windows.&lt;/p&gt;
&lt;p&gt;On Linux, most of the UI is handled by your desktop environment, or DE. If you&amp;rsquo;re looking for a traditional GUI experience, you can turn to the likes of Cinnamon, KDE, Unity, GNOME, Budgie, and countless others. Most of these DEs are OS agnostic, meaning they can be installed on top of any operating system. This gives you the ability to experiment with different DEs without changing your whole OS, and even run multiple DEs simultaneously.&lt;/p&gt;
&lt;h1 id=&#34;theming-my-system&#34;&gt;Theming My System&lt;/h1&gt;
&lt;p&gt;When I initially started theming my system, I envisioned something reminiscent of a sci-fi computer system.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/theming/scifi.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 1279px; height: 720px;&#34;  /&gt;


&lt;p&gt;Every program looks like it was a handmade for that particular system, and feels like a cohesive state of the art machine. However, a setup like the one above isn&amp;rsquo;t as versatile as I need my systems to be. If you want to try one out for kicks, I recommend a &lt;a href=&#34;https://github.com/GitSquared/edex-ui&#34;&gt;eDEX-UI&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As you may have guessed, I do not prefer a traditional GUI experience. I use i3, which is a &lt;em&gt;window&lt;/em&gt; manager as opposed to a &lt;em&gt;desktop&lt;/em&gt; manager. Since I don&amp;rsquo;t have a desktop with icons, or a main settings menu, I simply manage my windows using i3, no DE required. To get some of the nice features that come with DEs (such as a statusbar and tray), I opt to use an array of &lt;a href=&#34;http://gideonwolfe.com/posts/workflow/sidekickprograms/&#34;&gt;helper programs&lt;/a&gt; to add this functionality. Since I mainly use terminals for my day to day work, theming programs in the terminal is my primary concern.&lt;/p&gt;
&lt;p&gt;The cornerstone of my theme is a program called &lt;a href=&#34;https://github.com/dylanaraps/pywal&#34;&gt;pywal&lt;/a&gt;. pywal takes an image as input, and generates a colorscheme based on the colors in the image. Additionally, pywal has an assortment of built in colorschemes, no image required.&lt;/p&gt;
&lt;p&gt;pywal can also be used with different image backends to alter the final colorscheme, giving you a lot of ways to get the colors you want. In the future I want to look into &lt;a href=&#34;https://github.com/deviantfero/wpgtk&#34;&gt;wpgtk&lt;/a&gt;, which is a theming framework that utilizes pywal. This can be used to generate themes for GUI apps too!&lt;/p&gt;
&lt;p&gt;When pywal generates colors, it stores them in a few places.&lt;/p&gt;
&lt;p&gt;Firstly, there is your cache, where wal stores the current colors in many formats. Many programs can be pointed directly at these files to set the theme.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tree .cache/wal/

├── colors
├── colors.css
├── colors.hs
├── colors.json
├── colors-kitty.conf
├── colors-konsole.colorscheme
├── colors-oomox
├── colors-putty.reg
├── colors.reg
├── colors-rofi-dark.rasi
├── colors-rofi-light.rasi
├── colors.scss
├── colors.sh
├── colors-speedcrunch.json
├── colors-sway
├── colors-tty.sh
├── colors-wal-dmenu.h
├── colors-wal-dwm.h
├── colors-wal-st.h
├── colors-wal-tabbed.h
├── colors-wal.vim
├── colors-waybar.css
├── colors.xresources
├── colors.Xresources
├── colors.yml
├── firefox.css
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Many programs take their colors from .Xresources. I simply add the section below to my .Xresources to make the colorscheme available to programs.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*.color0: {color0}
*color0:  {color0}
*.color1: {color1}
*color1:  {color1}
*.color2: {color2}
*color2:  {color2}
*.color3: {color3}
*color3:  {color3}
*.color4: {color4}
*color4:  {color4}
*.color5: {color5}
*color5:  {color5}
*.color6: {color6}
*color6:  {color6}
*.color7: {color7}
*color7:  {color7}
*.color8: {color8}
*color8:  {color8}
*.color9: {color9}
*color9:  {color9}
*.color10: {color10}
*color10:  {color10}
*.color11: {color11}
*color11:  {color11}
*.color12: {color12}
*color12:  {color12}
*.color13: {color13}
*color13:  {color13}
*.color14: {color14}
*color14:  {color14}
*.color15: {color15}
*color15: {color15}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This should cover most TUI programs, because they generally just inherit colors from your terminal. Sometimes there are programs that don&amp;rsquo;t run in the terminal, or don&amp;rsquo;t automatically take colors from .Xresources.
In the case of the former, your best bet is to look for a wal theme or skin. If the program in question is easily themable, you can probably plug wal colors into it. You can check &lt;a href=&#34;https://github.com/dylanaraps/pywal/wiki/Customization&#34;&gt;this&lt;/a&gt; page to see all of the programs wal works with.&lt;/p&gt;
&lt;p&gt;I even wrote my own &lt;a href=&#34;https://github.com/GideonWolfe/Zathura-Pywal&#34;&gt;script&lt;/a&gt; for the Zathura document viewer that dynamically pulls colors from the current wal colorscheme. Solutions like this are pretty easy to implement with a bit of know how.&lt;/p&gt;
&lt;p&gt;Finally, the browser. I am using FireFox, which allows you to edit the CSS of how the browser actually looks. Take a look at my repo for the files. I wrote my own startpage, which is dynamically themed using the current colorscheme. The same scheme is applied to the core UI, but you need to restart the browser for this to take effect.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/theming/browser.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 1279px; height: 720px;&#34;  /&gt;


&lt;p&gt;This about sums up the themes I use in my system. Take a look at my &lt;a href=&#34;http://gideonwolfe.com/posts/workflow/sidekickprograms/&#34;&gt;helper programs&lt;/a&gt; post for info on how I configure specific programs.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Programming in Neovim</title>
      <link>https://gideonwolfe.com/posts/programming/general/texteditor/</link>
      <pubDate>Tue, 28 May 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/programming/general/texteditor/</guid>
      <description>&lt;h1 id=&#34;why-vim&#34;&gt;Why Vim?&lt;/h1&gt;
&lt;p&gt;When people in the development community hear the word vim, they generally think one of three things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;That nightmare program that I can never seem to exit, much less learn. mainly used by elitists.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A powerful and customizable text editor that is worth the steep learning curve.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The fact you are not using Emacs sickens me to my very core&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Today we are going to look at vim, and see why when utilized correctly, it can be an essential tool in your toolbox.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t get me wrong, emacs is cool, and I have colleagues who use it and love it. Emacs can certainly do many things that vim cannot, which is both a blessing and a curse.
If you recall my first post, I refer to the Unix philosophy as a guiding principle to my workflow. Unfortunately, when used to it&amp;rsquo;s fullest capacity, emacs goes against that philosophy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Emacs is a great operating system&amp;hellip; All it needs is a good text editor.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is a quip I hear often around developers, many who use emacs themselves. Like vim, emacs is quite extensible, taking advantage of a custom scripting language called Emacs-lisp, or &lt;a href=&#34;https://en.wikipedia.org/wiki/Emacs_Lisp&#34;&gt;elisp&lt;/a&gt;. The combination of elisp with a GUI emacs client has lead to a large ecosystem of user created applications and extensions that work right within emacs. Inherently, there is nothing wrong with this. Extensibility like this is part of makes vim great. However, at a certain point I have to question the scope of how a text editor should be used in one&amp;rsquo;s workflow,&lt;/p&gt;
&lt;p&gt;On &lt;a href=&#34;https://melpa.org/#/&#34;&gt;Milkypostman’s Emacs Lisp Package Archive&lt;/a&gt; or MELPA, one can browse over 4,000 emacs packages, from &lt;a href=&#34;https://melpa.org/#/calfw&#34;&gt;calendars&lt;/a&gt; to fully fledged &lt;a href=&#34;https://melpa.org/#/emms&#34;&gt;multimedia systems&lt;/a&gt;. If you really set your mind to it, you could build an emacs that contains every tool you need in your workflow, and work without every having to leave emacs. As you can see, this is quite contrary to the unix philosophy of every program being very good at &lt;strong&gt;one&lt;/strong&gt; thing.&lt;/p&gt;
&lt;p&gt;I use separate programs to handle separate tasks, and I wouldn&amp;rsquo;t really use the apps available to emacs. Without these features, there is nothing that sets emacs apart over vim, besides more difficult keybinds. At that point they are both text editors and do that job well.&lt;/p&gt;
&lt;p&gt;To answer the original question I posed in this section; I use vim because it is efficient, and it is universal.
No matter the job, whether that be spinning up virtual machines or SSHing into remote servers to work, I can count on a vim-like program being installed. You may not have all your customizations, but that is quickly fixed by copying over your .vimrc file.&lt;/p&gt;
&lt;p&gt;If you haven&amp;rsquo;t used vim before, I reccommend getting used to the commands. If you are running classic vim, you can run &lt;code&gt;vimtutor&lt;/code&gt; in your terminal, and you can work through these examples. If not, there are &lt;a href=&#34;https://vim-adventures.com/&#34;&gt;fun&lt;/a&gt; ways to get acquainted with the system.&lt;/p&gt;
&lt;p&gt;Learning the language of vim commands allows you to surgically edit files at lightning speed, all without leaving the comfort of your terminal. In this post, I&amp;rsquo;ll go over some of the customizations that really take vim to the next level.&lt;/p&gt;
&lt;h1 id=&#34;customizing-vim&#34;&gt;Customizing Vim&lt;/h1&gt;
&lt;p&gt;I use a fork of vim called &lt;a href=&#34;https://neovim.io/&#34;&gt;neovim&lt;/a&gt;. Neovim adds a lot of much needed features to vim, and has even better support for extensions and customization. However, most of these tips should translate to legacy vim as well.&lt;/p&gt;
&lt;p&gt;To see my full and up to date configuration, take a look at my &lt;a href=&#34;https://github.com/GideonWolfe/PC-dotfiles/blob/master/.config/nvim/init.vim&#34;&gt;init.vim&lt;/a&gt; file.&lt;/p&gt;
&lt;h2 id=&#34;changing-some-defaults&#34;&gt;Changing some defaults&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot; Statusline Config: Show filename and leave room for extensions to show output
set statusline+=%*
set statusline+=%F
set cmdheight=2

&amp;quot; Tab Settings: 1 tab = 4 spaces
set expandtab           
set tabstop=4           
set shiftwidth=4

&amp;quot; Misc
set showmatch &amp;quot;shows matching braces/parens
set formatoptions+=o
set number
set nocompatible
filetype off
set background=dark
colorscheme wal
set clipboard=unnamed 

&amp;quot; Relative line numbers
augroup numbertoggle
  autocmd!
  autocmd BufEnter,FocusGained,InsertLeave * set relativenumber
  autocmd BufLeave,FocusLost,InsertEnter   * set norelativenumber
augroup END

&amp;quot; Show next 3 lines while scrolling.
if !&amp;amp;scrolloff
    set scrolloff=3       
endif

&amp;quot; Show next 5 columns while side-scrolling.
if !&amp;amp;sidescrolloff
    set sidescrolloff=5   
endif
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;managing-plugins&#34;&gt;Managing plugins&lt;/h2&gt;
&lt;p&gt;For a plugin manager, I chose &lt;a href=&#34;https://github.com/VundleVim/Vundle.vim&#34;&gt;Vundle&lt;/a&gt;. Most plugin managers for vim are similar in use, and instructions for popular ones can be found on the pages for most vim plugins.&lt;/p&gt;
&lt;p&gt;To enable vundle, we add the following to our vim configuration:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-configuration&#34; data-lang=&#34;configuration&#34;&gt;set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin &#39;VundleVim/Vundle.vim&#39;



call vundle#end()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The third line of this excerpt declares Vundle, which itself is a plugin. However, we can follow this format and add any plugin using it&amp;rsquo;s github repo (username/repo). Here is a list of some of the must have plugins I use.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/honza/vim-snippets&#34;&gt;Vim snippets&lt;/a&gt; / &lt;a href=&#34;https://github.com/sirver/UltiSnips&#34;&gt;utilsnips&lt;/a&gt;: Together, these plugins provide an extensible engine for quick code snippets. Quickly write boilerplate code so you can focus on the tough stuff.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/Shougo/deoplete.nvim&#34;&gt;deoplete&lt;/a&gt;: Great autocompletion engine&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/w0rp/ale&#34;&gt;ALE&lt;/a&gt;: All purpose linter. Highlights errors and warnings in most programming languages.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After you add the plugins you want to your config, open any vim buffer and run :PluginInstall, which will attempt to&amp;hellip; Well, install your plugins.&lt;/p&gt;
&lt;p&gt;Look in my &lt;a href=&#34;https://github.com/GideonWolfe/PC-dotfiles/blob/master/.config/nvim/init.vim&#34;&gt;init.vim&lt;/a&gt; to see all of the specific plugins I use and how I configure them.&lt;/p&gt;

  &lt;img src=&#34;https://gideonwolfe.com/img/neovim/vimshot.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 1279px; height: 720px;&#34;  /&gt;


&lt;p&gt;This is only the tip of the iceberg. I am constantly discovering new plugins to enhance vim, all without leaving it&amp;rsquo;s scope as a text editor.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Workflow Optimization Part 3: Sidekick Programs for i3</title>
      <link>https://gideonwolfe.com/posts/workflow/sidekickprograms/</link>
      <pubDate>Tue, 02 Apr 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/workflow/sidekickprograms/</guid>
      <description>&lt;p&gt;i3 comes perfectly usable out of the box, but If there&amp;rsquo;s one thing you should have learned by now, I like customizing &lt;em&gt;everything&lt;/em&gt;.
By default, i3 comes with basic tools to facilitate a tiling WM workflow. That being said, there are some programs that are must haves in my opinion, that don&amp;rsquo;t come with i3.&lt;/p&gt;
&lt;h1 id=&#34;polybar&#34;&gt;Polybar&lt;/h1&gt;
&lt;p&gt;i3 comes with i3bar installed and enabled by defult. i3bar is a perfectly fine status bar, and if you&amp;rsquo;re interested in using it, I recommend checking out &lt;a href=&#34;https://www.youtube.com/watch?v=gKumet6b-WY&#34;&gt;Luke Smith&amp;rsquo;s&lt;/a&gt; overview of his i3bar setup. However, I prefer
&lt;a href=&#34;https://github.com/jaagr/polybar&#34;&gt;polybar&lt;/a&gt;, mostly for aesthetic reasons.&lt;/p&gt;
&lt;h2 id=&#34;configuring-polybar&#34;&gt;Configuring polybar&lt;/h2&gt;
&lt;p&gt;Configuring polybar is pretty straightforward. By default, there a config file located at &lt;code&gt;~/.config/polybar/config&lt;/code&gt;. The name of the default bar is example. Simply run &lt;code&gt;polybar example&lt;/code&gt; to start the bar. I recomend starting the bar from a terminal so you can see any errors polybar may throw at you. These errors will mostly warn you about misconfigurations in your config file, missing fonts, and the like.&lt;/p&gt;
&lt;p&gt;To get started with your custom config, I recommend looking at &lt;a href=&#34;https://www.reddit.com/r/unixporn/search?q=polybar&amp;amp;include_over_18=on&amp;amp;sort=relevance&amp;amp;t=all&#34;&gt;reddit&lt;/a&gt;, and the &lt;a href=&#34;https://github.com/arcolinux/arcolinux-polybar/blob/master/etc/skel/.config/polybar/config&#34;&gt;Arco Linux dotfiles&lt;/a&gt; for interesting modules. The creator of polybar also has some &lt;a href=&#34;https://github.com/jaagr/dots/tree/master/.local/etc/themer/themes&#34;&gt;slick looking themes&lt;/a&gt; on his repo. Basically, you can copy the modules from any polybar config, and edit the specifics to  suite your needs.&lt;/p&gt;
&lt;p&gt;For example, here is my configuration for the download speed module, seen in the top right of my statusbar.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;module/networkspeeddown&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
;https://github.com/jaagr/polybar/wiki/Module:-network
type &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; internal/network
interface &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; wlp3s0
;interface &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; enp14s0
;interface &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; enp0s31f6
;interface &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; enp4s0
label-connected &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;%downspeed:7%&amp;#34;&lt;/span&gt;
format-connected &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &amp;lt;label-connected&amp;gt;
format-connected-prefix &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
format-connected-prefix-foreground &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;colors.foreground-alt&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;
format-connected-foreground &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;colors.foreground&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;
format-connected-background &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;colors.background&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;
;format-connected-underline &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;#62FF00&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This module is a stock polybar module, but it won&amp;rsquo;t work if you don&amp;rsquo;t uncomment the correct interface for your system!
I use the following lines to import my colorscheme to polybar.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;colors&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;           
background &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;xrdb:color0:#222&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;    
background-alt &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;xrdb:color3:#222&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;
foreground &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;xrdb:color7:#222&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;    
foreground-alt &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;xrdb:color2:#555&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;
highlight &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;xrdb:color2:#f00&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;
urgent &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;#f00      &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I have this section to enable a system tray, for programs that use it. Nextcloud, Steam, etc.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;tray-detached &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; false
tray-position &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; right
tray-offset-x &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
tray-offset-y &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
tray-maxsize &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt;
tray-padding &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
tray-scale &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
tray-background &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;${&lt;/span&gt;colors.background&lt;span style=&#34;color:#e6db74&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Keep running polybar from the terminal until it looks the way you want, without any fatal errors. Then, I add the following line to my i3 config: &lt;code&gt;exec_always pkill -9 polybar ; polybar main&lt;/code&gt;.
This kills and restarts polybar everytime you refresh i3. This is an easy way to quickly reload your polybar config to test things, or if it glitches for some reason.&lt;/p&gt;
&lt;p&gt;Like i3bar, polybar supports many custom modules and scripts. For example, my cmus module runs a bash command every second to check the status of my music player, cmus. I added some logic for click behavior, and now it is a fully functioning music widget.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;module/player-cmus&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
type &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; custom/script
exec &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ~/.config/polybar/player-cmus.sh
interval &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
click-left &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; cmus-remote -n
click-right &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; cmus-remote -r
click-middle &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; cmus-remote -u
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It really is that simple. The script mentioned above can be found in my &lt;a href=&#34;https://github.com/GideonWolfe/PC-dotfiles/blob/master/.config/polybar/player-cmus.sh&#34;&gt;dotfiles&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;rofi&#34;&gt;Rofi&lt;/h1&gt;
&lt;p&gt;In the default i3 config, there is a built in hotkey to launch dmenu, a program launcher. dmenu is &lt;em&gt;great&lt;/em&gt;. I personally prefer &lt;a href=&#34;https://github.com/davatorium/rofi&#34;&gt;rofi&lt;/a&gt;, because I&amp;rsquo;ve been usig it for a long time now. Both rofi and dmenu serve basically the same purpose. They are general menu applications. This means they can be used for the default purpose, which is to choose and launch programs, but also so much more. You can integrate rofi or dmenu into your statusbar, and create &lt;a href=&#34;https://www.youtube.com/watch?v=R9m723tAurA&#34;&gt;interactive menus&lt;/a&gt; for any possible purpose.&lt;/p&gt;
&lt;h2 id=&#34;configuring-rofi&#34;&gt;Configuring rofi&lt;/h2&gt;
&lt;p&gt;Admittedly, I have been using rofi exclusively as an application launcher. Since I rarely touch the mouse in my workflow, having GUI click-through menus seems counterintuitive for my purpose. The configuration of rofi is pretty straightforward. I literally have a single line in the file &lt;code&gt;~/.config/roficonfig&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;rofi.theme: ~/.cache/wal/colors-rofi-dark.rasi&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This will make rofi check the colorscheme cached by wal the last time I generated a theme. More on that later. Interestingly enough, most of the real configuration is done in &lt;code&gt;~/.Xresources&lt;/code&gt;. The below section gives rofi a pretty slick look in my opinion. Simply edit these settings to your preferences and run &lt;code&gt;sudo xrdb -merge .Xresources&lt;/code&gt; to apply the changes. Arch users may have to download the &lt;code&gt;xorg-xrdb&lt;/code&gt; package in order to run the last command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;! rofi setup      
rofi.color-enabled:         true
rofi.separator-style:       solid
rofi.font:                  curieMedium 20
rofi.bw:                    2
rofi.columns:               1
rofi.yoffset:               0
rofi.fake-transparency:     false
rofi.hide-scrollbar:        true
!rofi.opacity:               90
rofi.location:              0
rofi.width:                 50
rofi.lines:                 10
rofi.fixed-num-lines:       true
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With rofi, there is no need for a taskbar, start menu, or any other cluttered GUI elements. I then edited the keybind in my i3 config to lauch rofi instead of dmenu.&lt;/p&gt;
&lt;h1 id=&#34;other-programs&#34;&gt;Other programs:&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/ranger/ranger&#34;&gt;ranger&lt;/a&gt;: Terminal based file manager. Great for easy browsing and previewing of files.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/schischi/xcwd&#34;&gt;xcwd&lt;/a&gt;: I add &lt;code&gt;bindsym $mod+Shift+Return exec urxvt -cd &amp;quot;``xcwd``&amp;quot;&lt;/code&gt; to my i3 config, and now I have the &amp;ldquo;Open terminal in current directory&amp;rdquo; functionality.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/cjbassi/gotop&#34;&gt;gotop&lt;/a&gt;: Terminal task manager/resource monitor. Functional &lt;em&gt;and&lt;/em&gt; cool looking.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/agarrharr/awesome-cli-apps&#34;&gt;Here&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt; is a list of awesome command line apps. Pick out the ones that you need and suite your workflow! If You&amp;rsquo;re running arch, don&amp;rsquo;t forget to check the AUR for these packages, it makes managing all these programs much easier.&lt;/p&gt;
&lt;p&gt;Next time, we take a closer look at theming.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Markdown test page</title>
      <link>https://gideonwolfe.com/posts/markdowntest/</link>
      <pubDate>Wed, 27 Mar 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/markdowntest/</guid>
      <description>&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Age&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bob&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;del&gt;Crossed Out&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;This is a footnote.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;definitions&#34;&gt;Definitions&lt;/h3&gt;
&lt;dl&gt;
&lt;dt&gt;Cat&lt;/dt&gt;
&lt;dd&gt;Fluffy animal everyone likes&lt;/dd&gt;
&lt;dt&gt;Internet&lt;/dt&gt;
&lt;dd&gt;Vector of transmission for pictures of cats&lt;/dd&gt;
&lt;/dl&gt;
&lt;h3 id=&#34;todo---tasks&#34;&gt;TODO - tasks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[  ] a task list item&lt;/li&gt;
&lt;li&gt;[  ] list syntax required&lt;/li&gt;
&lt;li&gt;[  ] incomplete&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; completed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I ❤️ Hugo!
😗&lt;/p&gt;
&lt;h1 id=&#34;math&#34;&gt;Math&lt;/h1&gt;
&lt;p&gt;$\require{\mhchem}$&lt;/p&gt;
&lt;p&gt;$$\ce{Zn^2+  &amp;lt;=&amp;gt;[+ 2OH-][+ 2H+]&lt;br&gt;
$\underset{\text{zinc hydroxide}}{\ce{Zn(OH)2 v}}
$  &amp;lt;=&amp;gt;[+ 2OH-][+ 2H+]
$\underset{\text{tetrahydroxozincate(II)}}{\ce{[Zn(OH)4]^2-}}$}$$&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;section class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34; role=&#34;doc-endnote&#34;&gt;
&lt;p&gt;the footnote text. &lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description>
    </item>
    
    <item>
      <title>Workflow Optimization Part 2: The i3 Window Manager</title>
      <link>https://gideonwolfe.com/posts/workflow/i3/</link>
      <pubDate>Wed, 27 Mar 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/workflow/i3/</guid>
      <description>&lt;h1 id=&#34;why-use-a-tiling-window-manager&#34;&gt;Why use a tiling window manager?&lt;/h1&gt;
&lt;p&gt;As I touched on in my introductory post, there are many reasons I prefer tiling window managers over traditional desktop environments. Of these reasons, let me highlight three. Efficiency, flexibility, and usability.&lt;/p&gt;
&lt;p&gt;A quick note about i3 and other tiling WMs. While tiling WMs support regular GUI programs, the benefits are most apparent while using the terminal. Most tiling WMs set &amp;ldquo;open terminal&amp;rdquo; as the most fundemental keybind. Most traditional desktop environments are configured with GUI settings menus, but i3 has none. i3 settings and the settings of many programs used with i3 are configured with plain text files. I will be talking about i3 in this series, but most of this applies to all tiling window managers. Check out alternatives like &lt;a href=&#34;https://xmonad.org/&#34;&gt;xmonad&lt;/a&gt;, or &lt;a href=&#34;https://dwm.suckless.org/&#34;&gt;dwm&lt;/a&gt;.&lt;/p&gt;
&lt;h5 id=&#34;efficiency&#34;&gt;Efficiency&lt;/h5&gt;
&lt;p&gt;If tiling window managers excel in one category, it would be efficiency. When we think about how we interact with a traditional desktop environment, we notice that much of our time is spent switching between the mouse and keyboard, or simply rearranging floating windows.&lt;/p&gt;
&lt;p&gt;Tiling window managers allow you to do pretty much everything from the keyboard, eliminating the need to constantly be reaching for the mouse. Since all windows are tiled, they can be manipulated with keybinds. In i3, windows can be stacked, tiled, tabbed, and even floated like in a traditional DE.&lt;/p&gt;
&lt;p&gt;It may seem ludicrous to spend so much effort on shaving a couple seconds off menial tasks. The reality is when you spend hours a day on the computer doing 1000&amp;rsquo;s of small tasks, the time saved really starts to add up.&lt;/p&gt;
&lt;h5 id=&#34;flexibility&#34;&gt;Flexibility&lt;/h5&gt;
&lt;p&gt;i3 is an extremely flexible window manager. Depending on your installation method, your i3 configuration file is located at either &lt;code&gt;$HOME/.i3/config&lt;/code&gt; or &lt;code&gt;$HOME/.config/i3/config&lt;/code&gt;. Within the file, you will find various i3 settings as well as comments describing their purpose. These settings allow you to easily understand and configure i3&amp;rsquo;s core functionality. Applying these changes is as easy as refreshing i3, no recompile required.&lt;/p&gt;
&lt;h5 id=&#34;usability&#34;&gt;Usability&lt;/h5&gt;
&lt;p&gt;To a new user, i3 may look and feel unusable. Like anything unfamiliar, i3 takes a bit of getting used to. After a couple days of glancing at the &lt;a href=&#34;https://i3wm.org/docs/refcard.html&#34;&gt;i3 reference card&lt;/a&gt;, I was pretty much up to my previous work speed. Much like going to a multimonitor setup, once you go to a tiling WM, it is extremely difficult to go back. With every possible action or program just a few keystrokes away, i3 beats digging through endless GUI menus in a traditional DE.&lt;/p&gt;
&lt;h1 id=&#34;my-i3-configuration&#34;&gt;My i3 configuration&lt;/h1&gt;
&lt;p&gt;My full i3 configuration is available &lt;a href=&#34;https://github.com/GideonWolfe/PC-dotfiles/tree/master/.config/i3&#34;&gt;here&lt;/a&gt;, but I will highlight a few of the changes I made to make i3 more usable.&lt;/p&gt;
&lt;h4 id=&#34;basic-keybinds&#34;&gt;Basic keybinds&lt;/h4&gt;
&lt;p&gt;The first thing I do is change the keybindings for window control to use the Vim keys &amp;ldquo;hjkl&amp;rdquo; instead of the i3 default of &amp;ldquo;jkl;&amp;rdquo;. This makes sense because &lt;em&gt;many&lt;/em&gt; terminal based programs incorporate vim keys, and having a single set of keybinds super convenient!&lt;/p&gt;
&lt;h5 id=&#34;gaps&#34;&gt;Gaps&lt;/h5&gt;
&lt;p&gt;I added the snippet below to my i3 config to define some window gaps. I find having no gaps feels claustraphobic, and you can&amp;rsquo;t see your wallpaper! You may want to change these values based on your resolution.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for_window [class=&amp;quot;^.*&amp;quot;] border pixel 3
new_window pixel 4
gaps inner 17
gaps outer 5
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id=&#34;setting-colors-from-xresources&#34;&gt;Setting colors from .Xresources&lt;/h5&gt;
&lt;p&gt;The .Xresources file is a configuration file shared between many applications to define common settings such as colors and fonts. Luckily, i3 gives us an easy way to access these values and use them in our setup.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set_from_resource $bg           i3wm.color3
set_from_resource $bg-alt       i3wm.color0
set_from_resource $fg           i3wm.color15
set_from_resource $fg-alt       i3wm.color2
set_from_resource $hl           i3wm.color4
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now that we have these values defined, let&amp;rsquo;s apply them to our UI elements.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set_from_resource $bg           i3wm.color3
# class                 border  backgr. text indicator      child_border
client.focused          $fg-alt $bg     $fg  $fg-alt        $hl
client.focused_inactive $bg     $bg-alt $fg  $bg            $bg
client.unfocused        $bg     $bg-alt $fg  $bg            $bg
client.urgent           $bg     $bg-alt $fg  $bg            $bg
client.placeholder      $bg     $bg-alt $fg  $bg            $bg
client.background       $bg
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you look in your .Xresources file (create it if it doesn&amp;rsquo;t exist), you should see something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*.color0: {color0}
*color0:  {color0}
*.color1: {color1}
*color1:  {color1}
*.color2: {color2}
*color2:  {color2}
*.color3: {color3}
*color3:  {color3}
*.color4: {color4}
*color4:  {color4}
*.color5: {color5}
*color5:  {color5}
*.color6: {color6}
*color6:  {color6}
*.color7: {color7}
*color7:  {color7}
*.color8: {color8}
*color8:  {color8}
*.color9: {color9}
*color9:  {color9}
*.color10: {color10}
*color10:  {color10}
*.color11: {color11}
*color11:  {color11}
*.color12: {color12}
*color12:  {color12}
*.color13: {color13}
*color13:  {color13}
*.color14: {color14}
*color14:  {color14}
*.color15: {color15}
*color15: {color15}

! Black color that will not be affected by bold highlighting.
*.color66: #131811
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If not, add it. This defines colors for other programs to use.&lt;/p&gt;
&lt;h5 id=&#34;startup-commands&#34;&gt;Startup Commands&lt;/h5&gt;
&lt;p&gt;i3 makes it easy to define custom commands that run when i3 restarts (with a logout/login) or refreshes (Mod+Shift+r by default). Here are the important commands I run.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;exec-always wal -R&lt;/code&gt; tells pywal to reload my last colorscheme every time I refresh i3.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec xset s off
exec xset -dpms
exec xset s noblank
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This setting will disable automatic screen blanking, which I prefer on my machines.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;exec_always urxvt -name math -e bash -c &#39;qalc&#39; 
for_window [instance=&amp;quot;math&amp;quot;] floating enable;
for_window [instance=&amp;quot;math&amp;quot;] move scratchpad; move position center;
bindsym $mod+m [instance=&amp;quot;math&amp;quot;] scratchpad show
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I added this calculator scratchpad which gives me acces to &lt;a href=&#34;https://qalculate.github.io/&#34;&gt;qalculate&lt;/a&gt;, my favorite calculator. Really handy!&lt;/p&gt;
&lt;h5 id=&#34;custom-keybinds&#34;&gt;Custom Keybinds&lt;/h5&gt;
&lt;p&gt;Keybinds in i3 are defined as follows: &lt;code&gt;bindsym $mod+f exec urxvt -e ranger&lt;/code&gt; would launch ranger, a terminal file manager, in my terminal urxvt.&lt;/p&gt;
&lt;p&gt;As long as your program is callable from the terminal, it can be bound to a keybind.&lt;/p&gt;
&lt;h5 id=&#34;misc&#34;&gt;Misc&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;bindsym XF86AudioRaiseVolume exec pactl set-sink-volume @DEFAULT_SINK@ +2%; exec pactl set-sink-mute @DEFAULT_SINK@ 0
bindsym XF86AudioLowerVolume exec pactl set-sink-volume @DEFAULT_SINK@ -2%; exec pactl set-sink-mute @DEFAULT_SINK@ 0
bindsym XF86AudioMute exec pactl set-sink-mute @DEFAULT_SINK@ toggle
bindsym XF86AudioPlay exec playerctl play-pause
bindsym XF86AudioNext exec playerctl next
bindsym XF86AudioPrev exec playerctl previous
bindsym XF86MonBrightnessUp exec light -A 10 # increase screen brightness
bindsym XF86MonBrightnessDown exec light -S 10 # decrease screen brightness
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These are the settings that allow me to use the built in media keys on my macbook.&lt;/p&gt;
&lt;p&gt;And that about wraps it up for this post. Next time I&amp;rsquo;ll discuss some of the programs that are needed to make i3 as usable as a standard DE.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Workflow Optimization Part 1: The System</title>
      <link>https://gideonwolfe.com/posts/workflow/system/</link>
      <pubDate>Tue, 26 Mar 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/workflow/system/</guid>
      <description>&lt;p&gt;I could write dozens of pages on why I choose linux over any other operating system. Let me save us both the time and break it down here.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Customization. If you can dream it, you can make it. From purely aesthetic &lt;a href=&#34;https://reddit.com/r/unixporn&#34;&gt;enhancements&lt;/a&gt; to low level system changes, linux gives you choices that simply are not available on other platforms.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Philosophy. Every program does one thing and does it well. Linux comes with free and open source software, and respects your privacy.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Control. When you run Linux, you truly &lt;strong&gt;own&lt;/strong&gt; your system. There is no corporate overlord renting you a license for your OS. Any possible system action and change is only a few commands away.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On my main machine, I run a distrobution called &lt;a href=&#34;https://www.archlinux.org/&#34;&gt;Arch Linux&lt;/a&gt;. This distro is a rolling release, meaning the repositories are constantly updated with new packages. In addition to this, it is a lightweight distro, and comes with practically nothing installed. By the time your workflow is complete, it will be a full fledged system.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
  &lt;img src=&#34;https://gideonwolfe.com/img/workflow/radare.png&#34;  class=&#34;center&#34;  style=&#34;border-radius: 8px; width: 853px; height: 480px;&#34;  /&gt;


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you take a look at the above screenshot, you will notice that the screen is divided into multiple black panes. Each of these panes are terminals, that allow me to launch and use pretty much any program on my system. Instead of managing a bunch of shortcuts and launchers, I simply spawn a terminal and tell it what to do.&lt;/p&gt;
&lt;p&gt;In addition to this, I am using a tiling window manager called &lt;a href=&#34;https://github.com/Airblader/i3&#34;&gt;i3-gaps&lt;/a&gt;. Tiling window managers allow you to more efficently move and interact with windows. Ever gotten frustrated when you have a million windows open and you&amp;rsquo;re just dragging them around frantically trying to find the right one? Tiling window managers like i3 let you tile all programs to prevent this. Works great with a terminal workflow, because terminals scale well and work fine at a small size.&lt;/p&gt;
&lt;p&gt;In my next post, I will be going into more detail about some of the configuration I&amp;rsquo;ve done to i3 to improve my workflow. Until then, check out my &lt;a href=&#34;https://github.com/GideonWolfe/PC-dotfiles&#34;&gt;dotfiles&lt;/a&gt; for the configs.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The Importance of Building an Optimized Workflow</title>
      <link>https://gideonwolfe.com/posts/workflow/workflow/</link>
      <pubDate>Mon, 25 Mar 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/posts/workflow/workflow/</guid>
      <description>&lt;p&gt;There are a few things that set apart true professionals from the rest in their trade. Among these things are a refined workflow and a mastery of one&amp;rsquo;s tools.&lt;/p&gt;
&lt;p&gt;No matter the industry, this philosphy holds true. A great carpenter will know the purpose and location of every tool in their shop. A great photographer will be intimately familiar with the settings and behavior of their camera, as well as a suite of photo editing tools and programs.&lt;/p&gt;
&lt;p&gt;A lot of times, we can expect programs to ship with what are commonly referred to as &amp;ldquo;sane defaults&amp;rdquo;. This means that for a new user, there shouldn&amp;rsquo;t be very much to configure in order to get up and running. The settings are preconfigured in a way that makes sense for the average use-case. This, combined with a general apathy towards customization/optimization from the average user, has left many of the most powerful tools, programs, and features unexplored.&lt;/p&gt;
&lt;p&gt;This is a tragedy, because if we fully harnessed the power of the software we already use, our productivity would greatly increase. Take document writing as an example. There are a million programs out there designed to type documents, all with varying features and specializations. However, a good portion of the population will never move beyond Microsoft Word, or whatever their first document editor was.&lt;/p&gt;
&lt;p&gt;Time after time, I see students (and professors) attempt to format a math heavy document in Word, completely unaware that LaTex or R Markdown exists. Or even worse, preform tedious and repetitive text editing tasks that probably could have been automated with a single vim command.&lt;/p&gt;
&lt;p&gt;Everytime I find myself thinking &amp;ldquo;there has &lt;em&gt;got&lt;/em&gt; to be a better way to do this&amp;hellip;&amp;rdquo;, I actually take the time to find and master that better way. And if it doesn&amp;rsquo;t exist, I do my best to make it. Some might consider such obsessive configuration a waste of time. Why spend hours writing config files when you could just be writing code?&lt;/p&gt;
&lt;p&gt;There are lots of benefits of building your own workflow, from increasing raw productivity to passively gaining knowledge by exposure to the granular settings offered by most tools and programs. In this series of posts, I am going to explain this philosophy and how I apply it to my own systems.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>About Me</title>
      <link>https://gideonwolfe.com/about/</link>
      <pubDate>Sat, 23 Mar 2019 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/about/</guid>
      <description>
  &lt;img src=&#34;https://gideonwolfe.com/img/Gideon.jpg&#34;  class=&#34;left&#34;  style=&#34;border-radius: 8px; width: 300px; height: 300px;&#34;  /&gt;


&lt;p&gt;&lt;a href=&#34;https://gideonwolfe.com/index.xml&#34;&gt;RSS feed&lt;/a&gt; with full post text&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://gideonwolfe.com/files/GideonWolfeCV.pdf&#34;&gt;My Resumé&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;~$ ./gideon.sh

Output:
------------------------

Position: Researcher, Employee, and Student at WWU
Languages: Python, JavaScript, Java, C, Racket, bash, Powershell
Interests: Infosec, Quantum Computing, Biotech, Music
Github: https://www.github.com/GideonWolfe
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href=&#34;https://gideonwolfe.com/files/publickey.gpg&#34;&gt;gpg file&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;153B 370B 0E00 4CDE 261C
CFC9 A97C 79D4 &lt;span style=&#34;color:#ae81ff&#34;&gt;0564&lt;/span&gt; E167
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Projects</title>
      <link>https://gideonwolfe.com/projects/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/projects/</guid>
      <description>&lt;h1 id=&#34;linux&#34;&gt;Linux&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/GideonWolfe/Zathura-Pywal&#34;&gt;Zathura-Pywal&lt;/a&gt;: Dynamically generate colorschemes for Zathura based on colors from Pywal&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/GideonWolfe/Gnuplot-Pywal&#34;&gt;Gnuplot-Pywal&lt;/a&gt;: Dynamically generate colorschemes for Gnuplot based on colors from Pywal&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/GideonWolfe/PC-dotfiles&#34;&gt;My Dotfiles&lt;/a&gt;: My system configuration files&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/GideonWolfe/CodeOverTime&#34;&gt;CodeOverTime&lt;/a&gt;: A bash utility that logs the lines of code in a git repo over the years&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/GideonWolfe/Chameleon&#34;&gt;Chameleon&lt;/a&gt;: A script to automate desktop theming on Linux&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/GideonWolfe/canvas-tui&#34;&gt;canvas-tui&lt;/a&gt;: A TUI for the Canvas education system&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;science&#34;&gt;Science&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/GideonWolfe/pTable&#34;&gt;pTable&lt;/a&gt;: A terminal based chemistry toolkit&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gideonwolfe.com/files/bio/bioinfoproj/finalreport.pdf&#34;&gt;Single and Pairwise Mutations and Their Impact on SARS-CoV-2 Proteins&lt;/a&gt;: Research paper on SARS-Cov-2 protein
mutations.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;programming&#34;&gt;Programming&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/GideonWolfe/vim.reaper&#34;&gt;vim.reaper&lt;/a&gt; 💀 A Hackable, Fully Featured, Rice Friendly Neovim Configuration&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Table of Contents</title>
      <link>https://gideonwolfe.com/contents/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://gideonwolfe.com/contents/</guid>
      <description>&lt;h1 id=&#34;linuxhttpgideonwolfecomtagslinux&#34;&gt;&lt;a href=&#34;http://gideonwolfe.com/tags/linux&#34;&gt;Linux:&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://gideonwolfe.com/tags/workflow/&#34;&gt;Workflow&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://gideonwolfe.com/posts/workflow/workflow/&#34;&gt;The Importance of Building an Optimized Workflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://gideonwolfe.com/posts/workflow/system/&#34;&gt;Workflow Optimization Part 1: The System&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://gideonwolfe.com/posts/workflow/i3/&#34;&gt;Workflow Optimization Part 2: The i3 Window Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://gideonwolfe.com/posts/workflow/sidekickprograms/&#34;&gt;Workflow Optimization Part 3: Sidekick Programs for i3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://gideonwolfe.com/posts/workflow/theming/&#34;&gt;Workflow Optimization Part 4: Theming Your System&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gideonwolfe.com/posts/workflow/chameleon/&#34;&gt;Automating Linux Desktop Theming With Chameleon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gideonwolfe.com/posts/workflow/newsboat/&#34;&gt;Unifying the News: Nextcloud, Newsboat, and Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/workflow/irc&#34;&gt;Chat like it&amp;rsquo;s &lt;del&gt;2000&lt;/del&gt; 2020: Using IRC in the modern world&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/workflow/i3/layouts&#34;&gt;Using preset layouts in i3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/workflow/neomutt/intro&#34;&gt;Email in the Terminal: Configuring Neomutt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/workflow/canvas-tui/canvas-tui&#34;&gt;Canvas in the Terminal: canvas-tui&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/workflow/xmenu&#34;&gt;xmenu: Desktop Agnostic Menu Utility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/workflow/i3/picom&#34;&gt;How to add a picom toggle to polybar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;mathhttpgideonwolfecomtagsmath&#34;&gt;&lt;a href=&#34;http://gideonwolfe.com/tags/math&#34;&gt;Math&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://gideonwolfe.com/tags/gnuplot&#34;&gt;gnuplot&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://gideonwolfe.com/posts/gnuplot/intro/&#34;&gt;Introduction to Gnuplot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://gideonwolfe.com/posts/gnuplot/theming/&#34;&gt;Theming Gnuplot&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;programminghttpgideonwolfecomtagsprogramming&#34;&gt;&lt;a href=&#34;http://gideonwolfe.com/tags/programming&#34;&gt;Programming&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;general&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gideonwolfe.com/posts/programming/general/texteditor/&#34;&gt;Programming in Neovim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gideonwolfe.com/posts/programming/general/vimreaper/&#34;&gt;vim.reaper: 💀 A Hackable, Fully Featured, Rice Friendly Neovim Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gideonwolfe.com/posts/programming/general/vimreaper-update/&#34;&gt;vim.reaper: 💀 What&amp;rsquo;s New?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://gideonwolfe.com/tags/python&#34;&gt;python&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://gideonwolfe.com/posts/programming/python/lambda/lambdapython/&#34;&gt;Using Lambda Functions in Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;securityhttpgideonwolfecomtagssecurity&#34;&gt;&lt;a href=&#34;http://gideonwolfe.com/tags/security&#34;&gt;Security&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://gideonwolfe.com/posts/security/p4wnp1/&#34;&gt;Creating a pocket pentest platform with P4wnP1: Part 1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;system-administrationhttpgideonwolfecomtagssysadmin&#34;&gt;&lt;a href=&#34;http://gideonwolfe.com/tags/sysadmin&#34;&gt;System Administration&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/hugo/hugonginx/&#34;&gt;Deploying a static Hugo site with NGINX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/mediaserver/&#34;&gt;Setting Up An Automated Home Media Server With Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/nextcloud/nextclouddocker/&#34;&gt;Controlling Your Cloud: Deploying a Nextcloud Server With Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/nextcloud/nextcloudworkflow/&#34;&gt;Controlling Your Cloud: Integrating Nextcloud Into Your Workflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/tig/intro&#34;&gt;Quantifying Your life: Introduction to the TIG Stack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/tig/advanced&#34;&gt;Quantifying Your life: Advanced TIG Techniques&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/hugo/hugogoogleanalytics/&#34;&gt;Adding Google Analytics to your Hugo Site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/hugo/hugorss/&#34;&gt;Adding RSS to your Hugo Site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/docker/watchtower/&#34;&gt;Keeping your docker containers updated with Watchtower&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/huginn/intro/&#34;&gt;Agents Standing By: Introduction to Huginn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/huginn/setup/&#34;&gt;Agents Standing By: Setting up Huginn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/huginn/status/&#34;&gt;Agents Standing By: Monitoring Website Status&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/huginn/disasters/&#34;&gt;Agents Standing By: Monitoring National Emergencies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/sysadmin/huginn/telegram/&#34;&gt;Agents Standing By: Notifications Through Telegram&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;sciencehttpgideonwolfecomtagsscience&#34;&gt;&lt;a href=&#34;http://gideonwolfe.com/tags/science&#34;&gt;Science&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://gideonwolfe.com/tags/quantum&#34;&gt;Quantum Computing&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/quantum/basicgates&#34;&gt;Quantum Katas #1: Basic Quantum Gates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/quantum/superposition&#34;&gt;Quantum Katas #2: Superposition&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.gideonwolfe.com/posts/quantum/measurement&#34;&gt;Quantum Katas #3: Measurement&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://gideonwolfe.com/tags/bioinformatics&#34;&gt;Bioinformatics&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gideonwolfe.com/posts/bio/yeast/intro&#34;&gt;Genetically Engineering Yeast to Bioluminescence: Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gideonwolfe.com/posts/bio/yeast/basicsteps&#34;&gt;Genetically Engineering Yeast to Bioluminescence: Overview of steps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gideonwolfe.com/posts/bio/bioinfoproj/project&#34;&gt;Single and Pairwise Mutations and Their Impact on SARS-CoV-2 Proteins&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;http://gideonwolfe.com/tags/chemistry&#34;&gt;Chemistry&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://gideonwolfe.com/posts/chemistry/bufferpractice1&#34;&gt;Chemistry Practice: Buffer Systems&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;musichttpgideonwolfecomtagsmusic&#34;&gt;&lt;a href=&#34;http://gideonwolfe.com/tags/music&#34;&gt;Music&lt;/a&gt;&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gideonwolfe.com/posts/music/alava/&#34;&gt;Alava - A new single by the Dawn Bombs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
