<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Steve Ziegler</title>
    <description>The latest articles on Forem by Steve Ziegler (@stevezieglerva).</description>
    <link>https://forem.com/stevezieglerva</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F8008%2Fh4tP32_K.jpeg</url>
      <title>Forem: Steve Ziegler</title>
      <link>https://forem.com/stevezieglerva</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/stevezieglerva"/>
    <language>en</language>
    <item>
      <title>🚌 How big is the bus factor for Forem's most complicated files?</title>
      <dc:creator>Steve Ziegler</dc:creator>
      <pubDate>Fri, 18 Jun 2021 19:33:01 +0000</pubDate>
      <link>https://forem.com/stevezieglerva/how-big-is-the-bus-factor-for-forem-s-most-complicated-files-48cm</link>
      <guid>https://forem.com/stevezieglerva/how-big-is-the-bus-factor-for-forem-s-most-complicated-files-48cm</guid>
      <description>&lt;p&gt;Ever since watching Adam Tornhill's excellent talk on &lt;a href="https://www.youtube.com/watch?v=fl4aZ2KXBsQ" rel="noopener noreferrer"&gt;prioritizing technical debt as if time and money matters&lt;/a&gt;, I've wanted a simple way to analyze my own repos. I wanted to replicate Adam's process of identifying code hotspots based on each file's code complexity, change frequency, and recency of the last change. I also wanted to see if I could recreate his "bus factor" analysis to see which files would be most adversely affected if a primary developer was hit by a bus, won the lottery, or just plain quit.&lt;/p&gt;

&lt;p&gt;I was able to create a simplified Python version that generated the hotspot data along with other basic git log metrics. I expected some high bus factor files knowing how many initial file commits Ben made to Forem. Surely there were plenty of complicated files that only he touched!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5y7cuzi2k17pu6v8e8jt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5y7cuzi2k17pu6v8e8jt.png" alt="Top forem committers over time showing the old timers: Ben, Mac, Molly, Michael, and rhymes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The hotspot list shows some intuitive hotspots for a Rails app like schema.rb and routes.rb which are used to manage the database and url routing. It also shows how user.rb and article.rb are hotspots for Forem which make sense given its focus on content publishing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🔥 Hotspots 
Commits  Comp.   Age    Score  File
  388    63589     1    100.0  db/schema.rb
  427    29318     1     50.7  config/routes.rb
  157    65260     2     41.5  app/javascript/chat/chat.jsx
  359    24357     1     35.4  app/models/user.rb
   98    72604    20     28.8  app/views/admin/configs/show.html.erb
  290    24093     6     28.3  app/models/article.rb
  169    34455     3     23.6  spec/models/user_spec.rb
  154    37107     7     23.2  spec/models/article_spec.rb
   69    48449    59     13.5  spec/requests/api/v0/articles_spec.rb
  177    17235     2     12.4  app/controllers/stories_controller.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So how susceptible are these hotspots to losing a team member? To analyze the bus factor, you can see how many different authors touched the file in the last 365 days.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjlzmrukcee115rub7coy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjlzmrukcee115rub7coy.png" alt="Histogram showing that most hotspots have had lots of authors touch it"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Luckily, most hotspots have had at least 10 unique authors touch the file. This might be another big benefit of taking Forem open: many people have touched the code and that collective body of knowledge now has 20+ unique authors committing per month.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmjkktcekwsjvviawphlv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmjkktcekwsjvviawphlv.png" alt="Forem has 20+ unique authors committing per month"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The good news is that the bus factor with Forem is low and the project should be able to weather changes in contributors. &lt;/p&gt;

&lt;p&gt;If you want to learn more, you can see all of the &lt;a href="http://nerdthoughts.net/git_analysis/forem/output/results.html" rel="noopener noreferrer"&gt;analytics&lt;/a&gt; on the repo and view the &lt;a href="https://github.com/stevezieglerva/git-log-analytics" rel="noopener noreferrer"&gt;source code&lt;/a&gt; on GitHub. &lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

