<?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>DEV Community: Amy Henning</title>
    <description>The latest articles on DEV Community by Amy Henning (@amyhenning).</description>
    <link>https://dev.to/amyhenning</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%2F137641%2Fe3dd89c1-410e-4b51-9706-c1368cda6806.jpeg</url>
      <title>DEV Community: Amy Henning</title>
      <link>https://dev.to/amyhenning</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amyhenning"/>
    <language>en</language>
    <item>
      <title>Getting a Hash Value from a String of Concatenated Keys</title>
      <dc:creator>Amy Henning</dc:creator>
      <pubDate>Mon, 23 Nov 2020 03:55:55 +0000</pubDate>
      <link>https://dev.to/amyhenning/getting-a-hash-value-from-a-string-of-concatenated-keys-3216</link>
      <guid>https://dev.to/amyhenning/getting-a-hash-value-from-a-string-of-concatenated-keys-3216</guid>
      <description>&lt;p&gt;Recently, I was tasked with determining if an expected value was present in a hash containing an arbitrary (and unknown) number of nested keys, using a string containing relevant keys to search for. Here's how I approached the problem and some useful Ruby methods I used along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Input
&lt;/h2&gt;

&lt;p&gt;The method I was working on would require a few things. First, a hash to be searched. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;pokemon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;:pikachu&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;:id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;:height&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;:types&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="ss"&gt;:one&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"electric"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="ss"&gt;:kubfu&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;:id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;891&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;:height&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;:types&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="ss"&gt;:one&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"fighting"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Second, a string of keys, prepended with the name of the hash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;key_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pokemon.pikachu.height"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, an expected value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;expected_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So in this case, I would need to check if the &lt;code&gt;height&lt;/code&gt; value of &lt;code&gt;pikachu&lt;/code&gt; within the &lt;code&gt;pokemon&lt;/code&gt; hash was equal to &lt;code&gt;4&lt;/code&gt;. In code terms...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pokemon&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:pikachu&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:height&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Success!"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Questions
&lt;/h2&gt;

&lt;p&gt;I usually write down questions that need answers when solving problems like this. Here are a few I considered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What should I do with the prepended hash name, knowing I'd be passed a &lt;code&gt;pokemon&lt;/code&gt; hash?&lt;/li&gt;
&lt;li&gt;How could I make this flexible enough to handle an abitrary number of keys in the string? I.e. someone could pass in a string like "pokemon.pikachu.types.one.name" and this method would need to be able to handle that as well as "pokemon.pikachu.id".&lt;/li&gt;
&lt;li&gt;How will I turn the keys in this string into a sensible way to search through a hash, especially knowing that the hash could have any number of keys and layers of nested keys?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fortunately, Ruby has some useful methods built in that made for a pretty concise solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Split the String
&lt;/h2&gt;

&lt;p&gt;The first thing to do was make that string into individual keys. I used the String class' &lt;a href="https://ruby-doc.org/core-2.7.0/String.html#method-i-split"&gt;&lt;code&gt;split&lt;/code&gt;&lt;/a&gt; method (aka &lt;code&gt;String#split&lt;/code&gt;) to get an array of substrings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;strings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key_string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# break apart the string wherever a . appears&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"pokemon"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"pikachu"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Get Rid of the Hash Name
&lt;/h2&gt;

&lt;p&gt;I didn't actually need the "pokemon" element of that array since I already had the &lt;code&gt;pokemon&lt;/code&gt; variable in scope for the code I was writing. I removed it using the handy &lt;a href="https://ruby-doc.org/core-2.7.0/Array.html#method-i-drop"&gt;&lt;code&gt;Array#drop(n)&lt;/code&gt;&lt;/a&gt; method, which returns a copy of the original array with the first &lt;code&gt;n&lt;/code&gt; elements removed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"pikachu"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(If the concatenated string had only contained keys within the given hash, I wouldn't have needed to do this step.)&lt;/p&gt;

&lt;p&gt;First question - answered! ✅&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Convert the Strings to Symbols
&lt;/h2&gt;

&lt;p&gt;To search the keys in the provided hash (which are symbols), I needed the elements of &lt;code&gt;keys&lt;/code&gt; array to be symbols. When I split them up, they were still strings, so I needed a quick way to switch their type. I settled on this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:to_sym&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:pikachu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:height&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://www.brianstorti.com/understanding-ruby-idiom-map-with-symbol/"&gt;&lt;code&gt;&amp;amp;&lt;/code&gt;&lt;/a&gt; in Ruby will convert a method (represented by a symbol - in this case, &lt;code&gt;:to_sym&lt;/code&gt;) into a &lt;a href="https://ruby-doc.org/core-2.7.0/Proc.html"&gt;&lt;code&gt;Proc&lt;/code&gt;&lt;/a&gt; - basically, finding a method with the same name as the symbol. Passing &lt;code&gt;&amp;amp;:to_sym&lt;/code&gt; to Ruby's &lt;a href="https://ruby-doc.org/core-2.7.0/Enumerable.html#method-i-map"&gt;&lt;code&gt;Enumerable#map&lt;/code&gt;&lt;/a&gt; resulted in the &lt;a href="https://ruby-doc.org/core-2.7.0/String.html#method-i-to_sym"&gt;&lt;code&gt;String#to_sym&lt;/code&gt;&lt;/a&gt; method being called on all elements of the &lt;code&gt;keys&lt;/code&gt; array to produce the output above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Pass the Symbols to the &lt;code&gt;Hash#dig&lt;/code&gt; Method
&lt;/h2&gt;

