<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Leonel Mandarino</title>
    <description>The latest articles on Forem by Leonel Mandarino (@skydler).</description>
    <link>https://forem.com/skydler</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%2F193332%2Fe850c2cd-4b76-432e-acc1-73fd01fd5711.jpg</url>
      <title>Forem: Leonel Mandarino</title>
      <link>https://forem.com/skydler</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/skydler"/>
    <language>en</language>
    <item>
      <title>Building a Wordle helper with Vue.js 3.0</title>
      <dc:creator>Leonel Mandarino</dc:creator>
      <pubDate>Tue, 17 Jan 2023 01:31:49 +0000</pubDate>
      <link>https://forem.com/skydler/building-a-wordle-helper-with-vuejs-30-29c</link>
      <guid>https://forem.com/skydler/building-a-wordle-helper-with-vuejs-30-29c</guid>
      <description>&lt;p&gt;Howdy, stranger🤠. How you doin'? I'm in the process of learning &lt;a href="https://vuejs.org/"&gt;Vue.js&lt;/a&gt; and as an easy project to get started with the main concepts I'll be building a &lt;a href="https://www.nytimes.com/games/wordle/index.html"&gt;Wordle&lt;/a&gt; helper. &lt;br&gt;
So... since you are here, you might as well stick around and take this as an introductory article to Vue or as a project idea if you will 😁.&lt;/p&gt;

&lt;p&gt;But first let's get...&lt;/p&gt;
&lt;h2&gt;
  
  
  The basic idea 🌠
&lt;/h2&gt;

&lt;p&gt;How does this "Wordle helper" works? First you need to know what Wordle is... okay I'll give you 2 secs, go google it quick... &lt;a href="https://www.google.com/search?q=what+is+wordle&amp;amp;oq=what+is+wordle"&gt;here let me help you&lt;/a&gt;. &lt;br&gt;
Right! It would be very &lt;em&gt;helpful&lt;/em&gt; to have a list of Wordle words because I haven't memorized the &lt;a href="https://towardsdatascience.com/loaded-words-in-wordle-e78cb36f1e3c"&gt;near 13000 words&lt;/a&gt; on the game. Also it would be VERY helpful to filter these words as needed based on the guesses we make in the game.&lt;/p&gt;

&lt;p&gt;For example we could have this interface:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kKNoJTNR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lv63y6w15vfk96fn09ac.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kKNoJTNR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lv63y6w15vfk96fn09ac.png" alt="Helper initial interface" width="880" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please take a breath and be sure to not get your mind blown...&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting our hands dirty
&lt;/h2&gt;

&lt;p&gt;Okay we have everything we need to start coding fun stuff. Now let's create a simple Vue app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init vue@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And after removing the files of the default Vue greeting, I've come up with this directory structure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KV3-pfFF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lle2rdmlav6qh3zt66ma.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KV3-pfFF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lle2rdmlav6qh3zt66ma.png" alt="Directory structure" width="195" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hey but wait a second, what are those folders and files? We'll get there.&lt;/p&gt;
&lt;h3&gt;
  
  
  Showing the words
&lt;/h3&gt;

&lt;p&gt;First we need the dataset with all the words from Wordle. After 3 intense seconds on the browser I found &lt;a href="https://github.com/tabatkins/wordle-list/"&gt;this repo&lt;/a&gt;. Let's define a function to fetch the words, also let's extract this function to it's own file just to remove some unncesessary logic from the main file and keep things simple.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/api/wordList.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;retrieveWords&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;words_txt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://raw.githubusercontent.com/tabatkins/wordle-list/main/words&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

  &lt;span class="c1"&gt;// This is useful because it will return an array of just words&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;words_txt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We need a way to show the list of possible words given the letters on the inputs. This should do the trick for now.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/App.vue&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;retrieveWords&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./api/wordList.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;retrieveWords&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;total_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;m_words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&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="c1"&gt;// I've kept the the main list with all the words on it's own variable.&lt;/span&gt;