</description>
      <category>meta</category>
      <category>techtalks</category>
    </item>
    <item>
      <title>TIL that git can checkout commits, not just branches</title>
      <dc:creator>Steve Ziegler</dc:creator>
      <pubDate>Sun, 11 Oct 2020 17:13:33 +0000</pubDate>
      <link>https://forem.com/stevezieglerva/til-that-git-can-checkout-commits-not-just-branches-368f</link>
      <guid>https://forem.com/stevezieglerva/til-that-git-can-checkout-commits-not-just-branches-368f</guid>
      <description>&lt;p&gt;You can pass a commit hash to checkout to quickly see a previous version of code. I like to commit often as I get new chunks of partial code working. If I advance to the point of breaking everything, it's an easy way to see what used to work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &amp;lt;commit &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>git</category>
    </item>
    <item>
      <title>Creating my own mixed news website free from "echo chamber" content algorithms 📰</title>
      <dc:creator>Steve Ziegler</dc:creator>
      <pubDate>Sat, 12 Sep 2020 14:03:58 +0000</pubDate>
      <link>https://forem.com/stevezieglerva/creating-my-own-mixed-news-website-free-from-echo-chamber-content-algorithms-55p0</link>
      <guid>https://forem.com/stevezieglerva/creating-my-own-mixed-news-website-free-from-echo-chamber-content-algorithms-55p0</guid>
      <description>&lt;p&gt;I've been frustrated with my various news feeds for showing the same type of content, with sensational headlines, re-enforcing my &lt;a href="https://en.wikipedia.org/wiki/Echo_chamber_(media)"&gt;echo chamber&lt;/a&gt;. Also, I often read a headline and wonder how "the other side" would report the same story. I wanted to have a simple website with a sampling of headlines representing liberal, conservative, and some international perspectives. &lt;/p&gt;

&lt;p&gt;Given my fear of all things frontend, I created a simple site with Hugo, a static site generator. I used Python to read a set of RSS feeds and create content markdown files based on the first few entries. The code is in &lt;a href="https://github.com/stevezieglerva/headlines"&gt;GitHub&lt;/a&gt; and the site is at &lt;a href="https://onlineheadlines.net"&gt;https://onlineheadlines.net&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are a few highlights:&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading the feeds
&lt;/h2&gt;

&lt;p&gt;My original vision was to visit each news site and effectively scrape the H1 as the top headline. But, assuming that sites would be too different to do that effectively, I decided to focus on RSS feeds (which are still alive and kicking!).&lt;/p&gt;

&lt;p&gt;I used the feedparser module to read the feeds. I iterate over an array of feeds and read them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;feed&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;FEEDS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;NewsFeed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;feedparser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Like most things in Python, the data is returned in beautiful dictionary objects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The warning isn't new. Experts have long cautioned the months ahead will be challenging. Here's why."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"link"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://rss.cnn.com/~r/rss/cnn_topstories/~3/b-gJezqWSTM/index.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Nearly 30 US states are reporting downward trends in..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"media_content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://cdn.cnn.com/cnnnext/dam/assets/200911014935-us-coronavirus-friday-0906-restricted-super-169.jpg"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating the content markdown files
&lt;/h2&gt;

