<?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: Teal Larson</title>
    <description>The latest articles on DEV Community by Teal Larson (@teallarson).</description>
    <link>https://dev.to/teallarson</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%2F571687%2F2472f21c-dddb-4c49-ba45-ed2ec594bf13.png</url>
      <title>DEV Community: Teal Larson</title>
      <link>https://dev.to/teallarson</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/teallarson"/>
    <language>en</language>
    <item>
      <title>Bootcamp to Job Hunt: What I did</title>
      <dc:creator>Teal Larson</dc:creator>
      <pubDate>Mon, 12 Sep 2022 14:15:00 +0000</pubDate>
      <link>https://dev.to/teallarson/bootcamp-to-job-hunt-what-i-did-25ol</link>
      <guid>https://dev.to/teallarson/bootcamp-to-job-hunt-what-i-did-25ol</guid>
      <description>&lt;p&gt;The idea of hunting for my first job after a coding bootcamp was intimidating, to say the least. I’d read blog posts from folks who said they got hired before even finishing their bootcamp and others who were looking for over a year.&lt;/p&gt;

&lt;p&gt;I have started and stopped this post many times in the past year for a handful of reasons. First, it feels vulnerable to share my story. Second, this path isn’t a guarantee. Somebody else could do the same things I did and not get hired, someone could do less and get hired sooner. So with that being said, this isn’t advice. Take it or leave it, do it or don’t. Everyone’s path looks different. However, I will say I was very strategic in my studies and approach after finishing bootcamp and I believe that made a big difference in my job hunt.&lt;/p&gt;

&lt;p&gt;Like all good stories, I’ll start at the beginning. These are the steps I took, more or less in chronological order. You don’t have to wait to finish bootcamp to start these, either!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oDhU7NMR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ddmdoap7scslbc9fhteg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oDhU7NMR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ddmdoap7scslbc9fhteg.jpeg" alt="Silhouette of a sign pointing in multiple directions in front of a sunset" width="880" height="586"&gt;&lt;/a&gt;&lt;br&gt;
&lt;small&gt;Photo credit: &lt;a href="https://unsplash.com/photos/C7B-ExXpOIE"&gt;unsplash&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Spruced up my online presence
&lt;/h2&gt;

&lt;p&gt;I wanted a way for folks to see my skills, my personality, and my learning. For me, this looked like upping my game on Twitter and LinkedIn, starting to blog, and building up a personal portfolio site. That order was specifically planned out.&lt;/p&gt;

&lt;p&gt;I started dipping my toes into “Tech Twitter” (this just means the nerdy, dev-centered side of Twitter) when I ordered my very first Udemy coding class. I started doing #100daysofcode and sharing what I was building and learning. Twitter is a great way to keep your finger on the pulse of hot topics and find meaningful conversations to read and share your thoughts on. Just remember you're in public and employers will find what you're talking about!&lt;/p&gt;

&lt;p&gt;For vamping up your LinkedIn, there are tons of resources out there on how to leverage your profile wisely. I dug into the recommendations on &lt;a href="https://www.youtube.com/watch?v=SG5Sb5WTV_g"&gt;Danny Thompson’s YouTube channel&lt;/a&gt; and found there was an immediate increase in traffic and communication within a short while!&lt;/p&gt;

&lt;p&gt;A lot of folks like Reddit, and there are lots of active conversations on there about a myriad of programming topics. I am still terrified of Reddit (have you seen how cruel folks can be on there?! 😳). I am mostly a “read and upvote only” type of user. That said if it’s a forum you find enjoyable, by all means, engage!&lt;/p&gt;

&lt;p&gt;My portfolio site was similar to &lt;a href="http://www.teallarson.dev"&gt;my site today&lt;/a&gt; – mostly just a central landing place for a small about me with links to a handful of my projects and posts.&lt;/p&gt;

&lt;p&gt;Wherever you’re active online, the most impact will be through meaningful interaction with others. When I was in bootcamp and on the job hunt, I made it a habit to find at least one conversation I could contribute meaningfully to every day. The imposter syndrome here was so real for me! But it got easier the more I flexed that muscle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shared about what I was doing/learning
&lt;/h2&gt;

&lt;p&gt;My online presence was looking good, I was interacting with others. Now, what do I share?&lt;/p&gt;

&lt;p&gt;Whatever I was doing or learning! Writing articles was my favorite outlet. Some folks prefer videos or podcasts, but I have always been a writer. However you get out there, this is a great way to show folks what you know, what you care about, and that you can communicate clearly.&lt;/p&gt;

&lt;p&gt;I started with blogging on DEV Community because I just wanted to start getting ideas out to the world without spending time building a blog site on my own. Also,_ _a big network like theirs gets a lot more traffic than my own site.&lt;/p&gt;

&lt;p&gt;I know this because I have a degree in it: teaching is one of the best ways to cement your learning. It was easy for me to fall into feeling like I had no helpful ideas. Like everyone else had already thought of and written about everything I think about. That’s not true at all! I guarantee you there are folks with less experience and knowledge (or more!) who will find your post useful or interesting. I have written about everything from how teachers are all pretty great at Agile, to my favorite sorting algorithm, to what VSCode features I was using most. The first tech company I worked at enjoyed my writing and I ended up getting to write a handful of engineering-related posts starting just a few weeks into the job.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--obIgU_rv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fua2yav3a0vdbx8o9wtg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--obIgU_rv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fua2yav3a0vdbx8o9wtg.jpeg" alt="Construction site&amp;lt;br&amp;gt;
" width="880" height="1068"&gt;&lt;/a&gt;&lt;br&gt;
&lt;small&gt;Photo credit: &lt;a href="https://unsplash.com/photos/PlBsJ5MybGc"&gt;unsplash&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Never stop learning and building
&lt;/h2&gt;

&lt;p&gt;Now, to be writing about what I was doing and learning, I had to be doing and learning things. I’m an incessantly curious person, so this wasn’t difficult for me. The most difficult part was narrowing down what to do or learn or build.&lt;/p&gt;

&lt;p&gt;I started by seeking out freelance work. I’d been doing website work for small businesses for a while (building websites, providing SEO and accessibility feedback, etc.), but now that I had a bit more knowledge, I dove into offering more full-blown projects and charging a bit more for them.&lt;/p&gt;

&lt;p&gt;In terms of learning, I had _no clue _what to learn next. Do I keep diving deeper into what I’ve already learned? Do I branch out wider? Looking back, I don’t think there’s any course or book that I regret diving into. All of my programming learnings have helped cement what I already know and helped me build mental connections between concepts. This was how I started building up some understanding of fundamental programming ideas and patterns without formal learning (things like, “Huh, this language deals with strings in this way… this other language does it differently… but they both have this in common. Do all programming languages have that part in common?”)&lt;/p&gt;

&lt;p&gt;A few areas I am really glad I dove into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Learned a more (and less) strongly typed language&lt;/strong&gt;. I started with learning JavaScript in bootcamp. I sort of cheated here because the “strongly typed language” I picked to learn more about was TypeScript, though I did do some brief skimming through Java resources and also got a course in Python. Again, I didn’t get that deep into any of these (except TypeScript), but I learned a lot about how languages are connected and different.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learned SQL.&lt;/strong&gt; I had used NoSQL in bootcamp. Presumably because it’s really easy to spin up a MongoDB Atlas instance for free. But every job I’ve had has relied heavily on SQL (I’ve been building data pipeline software since 2021) so this course has paid major dividends. To quote my mentor (who was quoting his mentor), “it’s not cute to say you just don’t know SQL”. I picked MySQL because someone said it was the friendliest. I have mostly used Postgres since then. That hasn’t mattered because they’re fundamentally similar. Just learn one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learned Ubuntu Server&lt;/strong&gt;. This was surprisingly useful. Have I even, in my professional career, spun up or maintained a server on my own? Not even close. But I &lt;em&gt;do&lt;/em&gt; use the command line every day and dang if I didn’t get a lot better around the command line from this class! I also learned some basics about IPs, ports, services, etc. that have come in handy. Do I have an opinion on the EMACS vs. VIM debate? No. But can I navigate my way around the command line and debug problems with my tests on CI? Yeah.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Was ridiculously curious
&lt;/h2&gt;

&lt;p&gt;Right along the same lines as always learning, just be curious! Ask questions. Ask questions to other people, ask questions about the code you’re working on, etc. When I solve a problem, it drives me insane if I don’t understand &lt;em&gt;why&lt;/em&gt; whatever I did works. And if there are exceptions, and if I can break it. It turns out that’s a great quality for a software engineer!&lt;/p&gt;

&lt;p&gt;This might mean clicking through source code or pouring over docs/Stack Overflow/GitHub repos. This might mean talking with someone else about it. This might mean writing a post about the solution that you’ve found.&lt;/p&gt;

&lt;p&gt;This may or may not come naturally to you, but I can tell you hiring panels watch for the type of questions you ask so start practicing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hung out at Hackathons and Meetups
&lt;/h2&gt;

&lt;p&gt;I went to as many hackathons as I could squeeze in, and attended a few online conferences and meetups (because it was still COVID). I met great people, I deepened technical skills, I practiced working remotely on self-organizing teams… and they were freaking fun. I mean seriously, when else would I have been able to hack up a prototype for a journal app that used sentiment analysis to build you a custom Spotify playlist?&lt;/p&gt;