&lt;span class="c1"&gt;// But I've defined another array which will contain the *filtered* words&lt;/span&gt;
&lt;span class="c1"&gt;// after inserting letters on the inputs.&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;total_words&lt;/span&gt; &lt;span class="o"&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;m_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Possible&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;m_words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;(word, index) in m_words&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;index&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;word&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Inputs
&lt;/h3&gt;

&lt;p&gt;We need to add the inputs that we'll use to filter the list of words! We need to treat each letter on the input as an independent box &lt;strong&gt;because the order of the letters matter&lt;/strong&gt;. So let's define the green, yellow and grey filters.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;word_filters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;green_letters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;yellow_letters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;grey_letters&lt;/span&gt;&lt;span class="p"&gt;:&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And... we need to render this on the template&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Green letters:&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
      &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"n in 5"&lt;/span&gt;
      &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"n"&lt;/span&gt;
      &lt;span class="na"&gt;v-model.trim=&lt;/span&gt;&lt;span class="s"&gt;"word_filters.green_letters[n - 1]"&lt;/span&gt;
      &lt;span class="na"&gt;maxlength=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;
      &lt;span class="na"&gt;size=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;
      &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"_"&lt;/span&gt;
    &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Yellow letters:&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
      &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"n in 5"&lt;/span&gt;
      &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"n"&lt;/span&gt;
      &lt;span class="na"&gt;v-model.trim=&lt;/span&gt;&lt;span class="s"&gt;"word_filters.yellow_letters[n - 1]"&lt;/span&gt;
      &lt;span class="na"&gt;maxlength=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;
      &lt;span class="na"&gt;size=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;
      &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"_"&lt;/span&gt;
    &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Grey letters:&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;v-model.trim=&lt;/span&gt;&lt;span class="s"&gt;"word_filters.grey_letters"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Filtering
&lt;/h3&gt;

&lt;p&gt;Let's take a 5 minute break from Vue. Before we continue we need to define the pieces that will do the actual computation and filtering. We'll need the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;filterMatching words, for the green letters on the correct position&lt;/li&gt;
&lt;li&gt;filterContains words, for the yellow letters contained in the word but not in the position specified&lt;/li&gt;
&lt;li&gt;filterExcludes words, for the grey letters that should not be in the word.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No need to think too hard... final result:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/lib/matcher.js&lt;/span&gt;

&lt;span class="c1"&gt;// Exporting the functions that we will use&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;filterMatching&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;letters&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;matching_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;isMatchingWord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;normalize_letters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;letters&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;matching_words&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;filterContains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;letters&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;matching_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;hasLetters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;normalize_letters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;letters&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;matching_words&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;filterExcludes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;letters&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;matching_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;excludeWithLetters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;normalize_letters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;letters&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;matching_words&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;// ==============Helper functions===================&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;normalize_letters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;letters&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="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;letters&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&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;isMatchingWord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;match&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;let&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&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;match_letter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&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;word_letter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&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;match_letter&lt;/span&gt; &lt;span class="o"&gt;===&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="k"&gt;continue&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;match_letter&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;word_letter&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="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;hasLetters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;contains&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;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;letter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contains&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;word&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="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;letter&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="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;excludeWithLetters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;exclude&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;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;letter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;exclude&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;word&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;letter&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="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Connecting the dots
&lt;/h3&gt;

&lt;p&gt;Now we need to put all of this together. Let's also define a function to fire the filters and another to reset the list with all the words&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;handleReset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;m_words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;total_words&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;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;m_words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;filters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;word_filters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filterExcludes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;grey_letters&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filterContains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yellow_letters&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filterMatching&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;green_letters&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;m_words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And the template:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Wordle helper!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"handleReset"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Reset&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"handleSubmit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Save&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Possible words: {{ m_words.length }}&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"(word, index) in m_words"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"index"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {{ word }}
      &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Running the extra mile
&lt;/h3&gt;