&lt;p&gt;The last step involved looking for the value associated with the particular sequence of &lt;code&gt;keys&lt;/code&gt; within the &lt;code&gt;pokemon&lt;/code&gt; hash. I briefly became overwhelmed with how to take an arbitrarily long array and pass each item as a key to a hash before I learned about the &lt;a href="https://ruby-doc.org/core-2.7.0/Hash.html#method-i-dig"&gt;&lt;code&gt;Hash#dig&lt;/code&gt;&lt;/a&gt; method.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dig()&lt;/code&gt; takes any number of keys as arguments and looks for those keys, in sequence, within the hash. If any of the keys can't be found, it returns &lt;code&gt;nil&lt;/code&gt;. I tried this, expecting it to return &lt;code&gt;true&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;pokemon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This did not work, though. Why? Passing &lt;code&gt;keys&lt;/code&gt; to &lt;code&gt;dig&lt;/code&gt; essentially amounted to saying "Find the value for the &lt;code&gt;[:pikachu, :height]&lt;/code&gt; key within the &lt;code&gt;pokemon&lt;/code&gt; hash." But there is no single key called &lt;code&gt;[:pikachu, :height]&lt;/code&gt; in the &lt;code&gt;pokemon&lt;/code&gt; hash. Enter the splat operator (&lt;code&gt;*&lt;/code&gt;), which &lt;a href="https://ruby-doc.org/core-2.7.0/doc/syntax/calling_methods_rdoc.html#label-Array+to+Arguments+Conversion"&gt;turns an array into arguments&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Doing the following was like saying "find the &lt;code&gt;:pikachu&lt;/code&gt; key; then beneath that, find the &lt;code&gt;:height&lt;/code&gt; key. Then, check if that value equals 4."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;pokemon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Second and third questions - answered! ✅✅&lt;/p&gt;

&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;

&lt;p&gt;What does this look like when not broken down step-by-step? Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Inputs&lt;/span&gt;
&lt;span class="n"&gt;pokemon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;:pikachu&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;:id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;:height&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;:types&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="ss"&gt;:one&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"electric"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="ss"&gt;:kubfu&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;:id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;891&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;:height&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;:types&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="ss"&gt;:one&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"fighting"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;key_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pokemon.pikachu.height"&lt;/span&gt;
&lt;span class="n"&gt;expected_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;

&lt;span class="c1"&gt;# Array of symbols from the key string, excluding "pokemon"&lt;/span&gt;
&lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key_string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;drop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:to_sym&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pokemon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expected_value&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Success!"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Success&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Reflections
&lt;/h2&gt;

&lt;p&gt;I've been working with Ruby for over 2 years, and I certainly don't have every method memorized. Some of these methods are tools I reach for regularly, whereas others like &lt;code&gt;drop&lt;/code&gt; were fun discoveries while I worked on this problem.&lt;/p&gt;

&lt;p&gt;The code snippet on which this post is based was part of a larger feature at work, but it was fun to write and, in the process, use some Ruby methods that made my life much easier.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Of Webpacker Config and Failed Rails App Deploys</title>
      <dc:creator>Amy Henning</dc:creator>
      <pubDate>Thu, 08 Oct 2020 03:28:38 +0000</pubDate>
      <link>https://dev.to/amyhenning/of-webpacker-config-and-failed-rails-app-deploys-4l57</link>
      <guid>https://dev.to/amyhenning/of-webpacker-config-and-failed-rails-app-deploys-4l57</guid>
      <description>&lt;p&gt;Earlier this year, deploys of my team's main application began failing with this error:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is a Rails app with an AngularJS front-end currently being converted to React. In the months leading up to those failures, deploy times had steadily increased. Before they began failing, our longest deploys took 24+ minutes. 😱 Here's how we fixed the issue and what I learned about the cause.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attempted Fixes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;--max_old_space_size&lt;/code&gt; Setting
&lt;/h3&gt;

&lt;p&gt;We increased Node.js's memory limit to 2GB by setting &lt;code&gt;--max_old_space_size=2048&lt;/code&gt; as recommended in several Stack Overflow posts and Github issues. While this worked for many others, it did not solve our problem. Deploys continued to fail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Node.js Upgrade
&lt;/h3&gt;

&lt;p&gt;We next upgraded the app's Node.js version from 8 to 12 to take advantage of this feature:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This update will configure the JavaScript heap size based on available memory instead of using defaults that were set by V8 for use with browsers. In previous releases, unless configured, V8 defaulted to limiting the max heap size to 700 MB or 1400MB on 32 and 64-bit platforms respectively. Configuring the heap size based on available memory ensures that Node.js does not try to use more memory than is available and terminating when its memory is exhausted. (&lt;a href="https://medium.com/@nodejs/introducing-node-js-12-76c41a1b3f3f"&gt;source&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Upgrading Node.js unblocked our deploys for several weeks. However, during that time, we continued converting our AngularJS code to React and added new features in React. Deploys took longer and longer, and after a while, they began failing again.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix
&lt;/h2&gt;