&lt;p&gt;In the end, which one of these made the &lt;em&gt;most&lt;/em&gt; difference in my job hunt? Who’s to say? I think the whole was more than the sum of its parts here. A lot of these are just good practices, period, for programmers. If you’re out there on the job hunt, I wish you the best! It’s not easy. I got a lot of “no”s, and even more ghostings. But all it takes is one yes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=SG5Sb5WTV_g&amp;amp;t=1s"&gt;How to Use LinkedIn as a Developer to Get a Job in Tech&lt;/a&gt; – this is the video series I used to spruce up my LinkedIn.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.meetup.com/"&gt;Meetup.com&lt;/a&gt; – This is where I’ve found most of the local meetups I’ve attended. They list both virtual and in-person events!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>career</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Nevertheless, Teal Coded in 2022</title>
      <dc:creator>Teal Larson</dc:creator>
      <pubDate>Wed, 09 Mar 2022 03:18:24 +0000</pubDate>
      <link>https://dev.to/teallarson/teal-coded-in-2022-14h0</link>
      <guid>https://dev.to/teallarson/teal-coded-in-2022-14h0</guid>
      <description>&lt;h2&gt;
  
  
  My biggest technical goals are…
&lt;/h2&gt;

&lt;p&gt;continuing to grow in systems thinking.  I want to grow my toolbelt of approaches to tackling problems and come at issues from a variety of informed angles before implementing a solution.&lt;/p&gt;

&lt;p&gt;On a similar note I want to give some killer tech talks this year and set aside more time for writing.  You can take the teacher out of the classroom, but I still really like sharing cool ideas and concepts with anyone who will listen.&lt;/p&gt;

&lt;h2&gt;
  
  
  My biggest technical achievements are…
&lt;/h2&gt;

&lt;p&gt;In the past few months I've owned the design and implementation of some core back end product features that improved performance and reliability as well as adding new user functionality.  Serious bonus of working at a startup -- getting to own some FUN problems across a variety of areas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advocating for myself looks like…
&lt;/h2&gt;

&lt;p&gt;not "kneecapping" my own ideas. &lt;/p&gt;

&lt;p&gt;"Kneecapping" your ideas was described to me as cutting them down before you even share them, presumably because you think you need to make your thoughts more palatable. Things like saying &lt;code&gt;"if it's not a bother"&lt;/code&gt; instead of asking for what you need or &lt;code&gt;"I think"&lt;/code&gt; instead of just saying what you think or overusing the word &lt;code&gt;"just"&lt;/code&gt;. With a background in cultural studies and linguistics, I would be entirely remiss if I didn’t mention that there are a lot of cultural factors and nuances to all of this.  What I have seen is that people who are successful in similar sociocultural settings as me generally share their thoughts directly.&lt;/p&gt;

&lt;p&gt;I started to say what I thought directly. I had some serious fears about communicating my thoughts directly coming across as an angry woman.&lt;/p&gt;

&lt;p&gt;But overall, I find that people I speak with take my ideas seriously when I share my ideas seriously. Your ideas are valuable. Share them!&lt;/p&gt;

&lt;h2&gt;
  
  
  I pledge to support women, non-binary folks, and other minorities in tech by…
&lt;/h2&gt;