&lt;p&gt;There is a little flaw in our app. As you might have noticed the app lags a bit when loading the 30000 words, that's because we are rendering 30000 &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; items on the HTML when the page loads.&lt;/p&gt;

&lt;p&gt;To fix this, we can opt for using a &lt;a href="https://github.com/Akryum/vue-virtual-scroller/tree/next/packages/vue-virtual-scroller"&gt;Virtual Scroller&lt;/a&gt; (luckly for us there is one for Vue 3.0) this will keep our page for rendering so many HTML tags and it will create a smooth and clean experience for our users.&lt;/p&gt;

&lt;p&gt;Here is the final piece of script&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="c1"&gt;// This is used by the template to put 3 words per row.&lt;/span&gt;
&lt;span class="c1"&gt;// These "rows" are generated dynamically on scroll by the RecycleScroller component&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;sliceIntoChunks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chunkSize&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;res&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;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;chunkSize&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;chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&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;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;chunkSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&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;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And template&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"display-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Wordle helper!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"m_words !== null"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"words-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"display-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Possible words: {{ m_words.length }}&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;RecycleScroller&lt;/span&gt;
      &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"scroller"&lt;/span&gt;
      &lt;span class="na"&gt;:items=&lt;/span&gt;&lt;span class="s"&gt;"sliceIntoChunks(m_words, 3)"&lt;/span&gt;
      &lt;span class="na"&gt;:item-size=&lt;/span&gt;&lt;span class="s"&gt;"45"&lt;/span&gt;
      &lt;span class="na"&gt;:keyField=&lt;/span&gt;&lt;span class="s"&gt;"null"&lt;/span&gt;
      &lt;span class="na"&gt;page-mode&lt;/span&gt;
      &lt;span class="na"&gt;v-slot=&lt;/span&gt;&lt;span class="s"&gt;"{ item }"&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;va-button&lt;/span&gt;
        &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"word-option"&lt;/span&gt;
        &lt;span class="na"&gt;:rounded=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
        &lt;span class="na"&gt;color=&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt;
        &lt;span class="na"&gt;gradient&lt;/span&gt;
        &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"(word, index) in item"&lt;/span&gt;
        &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"index"&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        {{ word }}
      &lt;span class="nt"&gt;&amp;lt;/va-button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/RecycleScroller&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-else&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"loading-div"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;va-progress-circle&lt;/span&gt; &lt;span class="na"&gt;indeterminate&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Also it would be nice to add some extra css to make things pretty and some quality of life changes to filter the words on each keypress. You can check the final result on my github repo!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Skydler"&gt;
        Skydler
      &lt;/a&gt; / &lt;a href="https://github.com/Skydler/wordler"&gt;
        wordler
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Wordler&lt;/h1&gt;
&lt;p&gt;Wordle helper because all the others weren't that nice&lt;/p&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Skydler/wordler"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



</description>
      <category>vue</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>AWS Hyperplane: Are Lambdas inside a VPC slow?</title>
      <dc:creator>Leonel Mandarino</dc:creator>
      <pubDate>Sun, 15 Jan 2023 01:46:29 +0000</pubDate>
      <link>https://forem.com/skydler/aws-hyperplane-are-lambdas-inside-a-vpc-slow-4mnb</link>
      <guid>https://forem.com/skydler/aws-hyperplane-are-lambdas-inside-a-vpc-slow-4mnb</guid>
      <description>&lt;p&gt;By default, when your Lambda function is not associated to your own VPCs, the function can access anything available on the public internet such as other AWS services, HTTPS endpoints for APIs, or services and endpoints outside AWS. The function then has no way to connect to your private resources inside your VPC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting to a VPC
&lt;/h2&gt;

&lt;p&gt;The way for your Lambdas to connect to private resources is by associating them with the VPC your resources reside in. This association is translated to an elastic network interface that lets traffic flow between function and VPC. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bzzqKw68--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/29wjbrpoekdioo37aw4e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bzzqKw68--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/29wjbrpoekdioo37aw4e.png" alt="Single Lambda using ENI to connect to a private VPC" width="665" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem?
&lt;/h3&gt;