&lt;p&gt;Given the attempted fixes above and with the help of infrastructure monitoring already in place, we were pretty sure that we weren't running out of memory on our deploy server. As it turns out, the root cause for this issue was in our Webpacker configuration.&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;webpacker.yml&lt;/code&gt; contained this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;default&lt;/span&gt;
    &lt;span class="na"&gt;source_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app-web&lt;/span&gt;
    &lt;span class="na"&gt;source_entry_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;react&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because of the way our app is structured, this meant we were telling Webpacker to process ALL of our React and Redux-related files, which were increasing in number with every sprint. As I researched the deploy failures, I learned about a helpful of rule of thumb about Webpacker from &lt;a href="https://rossta.net/blog/overpacking-a-common-webpacker-mistake.html"&gt;Ross Kaffenberger's blog&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If any file in Webpacker's "packs" directory does not also have a corresponding &lt;code&gt;javascript_pack_tag&lt;/code&gt; in your application, then you're overpacking.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Based on this rule, I should've seen just one file in our &lt;code&gt;packs&lt;/code&gt; directory. What I saw, though, was essentially a replica of the entire structure of our &lt;code&gt;/app-web/react&lt;/code&gt; directory. We were overpacking.&lt;/p&gt;

&lt;p&gt;Ultimately, we moved only the &lt;strong&gt;two&lt;/strong&gt; necessary files into a &lt;code&gt;startup&lt;/code&gt; directory and reconfigured &lt;code&gt;webpacker.yml&lt;/code&gt; to use that as its entry point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;default&lt;/span&gt;
    &lt;span class="na"&gt;source_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app-web&lt;/span&gt;
    &lt;span class="na"&gt;source_entry_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;react/startup&lt;/span&gt;
&lt;span class="nn"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is Webpacker, and what does it do?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://dev.toWebpacker"&gt;Webpacker&lt;/a&gt; is a gem which allows Rails apps to use &lt;a href="https://webpack.js.org/"&gt;webpack&lt;/a&gt; to process and bundle assets, particularly JavaScript.&lt;/p&gt;

&lt;p&gt;According to its documentation, webpack "is a static module bundler for modern JavaScript applications. When webpack processes your application, it internally builds a dependency graph which maps every module your project needs and generates one or more bundles."&lt;/p&gt;

&lt;h3&gt;
  
  
  Okay, cool. But what does that actually &lt;em&gt;mean&lt;/em&gt;?
&lt;/h3&gt;

&lt;p&gt;Webpack basically does the work of figuring out what depends on what in your application to generate the minimum "bundles" of assets required to run your app. You include these minimum packs in your application - in Rails, like below - so the app can load with the necessary assets already compiled.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight erb"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;%=&lt;/span&gt; &lt;span class="n"&gt;javascript_pack_tag&lt;/span&gt; &lt;span class="s1"&gt;'application'&lt;/span&gt; &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See &lt;a href="https://medium.com/the-self-taught-programmer/what-is-webpack-and-why-should-i-care-part-1-introduction-ca4da7d0d8dc"&gt;this article&lt;/a&gt; for a much more in-depth intro to what webpack actually does and why module bundlers are needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why was our configuration wrong?
&lt;/h3&gt;

&lt;p&gt;Since webpack builds a dependency graph based on a specified entry point, the greater the number of items in that entry point, the more processing time and resources needed. Because our configuration told Webpacker to process ALL of our React files, this required more time and server resources as we added more files to the React directory.&lt;/p&gt;

&lt;p&gt;So, basically, the idea was to not ask Webpacker to process every single file in our React application, but only the entry points to the React app (aka the files that have corresponding &lt;code&gt;javascript_pack_tag&lt;/code&gt;s), so that they and their immediate dependencies would be ready on initial application load.&lt;/p&gt;

&lt;h2&gt;
  
  
  Impact
&lt;/h2&gt;

&lt;p&gt;This fix unblocked our deploys &lt;em&gt;and&lt;/em&gt; dramatically reduced our deploy times and resource usage on our deploy server.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Deploy Time&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Max Deploy CPU Usage&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Max Deploy Memory Usage&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Before Fix&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&amp;gt; 24 min&lt;/td&gt;
&lt;td&gt;~90%&lt;/td&gt;
&lt;td&gt;~2.2GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;After Fix&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10 min&lt;/td&gt;
&lt;td&gt;~60%&lt;/td&gt;
&lt;td&gt;~0.28GB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So, lesson learned - don't overpack with Webpacker! 🧳&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@erwanhesry?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Erwan Hesry&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/suitcase?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;

</description>
      <category>rails</category>
      <category>webpack</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Strong, Not Perfect: How I Overcome Perfectionism Paralysis</title>
      <dc:creator>Amy Henning</dc:creator>
      <pubDate>Mon, 20 Apr 2020 00:04:32 +0000</pubDate>
      <link>https://dev.to/amyhenning/strong-not-perfect-how-i-overcome-perfectionism-paralysis-mja</link>
      <guid>https://dev.to/amyhenning/strong-not-perfect-how-i-overcome-perfectionism-paralysis-mja</guid>
      <description>&lt;center&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pylqZx75--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ztn5ftj0yx8s3ugz4i5m.gif" title="Chidi Anagonye from The Good Place saying 'My whole life has been a torture chamber of indecision.'" width="500" height="281"&gt;&lt;/center&gt;