&lt;p&gt;continuing to offer my experience and resources to those who are coming into tech from non-traditional backgrounds (and hopefully finish out some of the blog posts I've left yet unfinished about the topic).&lt;/p&gt;

&lt;h2&gt;
  
  
  I’m excited about…
&lt;/h2&gt;

&lt;p&gt;what this year has in store.  I'm excited about the under-represented folks I see joining the communities I'm a part of -- Slack, in person, and otherwise.  I'm excited about continuing to learn and to grow.  I'm excited about gearing up to do more speaking.  I'd be lying if I said I wasn't excited about my "to read" pile! &lt;/p&gt;

&lt;p&gt;Honestly I'm just excited.  At this point, my learning and growth seem to be on an exponential trajectory.  So I'm excited to continue on that journey and share out what I see along the way.  And hopefully it helps someone else, too.&lt;/p&gt;

</description>
      <category>wecoded</category>
      <category>womenintech</category>
    </item>
    <item>
      <title>Data cleaning null values -- SQL or Code?</title>
      <dc:creator>Teal Larson</dc:creator>
      <pubDate>Thu, 29 Jul 2021 22:36:48 +0000</pubDate>
      <link>https://dev.to/grouparoo/data-cleaning-null-values-sql-or-code-4db7</link>
      <guid>https://dev.to/grouparoo/data-cleaning-null-values-sql-or-code-4db7</guid>
      <description>&lt;p&gt;When preparing your data set for analysis, it is crucial to ensure that your data set is both complete and accurate. One step in this process is deciding how to handle null values. Depending on how your data is going to be used, you may not want null values at all!&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's clean some data
&lt;/h2&gt;

&lt;p&gt;We're going to take a look at calculating Lifetime Value (LTV) of a customer. We want a customer with no purchase history to have an LTV of 0. What happens if our aggregated column returns no rows, and thus is &lt;code&gt;null&lt;/code&gt;? Should we clean the data at the query level or afterwards using a script?&lt;/p&gt;

&lt;p&gt;We’re going to walk through this LTV example from beginning to end looking at different options -- some that work well, some that work poorly, and some that won’t work at all.&lt;/p&gt;

&lt;p&gt;To start, we have a &lt;code&gt;users&lt;/code&gt; table and a &lt;code&gt;purchases&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;users:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; user_id &lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tr&gt;
    &lt;td&gt;1&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;2&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;3&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;4&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;5&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
purchases:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; user_id &lt;/th&gt;
      &lt;th&gt; price &lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tr&gt;
    &lt;td&gt;1&lt;/td&gt;
    &lt;td&gt;79.36&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;3&lt;/td&gt;
    &lt;td&gt;42.97&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;1&lt;/td&gt;
    &lt;td&gt;33.14&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;2&lt;/td&gt;
    &lt;td&gt;16.48&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;4&lt;/td&gt;
    &lt;td&gt;96.41&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;As you can see, the users table has 5 unique users and the purchases table has 5 purchases from users 1, 2, 3, and 4. User 5 is not present in the purchases table. Now that we have our data, it’s time to create our calculated column. Our query is being called by a function that passes it a list of user_ids that can be used in the query.&lt;/p&gt;
&lt;h3&gt;
  
  
  Option 1: With a SQL Query
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Using &lt;code&gt;COALESCE&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;COALESCE&lt;/code&gt; is a keyword used by Postgres and other SQL dialects to return the first non-null value in a set. Because of this, it’s a common keyword for data cleaning. Let’s look closer at the following query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;COALESCE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;purchases&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;LTV&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user_id&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;purchases&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;purchases&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;
    &lt;span class="k"&gt;IN&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;When we look at the results from that query we end up with:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; user_id &lt;/th&gt;
      &lt;th&gt; LTV &lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tr&gt;
    &lt;td&gt;1&lt;/td&gt;
    &lt;td&gt;112.50&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;2&lt;/td&gt;
    &lt;td&gt;16.48&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;3&lt;/td&gt;
    &lt;td&gt;42.97&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;4&lt;/td&gt;
    &lt;td&gt;96.41&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;Yikes! No user 5. That means wherever you’re using this data, when you try and access the row for user 5, you’ll get &lt;code&gt;null&lt;/code&gt;, which may throw off calculations. So why did &lt;code&gt;COALESCE&lt;/code&gt; do this?&lt;/p&gt;

&lt;p&gt;A SQL query is like checking a post office box -- you might find a bunch of envelopes containing various amounts of mail, or even an empty envelope I suppose. But if there’s no mail at that post office box, you leave empty handed. If SQL can’t find any rows, it comes back empty handed as well. In fact, getting back a null vs a 0 vs an undefined may seem similar, but they tell us different things:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; value &lt;/th&gt;
      &lt;th&gt; meaning &lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tr&gt;
    &lt;td&gt;0&lt;/td&gt;
    &lt;td&gt;
      We know something is there and its value is zero.
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;null&lt;/td&gt;
    &lt;td&gt;
      We know something is there and its value is unspecified
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;empty set&lt;/td&gt;
    &lt;td&gt;
      We know nothing is there
    &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;So the issue with our query isn’t with the &lt;code&gt;COALESCE&lt;/code&gt; but with the order of execution - there are no rows to return with a &lt;code&gt;user_id&lt;/code&gt; of 5 in &lt;code&gt;purchases&lt;/code&gt;. Let's think about the logical order of how we get there:&lt;/p&gt;

&lt;p&gt;The order that query gets executed in is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find rows in &lt;code&gt;purchases&lt;/code&gt; that match the given user ids (5 rows, matching 4 of the given user ids)&lt;/li&gt;
&lt;li&gt;On each of the rows returned, return either the sum of the price column or 0 (same 5 rows, with aggregated data for LTV)&lt;/li&gt;
&lt;li&gt;Group by user_id and order by user_id (4 rows returned, in order by user_id, with aggregated data for LTV)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After the first line, there isn’t even a row for user 5 anymore. We can expect the same behavior if we try a &lt;code&gt;CASE&lt;/code&gt; switch for our LTV because, again, there is no row, no data for it to act on.&lt;/p&gt;

&lt;p&gt;Had our &lt;code&gt;purchases&lt;/code&gt; table contained a row for user_id 5 with &lt;code&gt;null&lt;/code&gt; for price, it would have returned as expected. Knowing that, a second option is to break out a right outer join.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;RIGHT OUTER JOIN&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Knowing that our issue was with missing rows, we could go the route of a &lt;code&gt;RIGHT OUTER JOIN&lt;/code&gt; with our users table to achieve that. This way, we’ll get back a row for every user from &lt;code&gt;users&lt;/code&gt;, and, if it’s there, the sum of their data from the “price” column in &lt;code&gt;purchases&lt;/code&gt;, otherwise a 0.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;COALESCE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;LTV&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;purchases&lt;/span&gt;
    &lt;span class="k"&gt;RIGHT&lt;/span&gt; &lt;span class="k"&gt;OUTER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;purchases&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; user_id &lt;/th&gt;
      &lt;th&gt; LTV &lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tr&gt;
    &lt;td&gt;1&lt;/td&gt;
    &lt;td&gt;112.50&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;2&lt;/td&gt;
    &lt;td&gt;16.48&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;3&lt;/td&gt;
    &lt;td&gt;42.97&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;4&lt;/td&gt;
    &lt;td&gt;96.41&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;5&lt;/td&gt;
    &lt;td&gt;0&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;It works! Fantastic.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 If all of your foreign keys are coming from a single table, the above might be the right solution for you. However, in more complex cases, you may not have something like a generic “users” table.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your primary data may be spread across multiple tables -- for instance, you may have a setup like:&lt;/p&gt;

&lt;p&gt;location_a_customers&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; Column &lt;/th&gt;
      &lt;th&gt; Type &lt;/th&gt;
      &lt;th&gt; Collation &lt;/th&gt;
      &lt;th&gt; Nullable &lt;/th&gt;
      &lt;th&gt; Default &lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tr&gt;
      &lt;th&gt; user_id &lt;/th&gt;
      &lt;th&gt; string &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
      &lt;th&gt; not null &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
      &lt;th&gt; email &lt;/th&gt;
      &lt;th&gt; string &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
      &lt;th&gt; not null &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
    &lt;/tr&gt;  
    &lt;tr&gt;
      &lt;th&gt; last_name &lt;/th&gt;
      &lt;th&gt; string &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
      &lt;th&gt; not null &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
    &lt;/tr&gt;  
    &lt;tr&gt;
      &lt;th&gt; user_id &lt;/th&gt;
      &lt;th&gt; string &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
      &lt;th&gt; not null &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
    &lt;/tr&gt;

&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;location_b_customers&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; Column &lt;/th&gt;
      &lt;th&gt; Type &lt;/th&gt;
      &lt;th&gt; Collation &lt;/th&gt;
      &lt;th&gt; Nullable &lt;/th&gt;
      &lt;th&gt; Default &lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tr&gt;
      &lt;th&gt; user_id &lt;/th&gt;
      &lt;th&gt; string &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
      &lt;th&gt; not null &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
      &lt;th&gt; email &lt;/th&gt;
      &lt;th&gt; string &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
      &lt;th&gt; not null &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
    &lt;/tr&gt;  
    &lt;tr&gt;
      &lt;th&gt; last_name &lt;/th&gt;
      &lt;th&gt; string &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
      &lt;th&gt; not null &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
    &lt;/tr&gt;  
    &lt;tr&gt;
      &lt;th&gt; user_id &lt;/th&gt;
      &lt;th&gt; string &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
      &lt;th&gt; not null &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
    &lt;/tr&gt;

&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;that you want to use with a purchases table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; Column &lt;/th&gt;
      &lt;th&gt; Type &lt;/th&gt;
      &lt;th&gt; Collation &lt;/th&gt;
      &lt;th&gt; Nullable &lt;/th&gt;
      &lt;th&gt; Default &lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tr&gt;
      &lt;th&gt; user_id &lt;/th&gt;
      &lt;th&gt; string &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
      &lt;th&gt; not null &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
      &lt;th&gt; purchase_amount &lt;/th&gt;
      &lt;th&gt; decimal &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
      &lt;th&gt; not null &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
    &lt;/tr&gt;  
    &lt;tr&gt;
      &lt;th&gt; item_sku &lt;/th&gt;
      &lt;th&gt; string &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
      &lt;th&gt; not null &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
    &lt;/tr&gt;  
    &lt;tr&gt;
      &lt;th&gt; item_category &lt;/th&gt;
      &lt;th&gt; string &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
      &lt;th&gt; not null &lt;/th&gt;
      &lt;th&gt;  &lt;/th&gt;
    &lt;/tr&gt;

&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Fear not, we can still make it happen. Though, for everyone’s sake, at this point I would recommend using a function over using SQL! Just for giggles, let's prove it's possible first.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;UNION&lt;/code&gt; with a list
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Overkill query ahead. You should really try a function instead.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One way around the issue of having multiple users tables would be to create a list of all the &lt;code&gt;user_id&lt;/code&gt;s for the query with a sublist of (&lt;code&gt;user_id&lt;/code&gt;, 0), then &lt;code&gt;UNION&lt;/code&gt; the original query with that list. If it sounds overkill, that’s because it is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;purchases&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;LTV&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;purchases&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;purchases&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="k"&gt;in&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;

&lt;span class="k"&gt;UNION&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;values&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LTV&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LTV&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Which returns our beloved 0:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; user_id &lt;/th&gt;
      &lt;th&gt; LTV &lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tr&gt;
    &lt;td&gt;1&lt;/td&gt;
    &lt;td&gt;112.50&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;2&lt;/td&gt;
    &lt;td&gt;16.48&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;3&lt;/td&gt;
    &lt;td&gt;42.97&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;4&lt;/td&gt;
    &lt;td&gt;96.41&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;5&lt;/td&gt;
    &lt;td&gt;0&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;The query isn’t too out of hand for 5 users, but imagine having to write that out (or have a function write that out) for 500 users! What about 10,000! Just because something works, doesn’t make it necessarily the right idea. So let’s try it from the programming sde.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2: After the SQL Query 🥇
&lt;/h3&gt;

&lt;p&gt;We’re really asking a lot of SQL there. While it was possible, it was not very pretty, very concise, or very readable. It also muddies things up as it is technically returning data from our database that isn’t there. Thankfully, transforming the data we do get back using a function is a much more straightforward task!&lt;/p&gt;

&lt;p&gt;I worked this one out in both TypeScript and Python. I love that we use TypeScript for building out our data pipeline because dynamic typing helps keep the guard rails on and make sure I’m paying attention to what I’m working with -- especially as our data structures grow in complexity, it helps to be completely sure what you’re working with. And Python for all the Python-loving data folks as well.&lt;/p&gt;

&lt;p&gt;Here’s how we can use a function to transform our data to include 0s. We start by setting the LTV of every id as [0], then iterate through our results and replace the [0]s as we go:&lt;/p&gt;

&lt;h4&gt;
  
  
  TypeScript:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Profile&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;DataResonseRow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;calculateLTV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;queryResults&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DataResponseRow&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;aggregationMethod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;profiles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Profile&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;responsesById&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="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;profiles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;aggregationMethod&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;count&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;aggregationMethod&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sum&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;//default all entries for counted or summed aggregations to 0 to start... will be replaced later if there is a response&lt;/span&gt;
      &lt;span class="nx"&gt;responsesById&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;profiles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;queryResults&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;responsesById&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;queryResults&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;queryResults&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;responsesById&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;h4&gt;
  
  
  Python:
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;🐍 Note: There are many Python libraries that help with data cleaning and analytics. Two popular choices are &lt;a href="https://pandas.pydata.org/"&gt;pandas&lt;/a&gt; and &lt;a href="https://matplotlib.org/stable/contents.html"&gt;matplotlib&lt;/a&gt;. However, this is a super straightforward solution using plain-vanilla Python.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_ltv&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;aggregation_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;profiles&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;responses_by_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt;  &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;profiles&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;aggregation_method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"count"&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;aggregation_method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"sum"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# default all entries for counted or summed aggregations to 0 to start... will be replaced later if there is a response
&lt;/span&gt;        &lt;span class="n"&gt;responses_by_id&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;query_results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;responses_by_id&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;responses_by_id&lt;/span&gt;


&lt;span class="n"&gt;mock_query_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s"&gt;"id"&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="s"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="mf"&gt;112.50&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="mf"&gt;16.48&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="mf"&gt;42.97&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;&lt;span class="mf"&gt;96.41&lt;/span&gt;&lt;span class="p"&gt;]}]&lt;/span&gt;
&lt;span class="n"&gt;mock_aggregation_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"sum"&lt;/span&gt;
&lt;span class="n"&gt;mock_profiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s"&gt;"id"&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="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;


&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calculate_ltv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mock_query_results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_aggregation_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_profiles&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;To see them in action, here’s &lt;a href="https://jsfiddle.net/xqd5rjb2/1/"&gt;a jsfiddle for the TypeScript solution&lt;/a&gt; and an IDEOne instance for the &lt;a href="https://ideone.com/qIgSap"&gt;Python solution&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn More:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;To learn more about handling conditionals and aggregations in Postgresql, check out &lt;a href="https://www.postgresql.org/docs/8.1/functions-conditional.html"&gt;their docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>sql</category>
      <category>datascience</category>
      <category>typescript</category>
      <category>python</category>
    </item>
    <item>
      <title>5 VSCode Features I Use Daily as a Full Stack Engineer</title>
      <dc:creator>Teal Larson</dc:creator>
      <pubDate>Tue, 01 Jun 2021 19:50:29 +0000</pubDate>
      <link>https://dev.to/teallarson/5-vscode-features-i-use-daily-as-a-full-stack-engineer-2nmp</link>
      <guid>https://dev.to/teallarson/5-vscode-features-i-use-daily-as-a-full-stack-engineer-2nmp</guid>
      <description>&lt;p&gt;As a software engineer, there are times you'll walk into a codebase that is already established and is some combination of: (a) new to you (b) much larger/more complex than other projects you've worked on and (c) uses a structure and some core libraries that are new to you.  OR you're a mutant genius, in which case no need to read on (but I would like to know more).  &lt;/p&gt;

&lt;p&gt;Having the "mind of a programmer" and being able to recognize patterns and connections will help, and so will pair programming and documentation.  But personally, some of my favorite strategies are tools and shortcuts that I've picked up to use VSCode to help me work smarter without always having to do either of those.&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%2Fr51yoawruos2f82kkirg.gif" 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%2Fr51yoawruos2f82kkirg.gif" alt="Grease GIF"&gt;&lt;/a&gt;&lt;sup&gt;Image credit: &lt;a href="https://giphy.com/gifs/grease-movie-john-travolta-zgf1opQOtG05a" rel="noopener noreferrer"&gt;Giphy&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;These five VSCode tools and shortcuts are ones that I use every day (if not every hour):&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Search by file content
&lt;/h3&gt;

&lt;p&gt;This is probably cheating, it's not really a hidden feature.  But SEARCH! If that search bar on the left isn't your friend already, you're missing out.  This search bar searches file contents.  Remember the name of a function or variable but not what files it was used in? Looking to see if a function or variable exists elsewhere?  Trying to make sure you removed all your &lt;code&gt;//TODO&lt;/code&gt; comments and &lt;code&gt;console.log()&lt;/code&gt; statements before you push?  Yeah, search is my jam.&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%2Fbsysyh5li3kvnh5vv2oe.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%2Fbsysyh5li3kvnh5vv2oe.png" alt="Search bar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Search by file name
&lt;/h3&gt;

&lt;h5&gt;
  
  
  Cmd+p search (Windows: Ctrl+p)
&lt;/h5&gt;

&lt;p&gt;Similar to the search on the left, but different in one key way: This search bar searches by file NAME!  I spent way too long not knowing about this second search bar.  &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%2Fl9o0t7kap86afhc79lkz.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%2Fl9o0t7kap86afhc79lkz.png" alt="Search by filename"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Search for settings
&lt;/h3&gt;

&lt;h5&gt;
  
  
  Cmd+shift+p (Windows: Ctrl+shift+p)
&lt;/h5&gt;

&lt;p&gt;This one is just ::chef kiss::.  I can't tell you how frequently I want to do something like toggle word wrap, reload the window, etc.  Instead of remembering the hot keys for all of those settings, you can open up this search bar and quickly find the setting you need.&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%2Fim3f71su9pj7fjxeqxam.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%2Fim3f71su9pj7fjxeqxam.png" alt="settings search"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Go to definition
&lt;/h3&gt;

&lt;h5&gt;
  
  
  Cmd + click (Windows: ctrl+click)
&lt;/h5&gt;

&lt;p&gt;Use this one on any variable, function, namespace, model... anything that was defined somewhere else.  VSCode will open up wherever it was defined in a new tab for you.  Boom.&lt;br&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%2Fu0k0m5i78a0g1zmgdtfo.gif" 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%2Fu0k0m5i78a0g1zmgdtfo.gif" alt="Go to definition"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Go to references
&lt;/h3&gt;

&lt;h5&gt;
  
  
  Right click, choose "go to references"
&lt;/h5&gt;

&lt;p&gt;Similar to "Go to definition", but I think this one is a level up.  Go to references will show you everywhere in the codebase whatever you're looking at is referenced.  This is great for seeing where a function might be in use before you modify it, for instance. I have learned so much about new codebases by browsing with "Go to references".&lt;br&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%2Fs2el4st9thrp3rszb1nr.gif" 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%2Fs2el4st9thrp3rszb1nr.gif" alt="Go to references"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Additional Resources
&lt;/h4&gt;

&lt;p&gt;Some other tools I use daily:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode" rel="noopener noreferrer"&gt;Prettier Code Formatter&lt;/a&gt; - Automatically tidies up your formatting.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer" rel="noopener noreferrer"&gt;Bracket Pair Colorizer&lt;/a&gt; - Never miss your closing bracket again. (I'm actually realizing I never loaded this on my work setup 😱, but I use it at home.)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens" rel="noopener noreferrer"&gt;Git Lens&lt;/a&gt; - I love this one for knowing who's worked on different parts of the code base and when!&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ohmyz.sh/" rel="noopener noreferrer"&gt;OhMyZsh&lt;/a&gt; - Makes working in the terminal 10000x less intimidating (and faster!)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Build a Responsive Mega Menu with React Bootstrap</title>
      <dc:creator>Teal Larson</dc:creator>
      <pubDate>Thu, 13 May 2021 22:48:25 +0000</pubDate>
      <link>https://dev.to/grouparoo/build-a-responsive-mega-menu-with-react-bootstrap-50pp</link>
      <guid>https://dev.to/grouparoo/build-a-responsive-mega-menu-with-react-bootstrap-50pp</guid>
      <description>&lt;p&gt;Having clear and accessible navigation is huge for website conversions. Sites with poor navigation are frustrating to use. Nested navigation menus are a common way to help keep top-level navigation to a minimum, but they can have major usability issues. A better way to handle a large number of links in a dropdown is to create a &lt;a href="https://www.nngroup.com/articles/mega-menus-work-well/" rel="noopener noreferrer"&gt;mega menu&lt;/a&gt;. Recently, we gave our site navigation a face lift using mega menus.&lt;/p&gt;

&lt;p&gt;Since both our &lt;a href="https://github.com/grouparoo/grouparoo" rel="noopener noreferrer"&gt;core product&lt;/a&gt; and our &lt;a href="https://github.com/grouparoo/www.grouparoo.com" rel="noopener noreferrer"&gt;website&lt;/a&gt; are open source here at Grouparoo, let’s dive in and take a look at how we built out a mega menu using our stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, What’s a Mega Menu?
&lt;/h2&gt;

&lt;p&gt;This!&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%2Fs52yqc0l9wdh3okmtjv5.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%2Fs52yqc0l9wdh3okmtjv5.png" alt="Mega menu on http://www.grouparoo.com"&gt;&lt;/a&gt;&lt;br&gt;
A mega menu is a way to have multiple columns (or more!) of items within your dropdown menu. Some key things to consider:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make sure you have enough items within your dropdown to warrant a mega menu&lt;/li&gt;
&lt;li&gt;Figure out how you want to arrange the items within your menu&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Recently, we’ve been adding a lot of content to our site.  We wanted to link more pages in our navigation, but still keep the top level navigation bar minimal.  So we went with a mega menu.  &lt;/p&gt;
&lt;h2&gt;
  
  
  Let’s Build
&lt;/h2&gt;

&lt;p&gt;For this tutorial, we'll be building this copycat mega menu:&lt;br&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%2Fcbhafsln8ak81cf8sz6d.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%2Fcbhafsln8ak81cf8sz6d.png" alt="Completed Navbar on laptop screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll be working off a &lt;a href="https://github.com/grouparoo/nextjs-react-bootstrap-boilerplate" rel="noopener noreferrer"&gt;boilerplate project&lt;/a&gt;&lt;br&gt;
with &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;NextJS&lt;/a&gt;, &lt;a href="https://react-bootstrap.github.io/" rel="noopener noreferrer"&gt;React Bootstrap&lt;/a&gt;,&lt;br&gt;
&lt;a href="https://sass-lang.com/" rel="noopener noreferrer"&gt;SASS&lt;/a&gt;, and &lt;a href="https://github.com/FortAwesome" rel="noopener noreferrer"&gt;Fort Awesome&lt;/a&gt;&lt;br&gt;
already imported and ready to go. Coffee themed, because of course.&lt;/p&gt;

&lt;p&gt;React Bootstrap, and Bootstrap in general are great. The built-in components, classes, and utilities save a lot of time building responsive layouts, and they're accessible by default. They’re also super flexible. For those less comfortable with front end, Bootstrap's &lt;a href="http://www.getbootstrap.com" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; is full of copy-and-pasteable examples to get started making modern, accessible sites. And once you've been working with Bootstrap for a while, it becomes almost second nature to Frankenstein pieces together like we're about to do.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 To get started, fork &lt;a href="https://github.com/grouparoo/nextjs-react-bootstrap-boilerplate" rel="noopener noreferrer"&gt;this&lt;br&gt;
repo&lt;/a&gt; and &lt;code&gt;npm install&lt;/code&gt;!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here is our &lt;code&gt;Navbar&lt;/code&gt; element starting out:&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%2Fb4i4eih3v7i3tn8rkbyl.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%2Fb4i4eih3v7i3tn8rkbyl.png" alt="Basic Navbar from boilerplate"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When developing our mega menu for Grouparoo, I started with this Figma mockup.  From there, I looked at what React Bootstrap components to use.  We did end up making a few design changes further into the process, but it all started with:&lt;br&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%2Fpom7lymy9xynh4qaqb85.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%2Fpom7lymy9xynh4qaqb85.png" alt="Mock up of Mega Menu for Grouparoo Nav"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We're going to build something similar where the "events" link currently lives on our template.  &lt;/p&gt;

&lt;p&gt;Let's start by adding the following into &lt;code&gt;/components/navigation.js&lt;/code&gt; in place of the current &lt;code&gt;Nav.Link&lt;/code&gt; for events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NavDropdown&lt;/span&gt;
  &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"pr-2 py-2 align-text-top"&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Events"&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"basic-nav-dropdown"&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"eventsNav pt-0 mt-0"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Col&lt;/span&gt; &lt;span class="na"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"12"&lt;/span&gt; &lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"6"&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-left"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FontAwesomeIcon&lt;/span&gt;
            &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"black"&lt;/span&gt;
            &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;concierge-bell&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1x"&lt;/span&gt;
            &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"pr-1"&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          Catering
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"nav-link"&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              Corporate
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"nav-link"&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              Private
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Divider&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FontAwesomeIcon&lt;/span&gt;
            &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"black"&lt;/span&gt;
            &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chalkboard-teacher&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1x"&lt;/span&gt;
            &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"pr-1"&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          Classes
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"nav-link"&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              Barista 101
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"nav-link"&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              History of Coffee
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"nav-link"&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              Intro to Cafe Snobbery
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Divider&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"d-md-none"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Col&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Col&lt;/span&gt; &lt;span class="na"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"12"&lt;/span&gt; &lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"6"&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-left"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FontAwesomeIcon&lt;/span&gt;
            &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"black"&lt;/span&gt;
            &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;building&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1x"&lt;/span&gt;
            &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"pr-1"&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          Rentals
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"nav-link"&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              Fireside Room
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"nav-link"&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              Roasting Room
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Divider&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FontAwesomeIcon&lt;/span&gt;
            &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"black"&lt;/span&gt;
            &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sun&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1x"&lt;/span&gt;
            &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"pr-1"&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          Seasonal
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"nav-link"&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              Coldbrew Night
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"nav-link text-wrap"&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              Campfire Coffee Class
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Dropdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Col&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;NavDropdown&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's where we're at: &lt;br&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%2Fr1odyc9am5lfxl1u3aax.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%2Fr1odyc9am5lfxl1u3aax.png" alt="Partly completed navigation dropdown"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's all there... but obviously in need of some help. I applied a custom &lt;code&gt;className&lt;/code&gt;&lt;br&gt;
of &lt;code&gt;eventsNav&lt;/code&gt; to the dropdown container knowing I'd need to add some SASS. It is&lt;br&gt;
wise to avoid custom styles (inline or on a stylesheet) if possible when working&lt;br&gt;
with Bootstrap as it can make debugging more difficult. However, sometimes, to strictly override the Bootstrap styles, it's necessary. Add the following to &lt;code&gt;/styles/styles.scss&lt;/code&gt;&lt;br&gt;
:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.nav-link&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.95rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#basic-nav-dropdown&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.95rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#seeMoreLink&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#607d8b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;#seeMoreLink&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;400&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.dropdown-menu&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.dropdown-item&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.dropdown-item&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.dropdown-item&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.dropdown-header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.eventsNav&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;22em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1em&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;Most of those rules are just visual adjustments to match fonts, remove text decorations, etc.  The ultra important rule there is the final &lt;code&gt;@media&lt;/code&gt; query that sets the width of &lt;code&gt;.eventsNav&lt;/code&gt;.  That rule is how we tell Bootstrap we want our dropdown menu's container a specific size.&lt;/p&gt;

&lt;p&gt;Et voila!  A mega menu showcasing multiple categories worth of pages (all the links currently point to home, but they work!): &lt;br&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%2Fcbhafsln8ak81cf8sz6d.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%2Fcbhafsln8ak81cf8sz6d.png" alt="Completed Navbar on laptop screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And on mobile additional divider divs appear and the columns expand to full container width.  Again, Bootsrap's utilities for working with screen size breakpoints are 👌:&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%2Fw56ccui0syfq725csjfh.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%2Fw56ccui0syfq725csjfh.png" alt="Mobile view of completed tutorial"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check out the original version live &lt;a href="http://www.grouparoo.com" rel="noopener noreferrer"&gt;here&lt;/a&gt; or star our &lt;a href="https://github.com/grouparoo/www.grouparoo.com" rel="noopener noreferrer"&gt;site repo&lt;/a&gt; or &lt;a href="https://github.com/grouparoo/grouparoo" rel="noopener noreferrer"&gt;core product&lt;/a&gt; to see more.  Or better yet, we're open source!  Drop us a PR!&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>nextjs</category>
      <category>react</category>
      <category>bootstrap</category>
    </item>
    <item>
      <title>Apple Migration Tips for M1 Macs</title>
      <dc:creator>Teal Larson</dc:creator>
      <pubDate>Thu, 29 Apr 2021 22:38:27 +0000</pubDate>
      <link>https://dev.to/grouparoo/apple-migration-tips-for-m1-macs-5dmf</link>
      <guid>https://dev.to/grouparoo/apple-migration-tips-for-m1-macs-5dmf</guid>
      <description>&lt;p&gt;Last week, I upgraded to a M1 Macbook Pro. I got it configured for development and 48 hours later, through a series of unfortunate events and hardware failure, I ended up with a &lt;em&gt;second&lt;/em&gt; M1 Macbook Pro instead. The transition between computers wasn’t too bad thanks to Apple’s &lt;a href="https://support.apple.com/en-us/HT204350" rel="noopener noreferrer"&gt;Migration Assistant&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I ran into an interesting situation, though. About 90% of the migration worked as expected or better, but the other 10% presented some puzzling blockers. Luckily, I worked through all the weirdness so you don’t have to! Let’s chat the good, the bad, and the ugly of migrating between Apple M1 Macs using Apple Migration Assistant.&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%2F68brobvxb26mepkyny13.jpeg" 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%2F68brobvxb26mepkyny13.jpeg" alt="Apple Migration Assistant Screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;br&gt;
  Apple Migration Assistant makes switching machines nearly seamless.&lt;br&gt;
&lt;/small&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Good: Applications and data stay mostly intact
&lt;/h2&gt;

&lt;p&gt;I mean, this is what Apple Migration Assistant bills itself as doing, so I’m not sure if you get points for doing what is expected of you, but it’s truly great.&lt;/p&gt;

&lt;p&gt;While most of my work is regularly backed up online, I do run a few programs locally. More on apps to come, but I was happy to see that, at the very least, VSCode and Homebrew were still alive and kicking. My SSH configurations were good to go which was really nice. Even my databases, which were installed via Homebrew, were up and running!&lt;/p&gt;

&lt;p&gt;I was pleasantly surprised to open Terminal on my new machine and see my most recent tabs still there. What’s more, they still had the same code I’d left them with which felt somehow cozy in a weird, nerdy way.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Bad: Get ready to re-set a lot of permissions
&lt;/h2&gt;

&lt;p&gt;Why on earth Apple remembered that I ran &lt;code&gt;pnpm install&lt;/code&gt; two days ago, but not that Chrome has permission to share my desktop and camera, I have no idea. I also had to sign back into iCloud a lot of times. Fairly annoying? Yeah. But doable.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Ugly: Apple Migration Application Purgatory
&lt;/h2&gt;

&lt;p&gt;While all my apps transferred over correctly, a few had some bizarre behavior. Bizarre as in when I clicked on them &lt;strong&gt;nothing&lt;/strong&gt; happened. Nothing on the screen, nothing on the Activity Monitor, zilch. I rebooted, uninstalled, deleted cached files, and reinstalled multiple times. Still no activity.&lt;/p&gt;

&lt;p&gt;Before I move on, it’s important to know about an application called Rosetta. You can’t run software built for an Intel chip on the new M1 chips. Rosetta acts as a middle man. According to &lt;a href="https://support.apple.com/en-us/HT211861" rel="noopener noreferrer"&gt;Apple&lt;/a&gt;, “Rosetta 2 works in the background whenever you use an app built only for Mac computers with an Intel processor. It automatically translates the app for use with Apple silicon.” In an ideal case, you won’t even know Rosetta is there aside from maybe a slower launch time.&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%2F60bybeqk9673ybmjl575.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%2F60bybeqk9673ybmjl575.png" alt="Rosetta install alert screenshot"&gt;&lt;/a&gt;&lt;br&gt;
&lt;small&gt;&lt;br&gt;
  This alert would have been handy!&lt;br&gt;
&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;When you go to launch an app that needs Rosetta, MacOS should prompt you to install Rosetta2 if you don't have it yet. And it does! Except after a migration. I ran into this with a screen sharing tool we use daily here at Grouparoo.&lt;/p&gt;

&lt;p&gt;I’m not entirely sure why Rosetta doesn’t migrate (or come native) if it’s used by so many apps right now, but it doesn’t.&lt;/p&gt;

&lt;p&gt;What was happening with my mysteriously inactive apps was that they migrated just fine, but couldn’t be executed. MacOS wasn’t registering that it was my first time running the application, either, so I didn't get a prompt to install Rosetta2. This is what I’ve come to term "Apple Migration Purgatory ™ ". The program ends up just… sitting there. Doing nothing. Fully installed, but fully unreadable, having its own little existential crisis.&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%2Fy9zjvssc8bbhi1rphj1c.gif" 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%2Fy9zjvssc8bbhi1rphj1c.gif" alt="Zoolander has an existential crisis.  Source: https://media.giphy.com/media/1I6HRxR7pQojS/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I made this discovery a few headaches later, when I went to install &lt;a href="https://freemacsoft.net/appcleaner/" rel="noopener noreferrer"&gt;App Cleaner&lt;/a&gt;. App Cleaner is a handy tool that can show you every file associated with a given application. And guess what popped up when I installed it… an alert to install Rosetta2. Just like that, my other software was suddenly usable now too!&lt;/p&gt;

&lt;p&gt;There were a few other small, similar hiccups. While Homebrew migrated over, for some reason my XCode CLI tools did not (and again, no prompt… they just didn’t work).&lt;/p&gt;

&lt;p&gt;Overall, if you’re running into issues with your Mac after migrating, take a look at whether you need to install or update Rosetta or XCode.&lt;/p&gt;
&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;If applications are not running as expected after migrating your computer, check that Rosetta2 and XCode CLI tools are installed and up-to-date:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo xcode-select --install  # install xcode tools
softwareupdate --install-rosetta  # install rosetta
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>todayilearned</category>
      <category>macos</category>
      <category>apple</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Take Smarter Notes to Boost Understanding and Memory!</title>
      <dc:creator>Teal Larson</dc:creator>
      <pubDate>Wed, 17 Mar 2021 00:57:59 +0000</pubDate>
      <link>https://dev.to/teallarson/take-smarter-notes-to-boost-understanding-and-memory-3hj5</link>
      <guid>https://dev.to/teallarson/take-smarter-notes-to-boost-understanding-and-memory-3hj5</guid>
      <description>&lt;p&gt;This past year has been crazy hard on us all. A few weeks ago I really felt like I hit a wall with learning new things, career growth, all of it. So I shifted my focus a bit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Giving Back
&lt;/h3&gt;

&lt;p&gt;Now I'm trying to spend part of my work time creating resources to help those just starting out their journey learning to code!&lt;/p&gt;

&lt;p&gt;So far I've done articles on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/tealdoestech/teachers-the-agile-development-ogs-39in"&gt;Agile methodologies and teachers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/tealdoestech/the-dutch-flag-quick-sort-4k8n"&gt;The Dutch Flag quick sort&lt;/a&gt; 
(and currently in drafts: Boyer-Moore-Horspool, my favorite string search!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Today, I'm reaching back to my days spent literally studying how people learn...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--49FeB4kY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1pww21wm29kbp16nhdky.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--49FeB4kY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1pww21wm29kbp16nhdky.png" alt="Screenshot of Cornell Notes Page"&gt;&lt;/a&gt;&lt;sup&gt;&lt;em&gt;Sample of my Cornell Notes Notion template&lt;/em&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Cornell Notes Matter
&lt;/h3&gt;

&lt;p&gt;Today I'm taking it back to my teaching roots with a learning resource!  My favorite notetaking style to teach was Cornell Notes.  It was a part of the AVID (&lt;a href="https://www.avid.org/"&gt;Advancement via Individual Determination&lt;/a&gt;) skills that I taught.  Essentially it involves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Taking notes using ideas, shorthand, sketches, etc. (rather than full sentences)&lt;/li&gt;
&lt;li&gt;Going back to add a main idea or guiding question for each section&lt;/li&gt;
&lt;li&gt;Summarizing each page based only on the main ideas/questions (cover the notes!)&lt;/li&gt;
&lt;li&gt;Reviewing the notes multiple times (I did 24 hour, 48 hour, and one week later)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Developing the main ideas, then by summarizing from those main ideas only help to build connections and process what was learned, versus regurgitating information.  The review helps to cement those neural pathways each time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Get Started!
&lt;/h3&gt;

&lt;p&gt;I've really fallen in love with Notion recently.  Naturally, I created a Notion template for Cornell Notes🙌. It includes a notebook and notetaking sheet that you can duplicate. It's designed to use Cornell Notes' review and repetition strategies to boost memory and understanding. I hope you find it useful!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7b93rJxj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o2qvhghaq1hn9jxn9pek.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7b93rJxj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o2qvhghaq1hn9jxn9pek.png" alt="Cornell Notes Notebook screenshot"&gt;&lt;/a&gt;&lt;sup&gt;&lt;em&gt;Preview of the Notebook layout&lt;/em&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Free Template:
&lt;/h5&gt;

&lt;p&gt;Get the template &lt;a href="https://www.tealjulia.com/#resources"&gt;here&lt;/a&gt; and duplicate it to your Notion workspace!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>learning</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Teachers: The Agile Development OGs</title>
      <dc:creator>Teal Larson</dc:creator>
      <pubDate>Tue, 02 Mar 2021 18:03:04 +0000</pubDate>
      <link>https://dev.to/teallarson/teachers-the-agile-development-ogs-39in</link>
      <guid>https://dev.to/teallarson/teachers-the-agile-development-ogs-39in</guid>
      <description>&lt;p&gt;While I've been coding off and on since grade school, my first career was as a teacher.  I specialized in working with &lt;a href="https://www.edweek.org/policy-politics/at-promise-can-a-new-term-for-at-risk-change-a-students-trajectory/2020/01" rel="noopener noreferrer"&gt;at-promise youth&lt;/a&gt; and students with low literacy.  My last teaching position was as a middle school reading specialist.  I had ~100 students a day, all considered "below standard" in their reading skills.  I also had no set curriculum.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Teaching, at least how I have seen it practiced, is an inherently agile workflow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Designing and implementing my own curriculum was a huge undertaking.  It morphed yearly, quarterly, monthly, weekly, even hour-by-hour based upon need.  Even teachers &lt;em&gt;with&lt;/em&gt; a curriculum dedicate hours adapting it to their students' needs.&lt;/p&gt;

&lt;p&gt;When I first decided to pivot into a tech career, I had never heard of "agile software development".  The more I learn about and see agile in action, the more I realize that teaching, at least how I have seen it practiced, is an inherently agile workflow. Many parts of teaching include the foresight and planning in Waterfall style development.  But in an even bigger way, teachers need to be quick on their feet and adapt on the fly.  And &lt;em&gt;that&lt;/em&gt; is what agile is about, adapting to changing needs.&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%2F0iok4x0l3cdtcilk1aq3.jpg" 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%2F0iok4x0l3cdtcilk1aq3.jpg" alt="Students seated at a table in a classroom.  Image via Unsplash."&gt;&lt;/a&gt;&lt;sup&gt;&lt;em&gt;image via Unsplash&lt;/em&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Core components of agile workflow
&lt;/h2&gt;

&lt;p&gt;I started to compare my work as a teacher to what I was learning about agile. I read through the &lt;a href="https://agilemanifesto.org/" rel="noopener noreferrer"&gt;Agile Manifesto&lt;/a&gt;, replacing "customer" with student.  I have to say, the metaphor fits.  The items below are adapted straight from the Agile Manifesto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Early and continuous delivery of a useful product
# Welcome changing requirements, even late in development
# Frequently delivered product (weeks rather than months)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Usable Information -- early and frequently
&lt;/h3&gt;

&lt;p&gt;Students can't wait until 30 minutes into a lesson to get information they can act on.  They need relevant, actionable learning quick and often.  Not only that, teachers need feedback.  Is the "product" (the teaching) was having the intended outcome.  Is it usable in the intended fashion?  Does the teacher need to pivot the lesson?&lt;/p&gt;

&lt;p&gt;As a teacher, it is so important to get incremental feedback.  Waiting until the end of a week or month-long unit to check in with the "customer" is a recipe for disaster. &lt;/p&gt;

&lt;h3&gt;
  
  
  Providing an MVP Guides Efficiency
&lt;/h3&gt;

&lt;p&gt;Customers are more satisfied with a product when they receive a useful product as soon as possible.  In agile this is called a "minimum viable product".   The top priority features get completed first as part of the MVP.  Then, the team can see how their customer interacts with the product and gather feedback.&lt;/p&gt;

&lt;p&gt;This not only increases customer satisfaction, but also the engineers' efficiency.  This early information lets the team know if their plans need adjusting right out of the gate.  It helps keep everyone on the same page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Close, daily cooperation between business people and developers
# Projects are built around motivated individuals, who should be trusted
# Face-to-face conversation is the best form of communication
# Self-organizing teams
# Collocation and pair programming
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Teachers Collaborate as a Way of Life
&lt;/h3&gt;

&lt;p&gt;This set of principles are basic guidelines for effective collaboration in any setting.&lt;/p&gt;

&lt;p&gt;As a reading specialist, I worked with at least eight different teams of professionals. These included grade level teams, subject area teams, district teams, and more.  Luckily, each team worked smoothly overall.  We were well-trusted by those around us to make the right decisions for student learning.  The frequent face-to-face meetings I was a part of helped me get input and ideas from teammates.  We were able to take information we had from our "clients" and adjust the sails of our plans.&lt;/p&gt;

&lt;p&gt;Likewise, in an agile environment, the onus is on teams completing work instead of external micromanagement.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Pair Programming
&lt;/h3&gt;

&lt;p&gt;An interesting part of agile is "pair programming".  In pair programming, one programmer is a "driver" and the other is the "navigator".  The navigator  thinks out loud, walking through the overall directions. The driver is the one doing the typing itself.  These roles are to switch every few minutes.  In the long-run, this helps spread knowledge across a team so all become experts.  This reminds me of observation rotations.  Teachers would sometimes go watch other teachers during their own planning times to gain insight and ideas.&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%2Fo0wq0gd4rldjzrf0liw6.jpg" 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%2Fo0wq0gd4rldjzrf0liw6.jpg" alt="sticky notes on a window"&gt;&lt;/a&gt;&lt;sup&gt;&lt;em&gt;image via Unsplash&lt;/em&gt;&lt;/sup&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Sustainability/the ability to maintain a constant pace
# Excellence through reflection
# Simplicity — the art of maximizing the amount of work not done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Notebook
&lt;/h3&gt;

&lt;p&gt;As a reading specialist, I was "a part" of many teams, but I was also apart from them.  I had an outsider view into their inner workings.  One team I worked with was especially great at working efficiently.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Their reflection fueled their simplicity, which led to a sustainable practice.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They completed team meetings in an hour flat or less each week.  Their students were engaged, knew expectations for their assignments, and completed quality work.&lt;/p&gt;

&lt;p&gt;You know what their secret was?  They spent a good chunk of their meeting time in reflection.  They also kept a running notebook reflecting on what had gone well (or not).  It was a simple composition notebook where they recorded outcomes and reflections.  This notebook served as a wonderful reference when they were planning.  They knew if they'd tried something similar before and what had went well (or not).  Their reflection fueled their simplicity, which led to a sustainable practice.&lt;/p&gt;

&lt;h3&gt;
  
  
  The reflection, simplicity, sustainability cycle
&lt;/h3&gt;

&lt;p&gt;Likewise, agile software development encourages keeping a constant pace.  This means there aren't quick accelerations followed by burnout.  Simplicity makes an even pace achievable.  At first glance, agile development seems to have less up front planning than waterfall.  This may be true, but a solid plan is essential in agile development too to keep a steady pace.  That planning should be effective and adaptable and, of course, fueled by reflection.  Reflective and adaptive planning are crucial in today's rapidly changing world.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Welcoming changing requirements, even late in the game
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Rolling with the Punches
&lt;/h3&gt;

&lt;p&gt;One trait that makes or breaks a teacher's success is flexibility.  The plans for a day (or week) may change for any number of reasons. Teaching is a series of moving targets.  And while flexibility is key, teachers also maintain their vision.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Flexibility for the sake of growth is the name of the game in the 21st century.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Agile Software Manifesto claims that being adaptive gives customers a competitive advantage.  To be successful, it is necessary to be able and willing to pivot while maintaining vision.  Failing to do so may put another competitor ahead in a day and age where the playing field moves constantly.  Flexibility for the sake of growth is the name of the game in the 21st century.&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%2Fq17r44sfsiy7xi7yt7em.jpg" 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%2Fq17r44sfsiy7xi7yt7em.jpg" alt="small team collaborating at a laptop"&gt;&lt;/a&gt;&lt;br&gt;
&lt;sup&gt;&lt;em&gt;image via Unsplash&lt;/em&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A final note:
&lt;/h2&gt;

&lt;p&gt;Breaking into the software engineering and web development world can feel intimidating.  There are so many new terms and acronyms that everyone else seems to already know.  At times, I felt I would never catch up with it all.&lt;/p&gt;

&lt;p&gt;I've spent some time speaking with mentors of mine in software engineering.  I keep hearing that &lt;em&gt;knowing a programming language doesn't **really&lt;/em&gt;* make you a good programmer*.  &lt;/p&gt;

&lt;p&gt;What it comes down to is problem solving, grit, planning, ability to learn, and flexibility.  Every teacher I've ever worked with has those in spades.  My fellow teaching ex-pats, you're going to do great things!&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources:
&lt;/h2&gt;

&lt;p&gt;Want to learn more about program management?  Check out these resources to get started:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://agilemanifesto.org/" rel="noopener noreferrer"&gt;The Agile Manifesto&lt;/a&gt; - Might as well start by going straight to the source!  They break down the four key values and twelve key principles of Agile.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.atlassian.com/agile/scrum" rel="noopener noreferrer"&gt;Atlassian's guide on Scrum&lt;/a&gt; - Atlassian has SO much material on Agile work environments!  I especially love this page.  Scrum, kanban, and agile all get thrown around a lot.  This article hits the nail on the head if you're struggling to see how they relate. (And for the record, I'm team scrumban)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.atlassian.com/agile/project-management/program" rel="noopener noreferrer"&gt;Atlassian's guide on agile vs. waterfall&lt;/a&gt; -- No surprise, this article is biased in favor of an agile workflow. But, it does a succinct job pointing out key differences between the two styles.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.joinpathlight.com/roles/program-manager" rel="noopener noreferrer"&gt;Pathlight's Program Manager page&lt;/a&gt; -- Pathlight is great for exploring different roles in the tech industry.  Their program management page breaks down what the day-to-day flow is like and has helpful resources.  Pathlight's Slack community, Breaking Into Tech, is excellent for connecting with other tech professionals!&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>agile</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The 'Dutch Flag' Quick Sort</title>
      <dc:creator>Teal Larson</dc:creator>
      <pubDate>Mon, 22 Feb 2021 17:58:55 +0000</pubDate>
      <link>https://dev.to/teallarson/the-dutch-flag-quick-sort-4k8n</link>
      <guid>https://dev.to/teallarson/the-dutch-flag-quick-sort-4k8n</guid>
      <description>&lt;p&gt;Is it weird to have a favorite algorithm?  I definitely have a top four.  Maybe it's because they remind me of puzzles I loved solving as a kid -- when I was growing up, my dad never let us get a Nintendo.  Instead, I grew up solving logic puzzles in my spare time.  And... I still love them.  I think that's why I loved the data structures and algorithms prep in my bootcamp and why I've enjoyed studying for technical interviews. &lt;/p&gt;

&lt;p&gt;Over the next few weeks, I'll be sharing my favorite data structures and algorithms problems that I've worked with.  Starting with... quick sorting by a pivot point, AKA the Dutch flag problem.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rJqH-edN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b66tawvg54f99y7xujv8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rJqH-edN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b66tawvg54f99y7xujv8.jpg" alt="Image of a Dutch flag"&gt;&lt;/a&gt;&lt;br&gt;
&lt;sup&gt;&lt;em&gt;Image credit: Unsplash&lt;/em&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So what's the big problem?
&lt;/h2&gt;

&lt;p&gt;The Dutch Flag problem comes to us from the 1970's thanks to in his book, &lt;em&gt;A Discipline of Programming&lt;/em&gt; &lt;a href="//Edsger_W._Dijkstra"&gt;Edsger Dijkstra&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;The problem is usually presented in some form of the following:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Given an array of 0s, 1s, and 2s, sort the items in-place in ascending order.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;sup&gt;&lt;em&gt;&lt;a href="https://leetcode.com/problems/sort-colors/"&gt;leetcode.com&lt;/a&gt; uses a color sort scenario to present this&lt;/em&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;To me, the solution for this is a beautiful sort of "controlled chaos".  Once we get started, items in our array move all over the place, but thanks to some thoughtful pointers, we complete this problem in one fell swoop through the data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why would I use this solution?
&lt;/h3&gt;

&lt;p&gt;Some quicksort algorithms can take up to O(N^2) runtime if there are a large number of repeated items like we have here.  The algorithm outlined below works with any integer range input so long as a pivot point is given (for example an array with integers between 0-7 and a pivot point of, say, 3 could be sorted in this same way).  The only difference would be a tweak to the if statements, and the inclusion of an additional argument (the pivot).  The method I outline below solves this problem in &lt;strong&gt;O(N) runtime&lt;/strong&gt;, and &lt;strong&gt;0(1)&lt;/strong&gt;, or constant, &lt;strong&gt;space.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's go!
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Initialize Variables
&lt;/h3&gt;

&lt;p&gt;This solution depends on the use of three pointers.  We'll start by initializing two of them -- a high pointer and a low pointer -- as the last and first items in our array respectively.  The third we'll initialize as i -- this is where we will track what item we are evaluating.&lt;/p&gt;

&lt;p&gt;The high and low will track what space we should swap a high or low value to.  So essentially "low" is one index AFTER the last 0 we've placed so far, and "high" is one index BEFORE the last 2 we've placed so far.  And... since we haven't placed ANY yet, they are at the exact beginning and end of our array.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VOPYvapy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/li5xg1ad9kkktj2yvwfb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VOPYvapy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/li5xg1ad9kkktj2yvwfb.png" alt="Step 1 -- initializing variables for an array [2, 1, 1, 0, 2, 2, 1, 0, 2]"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Javascript
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sortColors = (nums) =&amp;gt; {
  let low = 0;
  let high = nums.length-1;
  let i = 0; 

};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Python
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solution(object):
    def sortColors(self, nums):
        high = len(nums)-1
        low = 0
        i = 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Set up our loop syntax
&lt;/h3&gt;

&lt;p&gt;Now, we know we need to visit each item to evaluate it.  That means we'll need a loop.  For this problem, we'll run a while loop while i &amp;lt;= high.  Why do we only need to run it while i &amp;lt;= high?  Well, because we know that everything PAST high has already been sorted into place.  We KNOW they are 2's.  Therefore, there's no need to evaluate them a second time.&lt;/p&gt;

&lt;p&gt;Since we know we're returning an updated version of the same array, we'll throw our return statement in there now, too.&lt;/p&gt;

&lt;h4&gt;
  
  
  Javascript
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sortColors = (nums) =&amp;gt; {
  let low = 0;
  let high = nums.length-1;
  let i = 0; 

while (i &amp;lt;= high) {
  if(nums[i] === 0){

  } else if (nums[i] === 2){

  } else {

  }
}
return nums;   

};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Python
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solution(object):
    def sortColors(self, nums):
        high = len(nums)-1
        low = 0
        i = 0

        while i&amp;lt;= high:
            if nums[i] == 0:

            elif nums[i] == 2:

            else:

        print nums
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Getting down to business -- swapping items
&lt;/h3&gt;

&lt;p&gt;Now that we're all set up, let's work through what will happen at each item in our array.  &lt;/p&gt;

&lt;p&gt;If nums[i] is == 0, we will swap the value of nums[i] with nums[low] and increment i AND low.  If nums[i]==2, we do the same swap but with [high] and decrement high.  However this time we &lt;em&gt;don't increment i&lt;/em&gt;.  Why is that?&lt;/p&gt;

&lt;p&gt;Logically, we know that nums[low] is a 1 (unless we're at index 0).  How?  Because we know that we must have already evaluated it and decided it didn't need to go anywhere.  Therefore, it must be a 1, so we can just increment our i and not worry about it.&lt;/p&gt;

&lt;p&gt;However, swapping from nums[high] we have no clue what we're getting really, it's from the end of the array, after i.  Therefore, after we swap with nums[high] we do NOT increment i because we need to evaluate whatever just got swapped in there!&lt;/p&gt;

&lt;h4&gt;
  
  
  Javascript
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sortColors = (nums) =&amp;gt; {
  let low = 0;
  let high = nums.length-1;
  let i = 0; 

while (i &amp;lt;= high) {
  if(nums[i] === 0){
      [nums[i], nums[low]] = [nums[low], nums[i]];
      low++;
      i++;
  } else if (nums[i] === 2){
      [nums[i], nums[high]] = [nums[high], nums[i]];
      high--;
  } else {
      i++;
  }
}
return nums;   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Python
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solution(object):
    def sortColors(self, nums):
        high = len(nums)-1
        low = 0
        i = 0

        while i&amp;lt;= high:
            if nums[i] == 0:
                nums[low], nums[i] = nums[i], nums[low]
                i += 1
                low +=1
            elif nums[i] == 2:
                nums[i], nums[high] = nums[high], nums[i]
                high -=1
            elif nums[i] == 1:
                i += 1
        print nums
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's a brief run through using the sample array from above.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QLrfLxRF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qwq2ezo4dw65b442m8oo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QLrfLxRF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qwq2ezo4dw65b442m8oo.png" alt="arr[0] == 2 so swap with high, decrement high to arr[7] "&gt;&lt;/a&gt;&lt;br&gt;
First, we swap the value at i with the value at high and decrement high.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Sp9Czwen--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6flm15t47d4a3a6u608i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Sp9Czwen--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6flm15t47d4a3a6u608i.png" alt="the new arr[0] == 2 so swap again.  high is now == arr[6]"&gt;&lt;/a&gt;&lt;br&gt;
Another 2, so same thing again.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dUN-d39R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v6nhkud295eyt8zca77s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dUN-d39R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v6nhkud295eyt8zca77s.png" alt="increment past arr[1], arr[2]"&gt;&lt;/a&gt;&lt;br&gt;
Next are a few ones... We increment i and then at the next item (also a 1) we increment again.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M6Jug9eU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pmukv4mo8g4p0izf74mr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M6Jug9eU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/pmukv4mo8g4p0izf74mr.png" alt="Swap arr[3]with low, increment i and low"&gt;&lt;/a&gt;&lt;br&gt;
Swap arr[3] with low and increment i and low.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--skrcRh8j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cchnoteqs325e2wx7ujz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--skrcRh8j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cchnoteqs325e2wx7ujz.png" alt="swap arr[4] with high, decrement high"&gt;&lt;/a&gt;&lt;br&gt;
Another 1, so we increment i and then.....&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZHamjInj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nq1ny63tnl74todr17c0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZHamjInj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nq1ny63tnl74todr17c0.png" alt="i==high"&gt;&lt;/a&gt;&lt;br&gt;
Hopped over arr[4] is a 1 so we increment, then arr[5] is a 2, so it technically swaps with itself, then breaks the loop as i is higher than i.&lt;/p&gt;

&lt;p&gt;Hooray!  All sorted out!&lt;/p&gt;

&lt;p&gt;Now is when you will want to run more tests. Anytime you're working on a problem like this, you'll want to think about what "edge cases" could throw you for a(n infinite) loop.:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We know our range only contains positive integers, so no need to worry about negatives.&lt;/li&gt;
&lt;li&gt;What if we got an empty array?&lt;/li&gt;
&lt;li&gt;What if our array was all 0's? All 1's?  All 2's?&lt;/li&gt;
&lt;li&gt;What if it was already sorted?&lt;/li&gt;
&lt;li&gt;What if it was already sorted in descending order?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will leave you to check those out on your own.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EkKiIEa_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c4rm41rtx0adbrn1ivx6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EkKiIEa_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c4rm41rtx0adbrn1ivx6.jpg" alt="Person with black painted nails, tattoos, and jewelry explaining something while sitting at their laptop"&gt;&lt;/a&gt;&lt;br&gt;
&lt;sup&gt;&lt;em&gt;Image credit: Unsplash&lt;/em&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Before I go
&lt;/h3&gt;

&lt;p&gt;As a final note... you can solve all the problems you want, but in the end, a big part of the interview is being able to &lt;strong&gt;clearly communicate&lt;/strong&gt; what is happening in your mind.  In my experience talking through my thinking while writing (or typing!) as a teacher, it gets &lt;em&gt;much&lt;/em&gt; easier with practice.  It becomes second nature eventually.  Seriously, I think out loud all day long, for better or for worse.  Talk through the problems you're practicing as you solve them.  Tell anyone who will listen -- your dog, your cousin, your partner, yourself -- and then tell me how it goes!  These skills will not always come easy, but they can come with practice and hard work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Free resources:
&lt;/h3&gt;

&lt;p&gt;There are so many places to practice and learn about data structures and algorithms!  Here are a few free options that I've found helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.leetcode.com"&gt;Leetcode&lt;/a&gt; - Practice problems for data structures and algorithms.  Really easy to search by topic or difficulty.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.hackerrank.com"&gt;HackerRank&lt;/a&gt; - Another practice problems site.  HackerRank tends to give more of a background story for their challenges.  Some people love that, others don't. Some employers use their platform to screen candidates. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://codesignal.com/developers/"&gt;Code Signal&lt;/a&gt; - This was recommended to me by a mentor.  He's used it in the hiring process as a screener.  The practice problems are presented in a more gamified way than the sites above. &lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.geeksforgeeks.com/"&gt;Geeks for Geeks&lt;/a&gt; - Really great guides for solving problems.  They present multiple solutions and outline the runtime for them.  It's worth noting most solutions are only given in a limited number of languages, but the &lt;em&gt;logic&lt;/em&gt; shared is so valuable.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.youtube.com"&gt;YouTube&lt;/a&gt; - So many great channels for data structures and algorithms.  My top two favorites are &lt;a href="https://www.youtube.com/channel/UCmJz2DV1a3yfgrR7GqRtUUA"&gt;Back to Back SWE&lt;/a&gt; and &lt;a href="https://www.youtube.com/channel/UCnxhETjJtTPs37hOZ7vQ88g"&gt;Tech Dose&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>codenewbie</category>
      <category>algorithms</category>
      <category>javascript</category>
      <category>python</category>
    </item>
  </channel>
</rss>