&lt;p&gt;With this model, there are a number of challenges that you might face. The time taken to create and attach new network interfaces can cause longer cold-starts, increasing the time it takes to spin up a new execution environment before your code can be invoked.&lt;/p&gt;

&lt;p&gt;As your function’s execution environment scales to handle an increase in requests, more network interfaces are created and attached to the Lambda infrastructure. The exact number of network interfaces created and attached is a factor of your function configuration and concurrency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sPgVCC5F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7jtxisrks2l0x66hwqq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sPgVCC5F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7jtxisrks2l0x66hwqq8.png" alt="Multiple Lambdas, each one using an ENI to connect to a private VPC" width="880" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, each elastic network interface (ENI) uses an IP address of your VPC subnets so you could possibly reach a limit on the available IPs of your subnet, preventing you from creating additional resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution?
&lt;/h3&gt;

&lt;p&gt;So what should we do? Should we surrender to these trade-offs? Should we go for a different architecture?&lt;/p&gt;

&lt;p&gt;I've been there, I've done my research and I've tested that &lt;strong&gt;none of that happens currently&lt;/strong&gt;. There are a lot of outdated posts about it that generate a lot of misconceptions. That's the motivation of this post.&lt;/p&gt;

&lt;p&gt;Since 2019 AWS launched a new (internal) service called &lt;strong&gt;Hyperplane&lt;/strong&gt;, this service address the issues and drawbacks of putting lambdas inside private VPCs!&lt;/p&gt;

&lt;h4&gt;
  
  
  But... how?
&lt;/h4&gt;

&lt;p&gt;On a high level it's pretty simple and interesting, at least if you have some idea of how NAT works on a network. The idea it's basically the same, you have a bunch of lambdas living in the AWS infrastructure, but when you need to associate them with your VPC they all go through a NAT-ish service that translate each different lambda request to a resource by using only one ENI.&lt;/p&gt;

&lt;p&gt;It's very magical, and very convenient service. Because now, the difference in response times of VPC-ed Lambdas and normal Lambdas is almost negligible. I've tested this personally with my infrastructure but you can also see here &lt;a href="https://aws.amazon.com/blogs/compute/announcing-improved-vpc-networking-for-aws-lambda-functions/"&gt;a comparison made by AWS (with a more detailed explanation)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
    </item>
    <item>
      <title>How to successfully create habits</title>
      <dc:creator>Leonel Mandarino</dc:creator>
      <pubDate>Sat, 14 Jan 2023 21:39:23 +0000</pubDate>
      <link>https://forem.com/skydler/how-to-successfully-create-habits-g6g</link>
      <guid>https://forem.com/skydler/how-to-successfully-create-habits-g6g</guid>
      <description>&lt;p&gt;There are four rules that are needed to successfully form a new habit, and the opposites of these rules will break or prevent an existing habit. &lt;/p&gt;

&lt;p&gt;Disclaimer! All the information is taken from &lt;a href="https://www.amazon.com/gp/product/0735211299" rel="noopener noreferrer"&gt;Atomic Habits by James Clear&lt;/a&gt; so if you find this interesting you should check the book!&lt;/p&gt;

&lt;h2&gt;
  
  
  01: Make it obvious
&lt;/h2&gt;

&lt;p&gt;The main idea is to make your habits stand out, make them specific. Once you decide a time and a place to do them, you don't have to wait for inspiration to kick in. There is no need to make a decision. Simply follow your predetermined plan.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The simple way to apply this strategy to your habits is to fill out this sentence:&lt;br&gt;
I will [BEHAVIOR] at [TIME] in [LOCATION].&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another good trick to make them unavoidable it's called &lt;em&gt;habit stacking&lt;/em&gt;. Rather than pairing your new habit with a particular time and location, you pair it with a current habit.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The habit stacking formula is:&lt;br&gt;
After [CURRENT HABIT], I will [NEW HABIT].&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The key is to tie your desired behavior into something you already do each day. Once you have mastered this basic structure, you can begin to create larger stacks by chaining small habits together.&lt;/p&gt;