&lt;p&gt;Confession: Like Chidi from The Good Place, I am a person who often suffers from decision paralysis. As Chidi failed in life to make ethically-perfect decisions, I often find myself hampered by perfectionism.&lt;/p&gt;

&lt;p&gt;According to &lt;a href="https://www.gallup.com/cliftonstrengths/en/252278/input-theme.aspx"&gt;the StrengthsFinder inventory&lt;/a&gt; (I've had to do this thing many times for different jobs), "Input," as defined below, is one of my top strengths:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;People exceptionally talented in the Input theme have a need to collect and archive. They may accumulate information, ideas, artifacts or even relationships.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My need to gather lots of information to make &lt;em&gt;the best&lt;/em&gt; decision certainly helps me make informed decisions; and of course, it fuels my desire to constantly learn (which ultimately led me to this career). At other times, it hinders more than helps me and causes an endless cycle of information-gathering in pursuit of a perfect answer or option, until I feel like this:&lt;/p&gt;


&lt;center&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6o16HJP1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wnvaawmrsftlngz7wlja.gif" title="Chidi Anagonye from The Good Place saying 'My indecision has once again cost me happiness and I will now suffer the consequences.'" width="500" height="281"&gt;&lt;/center&gt;

&lt;p&gt;Case in point: a few years ago, I spent &lt;em&gt;weeks&lt;/em&gt; evaluating and comparing two different half marathon training apps, comparing their features and reading countless reviews of them online, before ultimately settling on one. In hindsight, it's ridiculous that I spent so much time on a decision of such relatively small significance.&lt;/p&gt;

&lt;p&gt;Decision paralysis creeps up on me in my work in tech, too. It took me several months to redo my personal site, partly because I was &lt;em&gt;very&lt;/em&gt; busy moving across the country and settling into my first full-time engineering job, but also because I went back and forth on tiny design details like fonts and link colors and waffled between a &lt;code&gt;.dev&lt;/code&gt; and a &lt;code&gt;.codes&lt;/code&gt; domain. Late last year, I posted this on Twitter:&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--5TTg2vGv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/429715377778475008/DElFoyaj_normal.jpeg" alt="Amy Henning profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Amy Henning
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @henningamy
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      So I decided to start working on my personal site again over this holiday break and was all ready to not obsess over little details (i.e. just finish this thing I started in like, January) yet here I sit, editing link colors after midnight.🤦🏻‍♀️
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      06:15 AM - 28 Dec 2019
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1210806498953007104" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1210806498953007104" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1210806498953007104" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;When I finally deployed &lt;a href="https://amyhenning.codes/"&gt;my personal site&lt;/a&gt; in early April of 2020, it was with the knowledge that it was &lt;em&gt;almost&lt;/em&gt; where I wanted it to be. There's a long list of things I want to improve: I could have formatted the blog post listing more creatively, I could have tried more combinations of fonts, I could have implemented a more visually-appealing list of skills and tools on the work page, I could have done more research into CSS transitions for toggling light/dark mode, I could have spent more time understanding GraphQL deeply, I could have built things from scratch instead of using Gatsby plugins . . . you get the idea.&lt;/p&gt;

&lt;p&gt;I'm still not super satisfied with all of the things on that list. So how did I overcome the indecision caused by the pursuit of perfection? Here are some things I've been trying to keep in mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Focus on Strong, Not Perfect
&lt;/h2&gt;


&lt;center&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--myBez_Q5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/p793x8kjnlqusrrsldiq.gif" title="Eleanor Shellstrop from The Good Place saying 'Pobody's nerfect!'" width="500" height="250"&gt;&lt;/center&gt;

&lt;p&gt;One of my colleagues in the education non-profit world often used the phrase "strong, not perfect" to describe the desired outcome of a project, knowing that we could never write a single curriculum that met the needs of every one of our over 10,000 students. We did, however, design something really good that we believed, based on research, would resonate with as many students as possible.&lt;/p&gt;

&lt;p&gt;I've worked hard to apply this mantra to my work in tech. I used to worry about covering every edge case and fretted that I wasn't optimizing code as much as possible in every PR. While there is, of course, value in doing one's due diligence, I don't think it's worth it to allow perfectionism to hold up good work. Now, I focus on doing my research, opening a PR with well-functioning and tested code, and knowing that I'll likely get helpful feedback to make it even better.&lt;/p&gt;

&lt;p&gt;Similarly, I &lt;em&gt;could&lt;/em&gt; have outlined solutions to the long list of things I want to improve in my site, then started working on all of them before deploying. That would have meant a significant delay in having a live site, though. So instead of obsessing over relatively minor decisions (i.e., things the site could function without), I decided to go ahead and deploy something good and focus on the nice-to-have details later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define "Good Enough"
&lt;/h2&gt;


&lt;center&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zhJz4Enz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gcdlmeek9sql1c7ao6vx.gif" title="Chidi Anagonye from The Good Place saying 'None of this is bad.'" width="500" height="281"&gt;&lt;/center&gt;

&lt;p&gt;Another thing that has helped me is setting clear expectations for what I hope to accomplish with a feature. What does completion look like? When does my work on one thing end, and another begin? What is "good enough"?&lt;/p&gt;

&lt;p&gt;The answers to those questions come in the form of acceptance criteria in every ticket I work on at my job, and I'm lucky to have great product managers on my team who I can go to for clarification on the exact scope of a ticket if needed.&lt;/p&gt;

&lt;p&gt;But what about personal projects? For this site, I wrote mini "tickets" for myself with bare minimum acceptance criteria to achieve to ensure I was making steady progress. Completing these empowered me to move on with things in a good-enough state, even if they weren't exactly as I envisioned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improve in Iterations
&lt;/h2&gt;


&lt;center&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vBPOKoHA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/goy5o1ir26xbeshtrdg8.gif" title="Michael from The Good Place saying 'Well, as humans like to say, third time's the charm.'" width="440" height="220"&gt;&lt;/center&gt;

&lt;p&gt;That last point leads me here: the importance of iterating to make incremental, yet steady, change. Accepting that I can do multiple rounds of improvements on a thing helped me just get started instead of being paralyzed by the desire for perfection.&lt;/p&gt;

&lt;p&gt;At work, we build large features iteratively, laying the groundwork for a feature in one ticket and improving it with subsequent work to eventually achieve the vision for the project. With my site, I used my definition of "good enough" to get it live, and have been making small tweaks to it when I have time.&lt;/p&gt;


&lt;center&gt;&lt;p&gt;* * *&lt;/p&gt;&lt;/center&gt;

&lt;p&gt;These three ideas have allowed me to make more progress on personal projects lately than I have in a long, long time. Some of the ideas came from my career as an educator, and others are lessons learned as an engineer.&lt;/p&gt;

&lt;p&gt;Don't get me wrong - I am not advocating for submitting half-finished code at work or not putting in time and effort. But things don't need to be utterly perfect for them to be good, and something good can be improved. It can be scary to let go of the desire to churn out perfect projects or perfectly optimized code, but in a way it is also liberating to let go of unrealistic expectations.&lt;/p&gt;



&lt;center&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cMdgXQro--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/xd04zttlqmk0s80mg4wr.gif" title="Chidi from The Good Place saying 'I'm very scared, but also, I like it?'" width="500" height="281"&gt;&lt;/center&gt;

</description>
      <category>motivation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Recreating the Pokémon Red/Blue Pokédex</title>
      <dc:creator>Amy Henning</dc:creator>
      <pubDate>Tue, 07 Apr 2020 03:21:23 +0000</pubDate>
      <link>https://dev.to/amyhenning/recreating-the-pokemon-red-blue-pokedex-3fpi</link>
      <guid>https://dev.to/amyhenning/recreating-the-pokemon-red-blue-pokedex-3fpi</guid>
      <description>&lt;p&gt;When I started my current job last spring, my engineering team's onboarding curriculum involved (among other things) integrating with an external API to build a microservice in Python; I worked with the &lt;a href="https://pokeapi.co/"&gt;PokéAPI&lt;/a&gt;. I had grand plans for styling the final product that didn't come to fruition due to time constraints, but I knew I'd want to come back to those original ideas.&lt;/p&gt;

&lt;p&gt;In this post, I focus on my thought process while building &lt;a href="https://pokedexapp.com/"&gt;pokedexapp.com&lt;/a&gt; instead of sharing code snippets tutorial-style. This is an intentional choice I've made with myself as a true beginner in mind: when I was first learning to code, I craved insight into how and why engineers make technical decisions when &lt;em&gt;not&lt;/em&gt; following a tutorial - and I am still learning more about this topic all the time. I hope this post is helpful in some way to others!&lt;/p&gt;

&lt;h1&gt;
  
  
  Getting Started
&lt;/h1&gt;

&lt;p&gt;Last month, I found myself with the time and energy to focus on a personal project, so I decided to rebuild my Pokédex app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decision point:&lt;/strong&gt; What were my goals in recreating this app, besides the '90s nostalgia factor?&lt;/p&gt;

&lt;p&gt;I knew from the start that I wanted my app to look as similar to the original Red and Blue versions of the game as possible. I also knew I wanted to use this project to continue to practice front-end work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decision point:&lt;/strong&gt; Which technologies could I use? Which were appropriate for the app's purpose and my goals?&lt;/p&gt;

&lt;p&gt;I considered creating a Rails backend application and then using &lt;code&gt;react-on-rails&lt;/code&gt; for the front-end. However, since the PokéAPI is &lt;code&gt;GET&lt;/code&gt;-only (and my application would be as well), it didn't make sense to build a server-side application. I left behind my Rails comfort zone and decided to work with &lt;code&gt;create-react-app&lt;/code&gt; to set up my Pokédex in React.&lt;/p&gt;

&lt;h1&gt;
  
  
  Design
&lt;/h1&gt;

&lt;p&gt;As mentioned above, I knew I wanted my app to mimic the style of the 1990s GameBoy games as closely as possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decision point:&lt;/strong&gt; What exactly does "mimic the style of the 1990s Gameboy games" even mean?&lt;/p&gt;

&lt;p&gt;I settled on a couple key screenshots from the first generation games to use as my "wireframes":&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J8XHMOWw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3sfd0er3fn0ctvsm4vrz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J8XHMOWw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3sfd0er3fn0ctvsm4vrz.jpg" alt="Squirtle's basic info from the early Pokémon games" width="160" height="192"&gt;&lt;/a&gt;&lt;/p&gt;
Screenshot that guided the first of two components containing data from the API



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nLj6mJg7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/14najv2lahpooiy0eiev.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nLj6mJg7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/14najv2lahpooiy0eiev.png" alt="Ryhdon's stats from the early Pokémon games" width="320" height="288"&gt;&lt;/a&gt;&lt;/p&gt;
Screenshot that guided the second of two components containing data from the API



&lt;p&gt;Throughout the development of the app, I returned to these images constantly to guide my work.&lt;/p&gt;

&lt;h1&gt;
  
  
  Data
&lt;/h1&gt;

&lt;p&gt;Since I had used the PokéAPI before, I knew that it returns a LOT of data on a single request. I also knew that it has multiple endpoints for different and sometimes overlapping sets of information. However, I had completely forgotten where the relevant data would be in each of those.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decision point:&lt;/strong&gt; How did I want to approach figuring out how to work with the API's responses?&lt;/p&gt;

&lt;p&gt;I could've created the different components of the application, then fetched the gigantic response objects and messed around with them in the UI. However, that would have entangled my process for getting better at React with my need to figure out the deeply-nested API responses.&lt;/p&gt;

&lt;p&gt;Before even touching the React app, I instead combed through the responses from two endpoints: &lt;code&gt;/api/v2/pokemon/${pokemon-name}&lt;/code&gt; and &lt;code&gt;/api/v2/pokemon-species/${pokemon-name}&lt;/code&gt;. This meant lots of &lt;code&gt;curl&lt;/code&gt; requests and command-line manipulation of the JSON responses to find the data I would need to bring the "wireframes" to life. I eventually mapped the specific data roughly to where I would want things to show up in the UI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sHxd0u25--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/17fvjbtb0p8gjvn9hpvw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sHxd0u25--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/17fvjbtb0p8gjvn9hpvw.jpg" title="A page from my notebook with hand-drawn wireframes" width="880" height="631"&gt;&lt;/a&gt;&lt;/p&gt;
Some hand-drawn wireframes to map data to the UI



&lt;p&gt;The "wireframes" I chose were key to helping guide me through this phase of planning the project. Without them, I would have been overwhelmed by the sheer amount of information that the PokéAPI can provide.&lt;/p&gt;

&lt;h1&gt;
  
  
  Components
&lt;/h1&gt;

&lt;p&gt;From there, I started writing code. A major goal of mine was to practice thinking through how props are passed from component to component in something a little more complex than the tutorials I'd been doing but less complex than the giant application my team maintains at work. As I got deeper into developing the components, I started losing track of how the they were working together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decision point:&lt;/strong&gt; How could I make my confusion into an opportunity to think more clearly about props and state?&lt;/p&gt;

&lt;p&gt;I could have gone to the old standby of Googling for similar projects and mimicking their structure. In an effort to become more self-sufficient at React and application-level decision making, I instead roughly sketched what I wanted each component to know and do in order to fulfill my vision for the app. (If you couldn't tell already, I do a lot of my best thinking when sketching things out on paper.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rGKkts-7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/klbq090cncu27rczkjeu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rGKkts-7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/klbq090cncu27rczkjeu.jpg" title="Another page from my notebook with a sketch of the components" width="880" height="1250"&gt;&lt;/a&gt;&lt;/p&gt;
A rough sketch to keep components, props, and state straight



&lt;p&gt;These sketches guided me to getting the app to a workable (if ugly) initial state, pulling in the right data from the API to the individual components:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ULGZF-gQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/tweet_video_thumb/ETvs7K9XQAUqg1G%3Fformat%3Djpg%26name%3Dmedium" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ULGZF-gQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/tweet_video_thumb/ETvs7K9XQAUqg1G%3Fformat%3Djpg%26name%3Dmedium" title="Gif of the early, unstyled app" width="880" height="741"&gt;&lt;/a&gt;&lt;/p&gt;
The working app in its early, ugly stage



&lt;p&gt;Since the minimal components were working at this point, I decided it was safe to move on to styling the app.&lt;/p&gt;

&lt;h1&gt;
  
  
  Styling
&lt;/h1&gt;

&lt;p&gt;I will be honest - styling (if I'm doing it from scratch, as I was for this app) is, for me, usually the most time-consuming stage of developing any application. I am extremely detail-oriented, so I can end up spending a lot of time on tiny details. Knowing this about myself, I took an iterative approach without making a conscious decision to do so.&lt;/p&gt;

&lt;p&gt;The first major iteration looked like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8R9P4uRw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fnl89gvxdawmj6p15t29.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8R9P4uRw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fnl89gvxdawmj6p15t29.gif" title="GIF of a styled but incomplete iteration of the Pokédex" width="836" height="804"&gt;&lt;/a&gt;&lt;/p&gt;
Lots of progress from the earlier iteration, but still not done!



&lt;p&gt;I was pretty happy with this version, but there definitely was room to improve: tiny details (boxes and Pokéball illustrations) on each component were missing, the position of the arrows was weird, the arrows on the stats component were missing, I didn't have much good error handling (which is less visible but still important!), and the UX when awaiting a response from the API was pretty unhelpful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decision point:&lt;/strong&gt; What did I want to prioritize while styling the application to avoid working on it forever?&lt;/p&gt;

&lt;p&gt;Small deviations from the wireframes didn't bother me too much - I was fine with having separate &lt;code&gt;Special Attack&lt;/code&gt; and &lt;code&gt;Special Defense&lt;/code&gt; categories and using metric measurements for Pokémon height and weight (the PokéAPI returns weight in hectograms and height in decimeters, for some reason, so converting those to feet/inches and pounds would have been a headache). I also left off the little arrows on the stats component borders.&lt;/p&gt;

&lt;p&gt;I invested a lot of time styling some more visual details and implementing a better UX while awaiting API responses and on invalid input. The whole thing involved quite a bit of experimentation, Googling CSS tricks, and trial and error (as engineering often does). The finished product wound up looking like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j-SPJsAW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/es017zzz2xaepnihfca1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j-SPJsAW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/es017zzz2xaepnihfca1.gif" title="GIF of the Pokédex in its current state" width="838" height="834"&gt;&lt;/a&gt;&lt;/p&gt;
Bonus points to anyone who gets the Pokérap reference :)



&lt;h1&gt;
  
  
  Deployment
&lt;/h1&gt;

&lt;p&gt;Despite having a working app, I put off deploying it because I wasn't sure how I wanted to do so. I knew of a couple options (namely, Heroku and Netlify), but wasn't sure if I should research others to learn something new.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decision point:&lt;/strong&gt; How should I deploy the finished app to production?&lt;/p&gt;

&lt;p&gt;Almost every personal project I've worked on in the past has been deployed with Heroku. The Heroku apps I've deployed in the past are pretty slow, though, and I was interested in trying something new.&lt;/p&gt;

&lt;p&gt;I ultimately chose Netlify to deploy the app and register its domain name. While there are many options available and I could've spent more time practicing getting DNS and certificates set up, it just wasn't the focus of this project. I also had been sitting on a complete project for a few days, and I just wanted to get it out into the world. There is nothing wrong with using existing tools to get a job done!&lt;/p&gt;

&lt;p&gt;In addition to easy deployment and domain setup, I really liked that Netlify offers previews before a deploy and that the preview URLs essentially allow you to archive versions of your site. Their CLI was easy to use (I referenced &lt;a href="https://www.freecodecamp.org/news/how-to-deploy-a-react-application-to-netlify-363b8a98a985/"&gt;this article&lt;/a&gt;). I'm also intrigued by their continuous deployment feature and plan to try it out with my personal site.&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrapping Up
&lt;/h1&gt;

&lt;p&gt;Tracking my process for developing this app proved how even an application as simple as this one contains many decision points (also that I can be indecisive!). I hope this post is helpful in illustrating the decision-making processes that engineers go through constantly. Feel free to check out the finished Pokédex at &lt;a href="https://pokedexapp.com/"&gt;pokedexapp.com&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>projects</category>
      <category>beginners</category>
      <category>react</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Overcoming Imposter Syndrome On My Journey Into Tech</title>
      <dc:creator>Amy Henning</dc:creator>
      <pubDate>Sun, 08 Mar 2020 04:42:58 +0000</pubDate>
      <link>https://dev.to/amyhenning/overcoming-imposter-syndrome-on-my-journey-into-tech-38e0</link>
      <guid>https://dev.to/amyhenning/overcoming-imposter-syndrome-on-my-journey-into-tech-38e0</guid>
      <description>&lt;p&gt;A little over a year ago, I transitioned into tech as a career-changer with a B.A. in English and an M.A. in teaching. It wasn't a straightforward or easy journey, but it's one of which I am proud. I'm particularly glad to be on the other side of some nasty, decades-old imposter syndrome.&lt;/p&gt;

&lt;h1&gt;
  
  
  Let's Start in 2012
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft6sb7amnwdm8hk4j1496.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft6sb7amnwdm8hk4j1496.jpg" alt="Photo of a high-rise apartment building" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;
My former apartment building



&lt;p&gt;I once lived in this apartment building. In 2012, I was living here and dreaming of what I could do besides teaching - I was utterly burned out from teaching kindergarten.&lt;/p&gt;

&lt;p&gt;A myriad of options occurred to me - working for a non-profit, teaching high school, going into fundraising, working at Starbucks . . . but I never considered coding as a serious career option. This was, in large part, due to intense imposter syndrome that had built up over the years. I'll have to rewind a bit further to explain the origins of that imposter syndrome, however.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Early Days: A Fun Hobby
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fggcygweaw5teuwyn04p8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fggcygweaw5teuwyn04p8.png" alt="Screenshot of a journal layout designed by the author in the early 2000s" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;
A journal layout I designed in the early 2000s



&lt;p&gt;As a high schooler, I taught myself to code so I could customize layouts for online journaling platforms (Diaryland, Livejournal, Xanga, etc.) for myself and my friends. I also built a number of ~&lt;em&gt;~official~&lt;/em&gt;~ fan sites for things like books and local bands, and had them hosted by people with their own domains (I was not nearly that advanced).&lt;/p&gt;

&lt;p&gt;At the time, I found web design to be a fun after-school hobby. Being self-taught and driven to succeed in school, it wasn't something I took too seriously. But it didn't intimidate me, either.&lt;/p&gt;

&lt;h1&gt;
  
  
  A Whisper of Imposter Syndrome
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; hello world
&amp;gt; goodbye, programming
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As high school progressed, I focused more on my schoolwork than on building websites. I let my sites fall by the wayside.&lt;/p&gt;

&lt;p&gt;I also started dating someone who was a talented programmer. I have very vivid memories of him guiding me through writing my first &lt;code&gt;hello world&lt;/code&gt; program. I can't remember which language we used, but I distinctly remember thinking, "This is &lt;em&gt;his&lt;/em&gt; world, not mine. I'm not good enough for this." &lt;/p&gt;

&lt;p&gt;In my mind, coding was for people who loved math (I took every math class I could in high school but didn't like it very much) and gathered with their friends at LAN parties--not for clarinet-playing, book-loving girls like me. Thus, imposter syndrome stopped me from learning more about programming at age 17.&lt;/p&gt;

&lt;h1&gt;
  
  
  Becoming "A Humanities Person"
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fldihg1kbypwkj591p2m8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fldihg1kbypwkj591p2m8.png" alt="Spirograph art created by a computer program" width="691" height="673"&gt;&lt;/a&gt;&lt;/p&gt;
Spirograph art similar to what we created in my Intro to Comp Sci class - &lt;a href="https://takeawildguess.net/blog/codeart/codeart4/" title="Image source"&gt;source&lt;/a&gt;



&lt;p&gt;At some point early in college, I decided I was just not a science-y or technical person, despite excelling in AP science and math in high school. I eventually majored in English with a concentration (kind of like a minor) in Linguistics.&lt;/p&gt;

&lt;p&gt;My mindset followed trends in the gender gap in STEM that has been widely &lt;a href="http://uis.unesco.org/en/topic/women-science" title="Link to the UIS statistics on women in science"&gt;researched&lt;/a&gt; and reported on. That isn't to say I didn't try - to be able to take a computational linguistics class, I had to take Intro to Computer Science.&lt;/p&gt;

&lt;p&gt;I liked the class and problem-solving logically, but was frankly intimidated by such technical work that was seemingly without practical application. (We used Scheme to essentially generate spirograph images like the one above.) Thus, imposter syndrome and the mindset it engendered prevented me from even attempting to take the computational linguistics course or any other computer science classes. I focused instead on anthropological linguistics.&lt;/p&gt;

&lt;h1&gt;
  
  
  Doing the Same Thing Repeatedly Produces the Same Results
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F64kfneywbfq7jexlx8o8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F64kfneywbfq7jexlx8o8.gif" alt="GIF of a Fox spinning in circles" width="200" height="200"&gt;&lt;/a&gt;&lt;/p&gt;
Fox spinning - &lt;a href="https://www.deviantart.com/powerpup/art/Fox-chases-his-tail-201843011" title="Image source"&gt;source&lt;/a&gt;



&lt;p&gt;Back to 2012: I was dreaming of new jobs and career possibilities. I wasn't bold (or jaded) enough to make a significant pivot, however; instead, I chose to teach high school.&lt;/p&gt;

&lt;p&gt;I endured 6.5 more years in education, going on to lead curriculum design for a national non-profit after 2 years teaching high school English. The reasons I say "endured" (and why I eventually left) are significant enough to warrant their own series of blog posts.&lt;/p&gt;

&lt;p&gt;Suffice to say, I realized in early 2018 that I would continue to get similar results if I continued doing the same things that made me so intensely unhappy. At this point, three of my former teaching colleagues had attended coding bootcamps and launched careers as developers, and I was intrigued.&lt;/p&gt;

&lt;h1&gt;
  
  
  Doubting Myself
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; hello again, world!
&amp;gt; hello, programming &amp;lt;3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the spring of 2018, I was 100% ready to give up my career in education. The final roadblock was largely mental: what would my friends and family think about non-technical me trying to go into tech? Would they scoff at the idea? Would they support me outwardly and keep their doubts to themselves?&lt;/p&gt;

&lt;p&gt;At the end of the day, the person with the biggest doubts was &lt;em&gt;me&lt;/em&gt;. Half a lifetime of imposter syndrome had reared its head and nearly prevented me from taking the leap. The alternative, however, was to continue facing the monster that was my education job (again, a story for another time). So I enrolled in a coding bootcamp to try and start fresh.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Payoff
&lt;/h1&gt;

&lt;p&gt;Mid-2018, I turned down a job offer in education with no prospects of a tech job but every hope that things would work out. In September 2018, I graduated from my program and was hired to do contract engineering work by an edtech startup. After working as a technical teaching assistant at my bootcamp for a few months, I was hired into my first full-time engineering job.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdykv6qbpc8q0id95c29y.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdykv6qbpc8q0id95c29y.jpeg" alt="A photo of an apartment building in Chicago" width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;
The view of my old building from my office



&lt;p&gt;Today, from my office, I can see the same building I lived in while contemplating my future career. Imposter syndrome still gets me from time to time in my current work - and I'm sure it will continue to do so. But I have cleared the biggest mental hurdles that, for so long, kept me from digging deeper into something I enjoyed so much as a kid and still do today.&lt;/p&gt;

</description>
      <category>wecoded</category>
      <category>womenintech</category>
      <category>codenewbie</category>
    </item>
  </channel>
</rss>