&lt;p&gt;To create the markdown files, I grabbed key fields from the RSS JSON and put them into a formatted string. Python has an object called f-strings that allow you to format multiline strings and easily insert variable values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;f"""---
title: "&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"
date: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;published&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;image_url_front&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
target_link: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
type: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
categories:
    - &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;content_type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
---
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The resulting string looks like standard front matter and markdown format for website content, like here on Dev.to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;warning&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;isn't&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;new.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Experts&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;have&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;long&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;cautioned&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;months&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ahead&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;will&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;be&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;challenging.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Here's&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;why."&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 

&lt;span class="na"&gt;target_link&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://rss.cnn.com/~r/rss/cnn_topstories/~3/b-gJezqWSTM/index.html&lt;/span&gt;
&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;first_headline&lt;/span&gt;
&lt;span class="na"&gt;categories&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;first_headline&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
Nearly 30 US states are reporting downward trends in...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I just save the files into the appropriate Hugo subdirectory.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XoOZCtKm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2jtv3v56qw2u5nazaw5p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XoOZCtKm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/2jtv3v56qw2u5nazaw5p.png" alt="List of markdown content files in the first_headline folder"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Generating the site
&lt;/h2&gt;

&lt;p&gt;Hugo is a typical static site generator that pre-generates all of the HTML and folders to provide a simple, pretty-url navigation experience. Building the site generates the full website in the public/ folder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0kYQgANm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ro68dl1naurtkephcwpn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0kYQgANm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ro68dl1naurtkephcwpn.png" alt="List of generated folders and HTML pages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hugo has lots of community-created themes. I picked &lt;a href="https://themes.gohugo.io/hugo-xmag/"&gt;hugo-xmag&lt;/a&gt; because it looked like a newspaper.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YBq0cQ35--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rn6j26ot97hp2rlxoxoz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YBq0cQ35--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/rn6j26ot97hp2rlxoxoz.png" alt="Theme preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The theme creator has an &lt;a href="https://xmag.yihui.org/about/"&gt;interesting perspective&lt;/a&gt; on how he created the theme to avoid the clutter of modern-websites and focus on the articles.&lt;/p&gt;
&lt;h2&gt;
  
  
  Building the site
&lt;/h2&gt;

&lt;p&gt;This is where the fun turned into self-inflicted pain. There are simple options for CI and hosting, like Netlify, that would build and deploy based on changes to master. But, I wanted to try to get a static S3 site running, with a custom domain name and SSL cert. I had failed at doing this once before and wanted to see if I could get it to work.&lt;/p&gt;

&lt;p&gt;I usually use AWS CodePipeline for builds since it's so easy to set up. But, I have a process that sends build progress emails for every CodePipeline build and I didn't want a flood of emails if I was going to build the site every hour. Since CodePipeline and CodeBuild are essentially just short lived containers to execute your build step, I created a &lt;a href="https://github.com/stevezieglerva/headlines/blob/master/Dockerfile"&gt;custom container&lt;/a&gt; with Python, Hugo, my Hugo site, and my build script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight docker"&gt;&lt;code&gt;...

&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; curl wget

&lt;span class="c"&gt;# Install Hugo&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; hugo.deb https://github.com/gohugoio/hugo/releases/download/v0.70.0/hugo_0.70.0_Linux-64bit.deb
&lt;span class="k"&gt;RUN &lt;/span&gt;dpkg &lt;span class="nt"&gt;-i&lt;/span&gt; hugo.deb


&lt;span class="c"&gt;# Install AWS CLI&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;awscli

&lt;span class="c"&gt;# Copy directory files for Hugo site&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./ ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; headlines_site/

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



&lt;p&gt;I also created a script to &lt;a href="https://github.com/stevezieglerva/headlines/blob/master/build_container.sh"&gt;build the container&lt;/a&gt; locally and push it to AWS ECR as my container registry. I scheduled a Fargate task to run the container every hour. I knew Fargate was a "serverless" (read: "managed") service to run containers and thought it would be easy to set up. But, it took me a while to get the services, tasks, and container all working together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hosting the site
&lt;/h2&gt;

&lt;p&gt;This is where most of the frustrations occurred, which surprised me since I'm just hosting a static S3 site. Here are the issues I ran into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using a custom domain name with an S3 website requires CloudFront (as far as I could tell)&lt;/li&gt;
&lt;li&gt;CloudFront doesn't automatically automatically respect index.html in subfolders which prevented the Hugo pretty URLs from working (like &lt;a href="https://onlineheadlines.net/about"&gt;https://onlineheadlines.net/about&lt;/a&gt;). Luckily, digital-sailors created &lt;a href="https://github.com/digital-sailors/standard-redirects-for-cloudfront"&gt;standard-redirects-for-cloudfront&lt;/a&gt; to give the URLs the respect they deserve.&lt;/li&gt;
&lt;li&gt;Using Route 53 and CloudFront for the domain name and SSL cert requires that you know what you're doing with DNS (A and CNAME records, with and without "&lt;a href="http://www."&gt;www."&lt;/a&gt;). Unfortunately, my fear of networking is just as healthy as my fear of frontend. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even with all of the frustrations, it was a good learning experience with some lessons learned that I can apply at work when I'm helping other teams. &lt;/p&gt;

</description>
      <category>aws</category>
      <category>hugo</category>
      <category>python</category>
    </item>
    <item>
      <title>Another Reason to Blog: Your Words Might Be Better SEO</title>
      <dc:creator>Steve Ziegler</dc:creator>
      <pubDate>Mon, 25 May 2020 22:00:56 +0000</pubDate>
      <link>https://forem.com/stevezieglerva/another-reason-to-blog-your-words-might-be-better-seo-27bf</link>
      <guid>https://forem.com/stevezieglerva/another-reason-to-blog-your-words-might-be-better-seo-27bf</guid>
      <description>&lt;p&gt;I was recently struggling with getting a CloudWatch alarm on a log filter metric to work. I was refactoring the creation from a CloudFormation template into just Lambda Python code. I was able to get both the filter metric (looking for errors and exceptions in logs) and alarm created. &lt;/p&gt;

&lt;p&gt;But, when I tested the alarm, it never went into an alarm state, even when then metric filter showed active data. It was driving me crazy. I was able to manually create a new alarm, pointing to the same metric filter and see it work. This is the type of bug that developers hate: a completely illogical bug (as viewed by the bug's creator).&lt;/p&gt;

&lt;p&gt;Here is the metric showing data:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9d5M8Mqs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d4cxcitx0bby8y9wzyaj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9d5M8Mqs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/d4cxcitx0bby8y9wzyaj.png" alt="Working CloudWatch metric showing a spike"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is what the empty alarm looked like:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--anGGmnrX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/emciexf55mmav1vw9rsg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--anGGmnrX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/emciexf55mmav1vw9rsg.png" alt="Broken CloudWatch alarm never showing the showing the spike"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Searching online for an answer was not easy. My heart sunk when Stack Overflow didn't have the exact answer to my question with my first search. :) Searches for "alarms not working for filter metrics" weren't leading anywhere. &lt;/p&gt;

&lt;p&gt;I slept on it and tried different searches the next day. Luckily, &lt;a href="https://medium.com/@martatatiana"&gt;Marta Tatiana&lt;/a&gt; blogged her solution once she finally found it: &lt;br&gt;
&lt;a href="https://medium.com/@martatatiana/insufficient-data-cloudwatch-alarm-based-on-custom-metric-filter-4e41c1f82050"&gt;Insufficient data: CloudWatch alarm based on custom metric filter.&lt;/a&gt;. It turns out that you can't specify the period units (seconds, minutes, ...) when creating the alarm programmatically. &lt;/p&gt;

&lt;p&gt;Marta demonstrated one of the best reasons for blogging: showing other people your solution to a problem using your words. Your words may end up being better SEO for some lucky developer down the road.&lt;/p&gt;

</description>
      <category>aws</category>
    </item>
    <item>
      <title>Bash alias for GMT</title>
      <dc:creator>Steve Ziegler</dc:creator>
      <pubDate>Mon, 17 Feb 2020 14:21:19 +0000</pubDate>
      <link>https://forem.com/stevezieglerva/bash-alias-for-gmt-5622</link>
      <guid>https://forem.com/stevezieglerva/bash-alias-for-gmt-5622</guid>
      <description>&lt;p&gt;I always struggle trying to convert GMT time to EST or EDT especially in 24 hour format. It's even harder when I'm staring at a log file trying to find the root cause of an issue. &lt;/p&gt;

&lt;p&gt;I wrote this bash alias to output the last 24 hours of time in both local and GMT. I find I'm using it all of the time now. Since it's an alias, I can easily run it from a Terminal window or within VSCode.&lt;/p&gt;

&lt;p&gt;Here is the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;gmt&lt;span class="o"&gt;(){&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nt"&gt;-24&lt;/span&gt;..-1&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;est&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;H&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;gmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;H&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;$est&lt;/span&gt;&lt;span class="s2"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;$gmt&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done
&lt;/span&gt;&lt;span class="nv"&gt;est&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;gmt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"0 &lt;/span&gt;&lt;span class="nv"&gt;$est&lt;/span&gt;&lt;span class="s2"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;$gmt&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here is sample output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-24     Sun Feb 16 08:49:05 EST 2020    Sun Feb 16 13:49:05 UTC 2020
-23     Sun Feb 16 09:49:05 EST 2020    Sun Feb 16 14:49:05 UTC 2020
-22     Sun Feb 16 10:49:05 EST 2020    Sun Feb 16 15:49:05 UTC 2020
-21     Sun Feb 16 11:49:05 EST 2020    Sun Feb 16 16:49:05 UTC 2020
-20     Sun Feb 16 12:49:05 EST 2020    Sun Feb 16 17:49:05 UTC 2020
-19     Sun Feb 16 13:49:05 EST 2020    Sun Feb 16 18:49:05 UTC 2020
-18     Sun Feb 16 14:49:05 EST 2020    Sun Feb 16 19:49:05 UTC 2020
-17     Sun Feb 16 15:49:05 EST 2020    Sun Feb 16 20:49:05 UTC 2020
-16     Sun Feb 16 16:49:05 EST 2020    Sun Feb 16 21:49:05 UTC 2020
-15     Sun Feb 16 17:49:05 EST 2020    Sun Feb 16 22:49:05 UTC 2020
-14     Sun Feb 16 18:49:05 EST 2020    Sun Feb 16 23:49:05 UTC 2020
-13     Sun Feb 16 19:49:05 EST 2020    Mon Feb 17 00:49:05 UTC 2020
-12     Sun Feb 16 20:49:05 EST 2020    Mon Feb 17 01:49:05 UTC 2020
-11     Sun Feb 16 21:49:05 EST 2020    Mon Feb 17 02:49:05 UTC 2020
-10     Sun Feb 16 22:49:05 EST 2020    Mon Feb 17 03:49:05 UTC 2020
-9      Sun Feb 16 23:49:05 EST 2020    Mon Feb 17 04:49:05 UTC 2020
-8      Mon Feb 17 00:49:05 EST 2020    Mon Feb 17 05:49:05 UTC 2020
-7      Mon Feb 17 01:49:05 EST 2020    Mon Feb 17 06:49:05 UTC 2020
-6      Mon Feb 17 02:49:05 EST 2020    Mon Feb 17 07:49:05 UTC 2020
-5      Mon Feb 17 03:49:05 EST 2020    Mon Feb 17 08:49:05 UTC 2020
-4      Mon Feb 17 04:49:05 EST 2020    Mon Feb 17 09:49:05 UTC 2020
-3      Mon Feb 17 05:49:05 EST 2020    Mon Feb 17 10:49:05 UTC 2020
-2      Mon Feb 17 06:49:05 EST 2020    Mon Feb 17 11:49:05 UTC 2020
-1      Mon Feb 17 07:49:05 EST 2020    Mon Feb 17 12:49:05 UTC 2020
0       Mon Feb 17 08:49:05 EST 2020    Mon Feb 17 13:49:05 UTC 2020
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>bash</category>
      <category>timezones</category>
    </item>
    <item>
      <title>How DEV's job listings changed my perspective on hiring</title>
      <dc:creator>Steve Ziegler</dc:creator>
      <pubDate>Sat, 06 Jul 2019 14:54:21 +0000</pubDate>
      <link>https://forem.com/stevezieglerva/how-dev-s-job-listings-changed-my-perspective-on-hiring-df</link>
      <guid>https://forem.com/stevezieglerva/how-dev-s-job-listings-changed-my-perspective-on-hiring-df</guid>
      <description>&lt;p&gt;I recently used DEV's listings to help make a hire. We'd been struggling to get candidates for a mid-level position located near our main company locations in the DC area. I remembered that DEV created a new Listings section and decided to look there for possible candidates. The process opened my eyes to a few new perspectives: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DEV members already pass my first level of vetting&lt;/strong&gt;&lt;br&gt;
DEV is a wonderful community. In my opinion, members already have a desire to continually learn and realize the value of others in their learning/career growth. Those that contribute by blogging themselves also show good organizational and communication skills. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Junior is OK&lt;/strong&gt;&lt;br&gt;
We were originally looking for a mid-level developer. But, as a consulting company, ICF is very dynamic environment with a wide variety of projects and opportunities for junior devs to learn on the job. I checked with our PMs to make sure they'd be able to use a junior dev before moving to far. Even if her first project isn't using the latest, cutting-edge technology, a junior dev could learn a lot about software development, real-world projects and challenges, and the soft skills required to work in a team.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Starting remote is OK&lt;/strong&gt;&lt;br&gt;
ICF has always been remote friendly, but usually with experienced developers that had previously worked in one of the main offices (including myself!). I've always thought that being in a local office provided some comfort to new hires. Even though your colleagues might be ecologists, cancer researchers, or social workers, they could still help a new hire navigate the company organization and processes. While that could be helpful, I don't think it's required any more.    &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, it was a good experience and I'm glad DEV has this new capability. I'm really like that the &lt;a href="https://github.com/thepracticaldev/dev.to/issues/3088"&gt;Contact via Connect&lt;/a&gt; is checked by default now to make it easier for people to connect.&lt;/p&gt;

&lt;p&gt;Happy Coding!&lt;/p&gt;

</description>
      <category>hiring</category>
      <category>joblistings</category>
      <category>listings</category>
    </item>
    <item>
      <title>Script To List AWS Services In Use</title>
      <dc:creator>Steve Ziegler</dc:creator>
      <pubDate>Sun, 02 Jun 2019 13:45:06 +0000</pubDate>
      <link>https://forem.com/stevezieglerva/script-to-list-aws-services-in-use-aeb</link>
      <guid>https://forem.com/stevezieglerva/script-to-list-aws-services-in-use-aeb</guid>
      <description>&lt;p&gt;I recenty created &lt;a href="https://github.com/icfnext/aws-account-summary"&gt;aws-account-summary&lt;/a&gt; to list out basic information on the AWS services in use by an account. It comes in handy when trying to confirm current or newly created infrastructure. I went with quick-and-dirty approach of just finding text in AWS CLI output. It's suprisingly useful for such little code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sample Output
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sun 06/02/2019  8:47:59.33
*
*
* API Gateway
            "name": "TestAPI",
*
*
* Cloudfront
                            "DomainName": "jekyll-site-1.s3.amazonaws.com",
                "DomainName": "d1xau5ri19gn0n.cloudfront.net",
                            "DomainName": "www.nerdthoughts.net.s3.amazonaws.com",
                "DomainName": "d20ip71gqm0ltw.cloudfront.net",
*
*
* Cloudwatch
            "logGroupName": "/aws/aes/domains/ziegler-es/application-logs",
            "logGroupName": "/aws/codebuild/DocumentLambdas",
            "logGroupName": "/aws/codebuild/NCStateFair",
            "logGroupName": "/aws/codebuild/nerdthoughts",
            "logGroupName": "/aws/lambda/aws-code-index-bulk-load",
            "logGroupName": "/aws/lambda/aws-code-index-escape-files",
            "logGroupName": "/aws/lambda/aws-code-index-escape-files-2",
            "logGroupName": "/aws/lambda/aws-code-index-format-files",
            "logGroupName": "/aws/lambda/aws-code-index-stream-bulk-load",
            "logGroupName": "/aws/lambda/aws-dynamodb-to-es-bulk",
            "logGroupName": "/aws/lambda/aws-lnkchk-cache-stream",
            "logGroupName": "/aws/lambda/aws-lnkchk-dynamodb-stream-to-es",
            "logGroupName": "/aws/lambda/aws-lnkchk-extract-links",
            "logGroupName": "/aws/lambda/aws-lnkchk-log-stream-to-es",
            "logGroupName": "/aws/lambda/aws-lnkchk-queue-stream",
            "logGroupName": "/aws/lambda/aws-lnkchk-start",
            "logGroupName": "/aws/lambda/aws-read-s3-es-events-in-chunks",
            "logGroupName": "/aws/lambda/aws-s3-to-es",
            "logGroupName": "/aws/lambda/aws-tika-app",
*
*
* Running EC2 instance
                    "KeyName": "linux",
*
*
* Elasticsearch Domains
    "DomainNames": [
            "DomainName": "my-es"
*
*
* Firehose
{
    "DeliveryStreamNames": [
        "code-index-files-csv",
        "code-index-files-es-bulk",
        "code-index-logs"
    ],
    "HasMoreDeliveryStreams": false
}
*
*
* Lambdas
            "FunctionName": "aws-lnkchk-start",
            "FunctionName": "aws-code-index-escape-files",
            "FunctionName": "BlogBuild",
            "FunctionName": "nc-state-fair-food-finder",
            "FunctionName": "aws-read-s3-es-events-in-chunks",
            "FunctionName": "aws-lnkchk-dynamodb-stream-to-es",
            "FunctionName": "aws-dynamodb-to-es-bulk",
            "FunctionName": "ephemeral",
            "FunctionName": "aws-code-index-format-files",
                    "type": "code-index"
            "FunctionName": "aws-s3-to-es",
            "FunctionName": "BingSpellcheck",
            "FunctionName": "aws-lnkchk-extract-links",
            "FunctionName": "aws-code-index-bulk-load",
            "FunctionName": "aws-code-index-stream-bulk-load",
            "FunctionName": "aws-lnkchk-log-stream-to-es",
            "FunctionName": "aws-tika-app",
                    "type": "tika"
*
*
* RDS
*
*
* S3 Buckets
            "Name": "aws-s3-to-es",
            "Name": "aws-tika-app-code",
            "Name": "code-index",
            "Name": "code-index-2",
            "Name": "code-index-3",
            "Name": "link-checker",
            "Name": "lnkchk",
            "Name": "lnkchk-100-pages",
            "Name": "lnkchk-complex-site-integration",
            "Name": "lnkchk-simple-site-integration",
*
*
* Sagemaker
*
*
* Secretsmanager
*
*
* SQS
{
    "QueueUrls": [
        "https://queue.amazonaws.com/9999/code-index",
        "https://queue.amazonaws.com/9999/code-index.fifo",
        "https://queue.amazonaws.com/9999/link-checker"
    ]
}
*
*
* Users
            "UserName": "joesmith"

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



</description>
      <category>aws</category>
    </item>
    <item>
      <title>You get two professional apologies per year. That's it.</title>
      <dc:creator>Steve Ziegler</dc:creator>
      <pubDate>Tue, 19 Mar 2019 13:10:08 +0000</pubDate>
      <link>https://forem.com/stevezieglerva/you-get-two-professional-apologies-per-year-thats-it-1k6a</link>
      <guid>https://forem.com/stevezieglerva/you-get-two-professional-apologies-per-year-thats-it-1k6a</guid>
      <description>&lt;p&gt;Jessica Hagy wrote a great article on Forbes about &lt;a href="https://www.forbes.com/sites/jessicahagy/2016/06/28/10-things-to-never-apologize-for-again"&gt;things to never apologize for at work&lt;/a&gt;. While the apology theme is great, there are lots of hidden career-advice gems as well. I love her simple, hard-hitting graphs!&lt;/p&gt;

&lt;p&gt;It reminds me how I've coached some people that they are only allowed two professional apologies at work per year, so they should use them wisely. &lt;/p&gt;

</description>
      <category>career</category>
      <category>advice</category>
    </item>
    <item>
      <title>How To Use A Meeting To Elevate a Team Member</title>
      <dc:creator>Steve Ziegler</dc:creator>
      <pubDate>Sat, 22 Dec 2018 14:41:21 +0000</pubDate>
      <link>https://forem.com/stevezieglerva/how-to-use-a-meeting-to-elevate-a-team-member-bpc</link>
      <guid>https://forem.com/stevezieglerva/how-to-use-a-meeting-to-elevate-a-team-member-bpc</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YqZGWX-U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/u3zrex8n1ci9hli9yojt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YqZGWX-U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/u3zrex8n1ci9hli9yojt.jpg" alt="Buddy the Elf says 'I like meetings. Meetings are my favorite."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've been fortunate in my career to have very strong advocates. My advocates would mentor me and provide good opportunities for work and career advancement. A few years into my first job, my advocates positioned me for a leadership role on a new, large IT modernization project. They used a kickoff meeting with the client to elevate my status into a leadership role. The client, ExxonMobil, had just completed their merger to become the largest company in the world and was going to replace dozens of legacy systems with a new global, health and safety system for all of their business units. &lt;/p&gt;

&lt;p&gt;For the kickoff meeting, ExxonMobil was going to fly in senior leaders from around the world to hear our company's plan for the project. To my surprise, my advocates assigned me a speaking role on a data conversion tool that I had never used. I had no business telling 30-year petrochemical industry veterans how I was going to use this tool to convert their complex legacy data. I had to scramble to talk to the tool developer and learn everything I could from her before the meeting. &lt;/p&gt;

&lt;p&gt;On the day of the kickoff meeting, I was able to get through the presentation (with no questions luckily!). After the meeting, my advocates told me that the  clients were happy that I was on the project. Knowing how inexperienced I was, I realized how important perceptions, not reality, are. I also realized that my advocates did several specific things to change perceptions about me and elevate my status.&lt;/p&gt;

&lt;p&gt;As I've been an advocate for people, I try to use those same techniques to elevate people (usually developers) around key project or company meetings. Here are some of the things I do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Have the developer send the meeting invite&lt;/strong&gt; - This shows some ownership over the meeting and topic, even if it is just a perception.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make sure she has a speaking role&lt;/strong&gt; - She should have a defined speaking role during the meeting, even if just to review the agenda. You can use subsequent meetings to increase the speaking role.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coach him on how to confidently introduce himself&lt;/strong&gt; - A major factor in the perception of the developer's status is his confidence. Coach the developer on how to introduce himself with strong, active language: "I'm John Doe and I will be  ..." Be sure to avoid phrases like "I'm here because &lt;em&gt;Steve invited me&lt;/em&gt;" or "I'll be &lt;em&gt;helping&lt;/em&gt; Steve to  ..."&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>leadership</category>
      <category>mentoring</category>
    </item>
    <item>
      <title>You don't have to learn everything</title>
      <dc:creator>Steve Ziegler</dc:creator>
      <pubDate>Sun, 04 Mar 2018 15:37:05 +0000</pubDate>
      <link>https://forem.com/stevezieglerva/you-dont-have-to-learn-everything--718</link>
      <guid>https://forem.com/stevezieglerva/you-dont-have-to-learn-everything--718</guid>
      <description>&lt;p&gt;I read Abisekh's post on not knowing what to study next while trying to learn programming and data science.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;div class="ltag__link__content"&gt;
    &lt;div class="missing"&gt;
      &lt;h2&gt;Article No Longer Available&lt;/h2&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;I really felt for him. He's obviously passionate about wanting to get into the field and learning software development. Many of us in the development community have the same nagging feelings that we haven't learned the right things or haven't kept up. It's the tough part about being in an industry where everything changes constantly. But, as I thought about his post, I reflected on my career and how some things have stayed the same since I was building client server apps in PowerBuilder. These building blocks helped with my career when I wan't able to learn everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  User Interface
&lt;/h2&gt;

&lt;p&gt;There will always be a user interface. Given Siri and Alexa these days, it's not always a graphical interface. But, there will be a need to get input from the user and take action on it. Spending time to understand the basics of input data types (string, number, currency, ...), input controls (text box, dropdown, checkbox, radio button, ...), and when to use them will serve you well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logic
&lt;/h2&gt;

&lt;p&gt;Regardless of language, basic logic and flow control is essential. Every language will have mechanisms to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Iterate over sequences or lists with &lt;em&gt;for&lt;/em&gt; loops, &lt;em&gt;while&lt;/em&gt; loops, and list iterators&lt;/li&gt;
&lt;li&gt;Create and manipulate lists whether they are arrays, linked lists, hashes, or dictionaries&lt;/li&gt;
&lt;li&gt;Branch on conditions using &lt;em&gt;if&lt;/em&gt;, &lt;em&gt;if else&lt;/em&gt; (spelled a hundred different ways!), and &lt;em&gt;else&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As many people recommended in the comments, going deep in a single language first will allow you to master these basics making it easier to apply to other languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Storage
&lt;/h2&gt;

&lt;p&gt;Most apps will require data storage at some point, whether just in memory or written to disk. Understanding the basics of writing data for future retrieval is major building block for a career as a developer. I would start with a good ole relational database and learn SQL. SQL is a beautiful language. You'll be amazed with what you can do &lt;em&gt;joins&lt;/em&gt;, &lt;em&gt;group bys&lt;/em&gt;, and &lt;em&gt;sub-selects&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Grey Boxes
&lt;/h2&gt;

&lt;p&gt;Scott Hanselman has a great post saying that the &lt;a href="https://www.hanselman.com/blog/TheInternetIsNotABlackBoxLookInside.aspx" rel="noopener noreferrer"&gt;internet is not a black box&lt;/a&gt;. There really aren't many true black boxes in the software world. When things go wrong in these grey boxes, regardless of tech stack, there are lots of tools to help:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;monitor file or directory access (Process Monitor on Windows)&lt;/li&gt;
&lt;li&gt;read logs of systems&lt;/li&gt;
&lt;li&gt;check server performance for CPU or memory hogs&lt;/li&gt;
&lt;li&gt;review DB processes for slow queries or locks&lt;/li&gt;
&lt;li&gt;see web client behavior (F12 as Scott explains)&lt;/li&gt;
&lt;li&gt;understand how a web resource responds to different HTTP verbs and headers (&lt;a href="https://curl.haxx.se/" rel="noopener noreferrer"&gt;curl&lt;/a&gt; or my favorite &lt;a href="https://httpie.org/" rel="noopener noreferrer"&gt;HTTPie&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;see network traffic (&lt;a href="https://www.wireshark.org/" rel="noopener noreferrer"&gt;Wireshark&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;One constant throughout my career is that people expected my code to work. How rude! Learning to never trust your own code is another valuable career skill. Hammer your inputs with nulls, empty strings, bad data types, wrong combinations, invalid file formats, and bad urls. Luckily, doing this is much easier these days with the prevalence of unit testing tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Soft skills
&lt;/h2&gt;

&lt;p&gt;Chances are very high that you will be writing code as a part of team in a organization that contains people. When learning how to code, don't forget to learn how to deal with people. You will need to win friends and influence people. You might find Jon Sonmez's &lt;a href="https://www.amazon.com/Soft-Skills-software-developers-manual/dp/1617292397" rel="noopener noreferrer"&gt;Soft Skills: The software developer's life manual&lt;/a&gt; book useful.&lt;/p&gt;

&lt;p&gt;While the desire to learn everything may pull at you, focusing on the basics  first will provide a great foundation for a development career.&lt;/p&gt;

&lt;p&gt;Cover Image: &lt;a href="https://www.flickr.com/photos/_madolan_/5018250044/" rel="noopener noreferrer"&gt;Abbey Bookshop&lt;/a&gt; by &lt;a href="https://www.flickr.com/photos/_madolan_/" rel="noopener noreferrer"&gt;Mandolan Greene&lt;/a&gt;&lt;/p&gt;

</description>
      <category>learning</category>
      <category>careeradvice</category>
    </item>
  </channel>
</rss>