&lt;h3&gt;
  
  
  Environmental cues:
&lt;/h3&gt;

&lt;p&gt;The cues that trigger a habit can start out very specific, but over time your habits become associated not with a single trigger but with the entire &lt;em&gt;context&lt;/em&gt; surrounding the behavior. A stable environment where everything has a place and a purpose is an environment where habits can easily form.&lt;/p&gt;

&lt;p&gt;If you predispose your surroundings with the stuff that makes you remember your habit, you will probably be inclined toward that habit, even subconsciously. When you are at a party drinking with friends you probably drink more that if you are alone, that's because your context at that time makes it attractive to drink more. And that take us to our next rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  02: Make it attractive
&lt;/h2&gt;

&lt;p&gt;Habits are a dopamine-driven feedback loop. Every behavior that is highly habit-forming—taking drugs, eating junk food, playing video games, browsing social media—is associated with higher levels of dopamine.&lt;/p&gt;

&lt;p&gt;But dopamine isn't released only when you experience &lt;em&gt;pleasure&lt;/em&gt;, but also when you &lt;em&gt;anticipate&lt;/em&gt; it. And when dopamine rises, so does your motivation to act. It is the anticipation of a reward—not the fulfillment of it—that gets us to take action.&lt;/p&gt;

&lt;h3&gt;
  
  
  Culture:
&lt;/h3&gt;

&lt;p&gt;We are drawn to behaviors that earn us respect, approval, admiration, and status. The culture we live in determines which behaviors are attractive to us. We tend to adopt habits that are praised and approved of by our culture because we have a strong desire to fit in and belong to the tribe.&lt;br&gt;
One of the most effective things you can do to build better habits is to join a culture where your desired behavior is the normal behavior and you already have something in common with the group. So for example, if you want to start jogging more often, you could start by jogging with other people and making runner friends.&lt;/p&gt;

&lt;h2&gt;
  
  
  03: Make it easy
&lt;/h2&gt;

&lt;p&gt;To make a habit easy is to stop pressuring yourself to archive big goals in short periods of time. You don't need to start from zero to two hours at the gym every day. Just being there every day (or three times a week, whatever) it's enough to start, even if it's just 10 minutes.&lt;/p&gt;

&lt;p&gt;Habits are the automation of repeated tasks, so when forming a habit it's better to make a lot of simple repetitions than a few hard ones. Then, when you have form the habit, you can focus on improvement.&lt;/p&gt;

&lt;p&gt;Human behavior follows the Law of Least Effort. We will naturally gravitate toward the option that requires the least amount of work. Create an environment where doing the right thing is as easy as possible and doing the wrong thing is as hard as possible. If you want to stop using your phone each morning when you wake up, why not put the phone away or in another room?&lt;/p&gt;

&lt;h3&gt;
  
  
  Decisive moments
&lt;/h3&gt;

&lt;p&gt;Every day, there are a handful of moments that deliver an outsized impact. The moment you decide between ordering takeout or cooking dinner. The moment you choose between driving your car or riding your bike. The moment you decide between starting your homework or grabbing the video game controller. These choices are a fork in the road.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fjrbb4uq3tbt0juarg3e4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fjrbb4uq3tbt0juarg3e4.png" alt="Decision tree ramifiactions" width="552" height="545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are limited by where our habits lead us. This is why mastering the decisive moments throughout your day is so important. Each day is made up of many moments, but it is really a few habitual choices that determine the path you take. These little choices stack up, each one setting the trajectory for how you spend the next chunk of time.&lt;/p&gt;

&lt;h4&gt;
  
  
  Procrastination
&lt;/h4&gt;

&lt;p&gt;The idea is to make your habits as easy as possible to start. Anyone can meditate for one minute, read one page, or put one item of clothing away. And, as we have just discussed, this is a powerful strategy because once you’ve started doing the right thing, it is much easier to continue doing it. A new habit should not feel like a challenge. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The secret is to always stay below the point where it feels like work.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you show up at the gym five days in a row—even if it’s just for two minutes—you are casting votes for your new identity. You’re not worried about getting in shape. You’re focused on becoming the type of person who doesn’t miss workouts. You’re taking the smallest action that confirms the type of person you want to be.&lt;/p&gt;

&lt;h2&gt;
  
  
  04: Make it statisfying
&lt;/h2&gt;

&lt;p&gt;We are more likely to repeat a behavior when the experience is satisfying because the human brain evolved to prioritize immediate rewards over delayed rewards. The Cardinal Rule of Behavior Change says that what is immediately rewarded is repeated and what is immediately punished is avoided.&lt;/p&gt;

&lt;p&gt;One of the most satisfying feelings is the feeling of making progress, for this reason one way to feel like progress is by using some kind of &lt;em&gt;habit tracker&lt;/em&gt;. A habit tracker is a simple way to measure whether you did a habit—like marking an X on a calendar. Habit trackers and other visual forms of measurement can make your habits satisfying by providing clear evidence of your progress.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>career</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Atomic Habits</title>
      <dc:creator>Leonel Mandarino</dc:creator>
      <pubDate>Sat, 14 Jan 2023 21:34:22 +0000</pubDate>
      <link>https://forem.com/skydler/atomic-habits-20an</link>
      <guid>https://forem.com/skydler/atomic-habits-20an</guid>
      <description>&lt;p&gt;Hi folks! I'll be covering the fundamentals of habits and some ideas, important lessons and quotes from the book &lt;a href="https://www.amazon.com/gp/product/0735211299" rel="noopener noreferrer"&gt;Atomic Habits by James Clear&lt;/a&gt;, so please if you find this interesting I highly recommend reading the book.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why habits matter?
&lt;/h2&gt;

&lt;p&gt;It is so easy to overestimate the importance of one defining moment and underestimate the value of making small improvements on a daily basis. Too often, we convince ourselves that massive success requires massive action.&lt;/p&gt;

&lt;p&gt;Like everything that's good, it takes time to see the results. &lt;strong&gt;Habits are the compound interest of self-improvement&lt;/strong&gt;. The same way that money multiplies through compound interest, the effects of your habits multiply as you repeat them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fjm8q308omt7zrt09zl51.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fjm8q308omt7zrt09zl51.png" alt="Compound interest curve of making habits" width="518" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Habits are important because they free us of thinking every step of an action. They give us space to think in a higher level, habits let us ignore the tiny details that are automated on each repetition. When we start driving we are very conscious about every action we take to prevent crashing the car. As we gain experience and drive more often, we stop thinking about "putting the right shift" or "turning on the turn signal" and we start thinking about interactions with other cars and the subtle actions of people walking.&lt;/p&gt;

&lt;h2&gt;
  
  
  Systems and goals
&lt;/h2&gt;

&lt;p&gt;Goals are about the results you want to achieve. Systems are about the processes that lead to those results. Goals are good for setting a direction, but systems are best for making progress. A handful of problems arise when you spend too much time thinking about your goals and not enough time designing your systems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Winners and losers have the same goals:&lt;/strong&gt; We concentrate on the people who end up winning and mistakenly assume that ambitious goals led to their success, while overlooking all the people who had the same objective but didn’t succeed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Achieving a goal is only a momentary change:&lt;/strong&gt; Usually when chasing a goal, we treat the symptom without addressing the cause. For example, if you summon the energy to organize your room, you will have a clean room... for now. But if you keep your usual disorganized habits, it won't be long until your room is all cluttered again.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Goals restrict your happiness:&lt;/strong&gt; The implicit assumption behind any goal is this: “Once I reach my goal, then I’ll be happy.” The problem with a goals-first mentality is that you’re continually putting happiness off until the next milestone. Furthermore, goals create an “either-or” conflict: either you achieve your goal and are successful or you fail and you are a disappointment. This is totally misguided as there are many ways to success and life is unpredictable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Goals are the enemy of long-term progress:&lt;/strong&gt; A goal-oriented mind may limit your motivation. Many runners work hard for months, but as soon as they cross the finish line, they stop training. The race is no longer there to motivate them. When all of your hard work is focused on a particular goal, what is left to push you forward after you achieve it? This is why many people find themselves reverting to their old habits after accomplishing a goal.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Habits &amp;lt; -- shape -- &amp;gt; Identity
&lt;/h2&gt;

&lt;p&gt;It's bidirectional, habits shape your identity and your identity shapes your habits. As was said earlier, we need to change the system that drives us every day to change the outcomes we get. The beliefs and assumptions about ourselves shape our system and interactions.&lt;/p&gt;

&lt;p&gt;If you don't start to think about yourself as a runner, you won't be running daily. Behavior that is incongruent with the self will not last. You may want more money, but if you identify as someone who consumes rather than creates, then you’ll continue to be pulled toward spending rather than earning. It’s hard to change your habits if you never change the underlying beliefs that led to your past behavior. You have a new goal and a new plan, but you haven’t changed &lt;em&gt;who&lt;/em&gt; you are.&lt;/p&gt;

&lt;p&gt;Ultimately, your habits matter because they help you become the type of person you wish to be. They are the channel through which you develop your deepest beliefs about yourself. Quite literally, you become your habits.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Deadlocks in OS explained</title>
      <dc:creator>Leonel Mandarino</dc:creator>
      <pubDate>Thu, 16 Jul 2020 19:12:26 +0000</pubDate>
      <link>https://forem.com/skydler/deadlocks-in-os-explained-18id</link>
      <guid>https://forem.com/skydler/deadlocks-in-os-explained-18id</guid>
      <description>&lt;p&gt;An operating system is a complex and big software. It always amazed me all the stuff that's going on inside of it. &lt;br&gt;
So today I'm going to talk a bit about the management of system resources on processes (e.g. CPU, memory, I/O), specifically about deadlock.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is deadlock?
&lt;/h1&gt;

&lt;p&gt;Deadlock is a state that occurs when two or more processes block themselves simultaneously during the access of a resource.&lt;br&gt;
Let's put it in an example:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mfcoRjfY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uhntkx87kiw7rgyabscq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mfcoRjfY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uhntkx87kiw7rgyabscq.png" alt="Deadlock example" width="632" height="301"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Process 1&lt;/strong&gt; is using R1 and it's waiting for R2 to keep running. On the other side &lt;strong&gt;Process 2&lt;/strong&gt; is using R2 and it's waiting for R1.&lt;/p&gt;

&lt;p&gt;This can lead to a deadlock propagation, because more and more processes keep requesting resources which are blocked by processes in deadlock state and so on. Eventually this could end in the system crashing or rebooting.&lt;/p&gt;

&lt;h1&gt;
  
  
  Coffman conditions
&lt;/h1&gt;

&lt;p&gt;There are four conditions that must hold true at the same time for a deadlock to happen. These conditions were first described by &lt;a href="https://en.wikipedia.org/wiki/Edward_G._Coffman,_Jr."&gt;Edward G. Coffman&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mutual exclusion: In an instant of time, only one process can use an instance of the resource.&lt;/li&gt;
&lt;li&gt;Hold and wait: The processes must hold their assigned resources and wait for new ones.&lt;/li&gt;
&lt;li&gt;No preemption: Resources can only be freed  voluntarily by the process holding it.&lt;/li&gt;
&lt;li&gt;Circular wait: The process takes part in a circular list in which each process of the list is waiting for at least other resource assigned to other process in the same list&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means that we need to find a way to attack at least one of these conditions to stop deadlock from happening.&lt;/p&gt;

&lt;h1&gt;
  
  
  Deadlock treatment
&lt;/h1&gt;

&lt;p&gt;There are 3 main ways to stop deadlock and in many modern operating systems this algorithms are mixed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use a protocol that assures that deadlock will &lt;em&gt;never&lt;/em&gt; happen
&lt;/h3&gt;

&lt;p&gt;This scheme is based on two concepts:&lt;/p&gt;

&lt;h4&gt;
  
  
  Prevention
&lt;/h4&gt;

&lt;p&gt;We need to prevent at least one of Coffman conditions from happening so let's analyze each one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mutual exclusion: Here we can't do very much because some resources are non-shareable by nature.&lt;/li&gt;
&lt;li&gt;Hold and wait: To prevent this, we must ensure every process that solicits a new resource doesn't hold any other resource.
Another protocol could be to make every process request every resource that's going to use during his lifetime before his execution. This way the OS can administrate the processes and assign resources safely.
But there is a problem. This protocols are difficult to ensure given the dynamic nature of the requirements, also this could lead to &lt;a href="https://en.wikipedia.org/wiki/Starvation_(computer_science)"&gt;starvation&lt;/a&gt; and make the OS very slow in order to keep up with all this "extra processing".&lt;/li&gt;
&lt;li&gt;No preemption: One way to solve this would be to make each resource of each process appropriable on demand. Usually this approach makes the execution of processes really slow and doesn't scale very well because of the constant interruptions.&lt;/li&gt;
&lt;li&gt;Circular wait: Approaches that avoid circular waits include disabling interrupts during critical sections and using a hierarchy to determine a partial ordering of resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Avoidance
&lt;/h4&gt;

&lt;p&gt;This method searches for ways to avoid deadlock limiting the way resources are requested.&lt;br&gt;
For this to work we need to assume that the OS has all the information on what resources the processes are gonna need &lt;strong&gt;before&lt;/strong&gt; execution. Given this information, it's possible to run an algorithm that assures the system will never be in deadlock.&lt;br&gt;
This type of algorithms examine dynamically the state of allocation of resources to avoid a circular wait between processes. A lot of these algorithms differ in the amount and type of information needed to work properly. Some of them are &lt;a href="https://www.geeksforgeeks.org/bankers-algorithm-in-operating-system-2/"&gt;Banker’s Algorithm&lt;/a&gt;, &lt;a href="https://www.geeksforgeeks.org/resource-allocation-graph-rag-in-operating-system/"&gt;Resource allocation graph (RAG)&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Allow deadlock and then recover if it occurs
&lt;/h3&gt;

&lt;p&gt;In this scheme we will focus on different techniques that allow us to determine if a deadlock is currently happening and if that's the case, to recover from it.&lt;/p&gt;

&lt;p&gt;For detection we need to analyze the state of the system periodically to know soon as possible if the system is in deadlock. An algorithm that tracks the resource allocation and process states is employed.&lt;br&gt;
Once deadlock is detected it can be eliminated by process termination, resource preemption or ultimately by giving a prompt to the user asking to determine which process must be closed to stop it.&lt;/p&gt;

&lt;p&gt;The difficulty of this approach resides in knowing when to run these algorithms because they are very expensive in relation to time. Also we need to know which process is the most indicated to choose as victim for the recover algorithms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ignore the problem and hope it never happens 🙂
&lt;/h3&gt;

&lt;p&gt;This scheme considers that the probability of a deadlock happening is too low and if it were to happen it's not a big deal. Worst case scenario the system will reboot and everything will be fine as always.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;The truth is in general operating systems take the "ignore the problem" approach because the other would slow the system a lot for very little gain.&lt;br&gt;
Still, there are components that need more protection than others. For this the OS uses a combination of the previous algorithms, usually trying to break the circular wait somehow.&lt;/p&gt;

</description>
      <category>deadlocks</category>
      <category>os</category>
      <category>operatingsystem</category>
    </item>
  </channel>
</rss>
