<?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: Slobi</title>
    <description>The latest articles on DEV Community by Slobi (@slobodan4nista).</description>
    <link>https://dev.to/slobodan4nista</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%2F93862%2Fd9c3d90f-483e-4431-9d84-0c69de9de116.jpeg</url>
      <title>DEV Community: Slobi</title>
      <link>https://dev.to/slobodan4nista</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/slobodan4nista"/>
    <language>en</language>
    <item>
      <title>Animation Simulation 2D</title>
      <dc:creator>Slobi</dc:creator>
      <pubDate>Fri, 12 Sep 2025 20:37:19 +0000</pubDate>
      <link>https://dev.to/slobodan4nista/animation-simulation-2d-368a</link>
      <guid>https://dev.to/slobodan4nista/animation-simulation-2d-368a</guid>
      <description>&lt;h2&gt;
  
  
  Genesis
&lt;/h2&gt;

&lt;p&gt;I wanted to give life to this little guy:&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%2Frmv9ono166fkvylm2bhf.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%2Frmv9ono166fkvylm2bhf.png" alt="Live question, short LQ" width="191" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have years of experience making games and simulations, but I never had a chase to play with characters except for the ones that are in sprite sheets, plain dead images that go trough fast carousel and BaM! illusion of motion is there.&lt;/p&gt;

&lt;p&gt;So I set my course to make something kind of lively and kind of real. I had some previous work done that was not very promising, just look:&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%2Fm3ksff8hooq7gcghscvg.gif" 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%2Fm3ksff8hooq7gcghscvg.gif" alt="Not so live question" width="480" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was a result of me wanting to make a Ninja, the task turned to be too big. So I decided to reborn it into something that I can realistically do in time I have and not to get bored doing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Few rules had to be broken
&lt;/h2&gt;

&lt;p&gt;I have two dragons that fight, one wants to leverage all the libraries I have and return the fruits of work to base library, the other one wants to slash and dash all fresh baked code with a whip of the best current practices I adopted yesterday.&lt;/p&gt;

&lt;p&gt;I decided to go to third route, I copied only the code I relay needed for this project. The copied code gets shredded with new code that is one off for this endeavor. And the code I can't find a place for... I just paste it into main.js, yeah sue me!&lt;/p&gt;

&lt;h2&gt;
  
  
  The result
&lt;/h2&gt;

&lt;p&gt;My feel good was off the charts, I created one system for tracking two ententes with sprites that are independent. I tested adaptability of my ECS system, and was delighted. Got to play with my favorite math. Updated the collision system, shall I ever return it to the source?!&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't lock back
&lt;/h2&gt;

&lt;p&gt;I almost scraped this project in order try making my system warp one big sprite image, but I decided to leave that for some next time. And after falling on my face with energy once in doubt and fighting with scope creep I got some results:&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%2Fi85ci7tcxd012htdlpem.gif" 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%2Fi85ci7tcxd012htdlpem.gif" alt="Falling almost live question" width="300" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The results were promising but it was not live, so I used some cursed code like:&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;rez&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rez&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;distance&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="nf"&gt;get&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;chainLink1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;distance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="nf"&gt;set&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="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;chainLink1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;distance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
                &lt;span class="nx"&gt;chainLink2&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chainLink2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;distance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&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="nx"&gt;rez&lt;/span&gt;
&lt;span class="c1"&gt;// ----- SO I CAN DO&lt;/span&gt;
        &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;animation&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;newDistance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lowPinDistance0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;lowPinDistance0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;
            &lt;span class="nx"&gt;lowPinConnection0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;distance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newDistance&lt;/span&gt;
            &lt;span class="nx"&gt;lowPinConnection1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;distance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newDistance&lt;/span&gt;
            &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="mf"&gt;0.075&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; 

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

&lt;/div&gt;



&lt;p&gt;And it finally started to act like real live puctuation sign:&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%2Fth6a7703g1r9yft3br85.gif" 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%2Fth6a7703g1r9yft3br85.gif" alt="Jumping joy live question" width="300" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Some games are there for players the wast majority is for the creators of those games. Some projects are hard by nature, we don't need to make them even harder with fake walls that are not even there. If this idea lives I will come around and invest my proper energy and time, but at least I seen the result early and can get feedback early.&lt;/p&gt;

&lt;p&gt;Thank you for reading, I hope that someone will find this article helpful or at least amusing!&lt;/p&gt;

</description>
      <category>prototyping</category>
      <category>indie</category>
    </item>
    <item>
      <title>I Built MultiFile Canvas for VS Code</title>
      <dc:creator>Slobi</dc:creator>
      <pubDate>Fri, 22 Aug 2025 20:42:00 +0000</pubDate>
      <link>https://dev.to/slobodan4nista/i-built-multifile-canvas-for-vs-code-500p</link>
      <guid>https://dev.to/slobodan4nista/i-built-multifile-canvas-for-vs-code-500p</guid>
      <description>&lt;h2&gt;
  
  
  Why are we here
&lt;/h2&gt;

&lt;p&gt;Sometimes you just need to bounce between tiny utility files, configs, and snippets. The constant tab switching drives me nuts.  &lt;/p&gt;

&lt;p&gt;I looked around for a solution, but couldn’t find anything that worked the way I wanted. I’m not committed enough to go full keyboard-only IDE (Vim-like), though some of those ideas were very appealing.&lt;br&gt;&lt;br&gt;
What I really wanted was a single file or view where I could edit multiple files at once. I also wanted it integrated into a familiar environment, because my goal is to produce, not just learn a new tool.  &lt;/p&gt;

&lt;p&gt;So… I did what any developer eventually does: &lt;strong&gt;I built it myself.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Introducing MultiFile Canvas&lt;/strong&gt; – a VS Code extension that lets you merge multiple files into a single view.  &lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 How it works
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create a .mf file (like project.mf)
&lt;/li&gt;
&lt;li&gt;Add dividers like:
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;---- main.js ----&lt;br&gt;&lt;br&gt;
  ---- lib/utils.js ----&lt;br&gt;&lt;br&gt;
  ---- index.js ----  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Files load directly under the merged view
&lt;/li&gt;
&lt;li&gt;Edit inside your .mf, and saving writes back to the originals
&lt;/li&gt;
&lt;li&gt;If originals change, your view updates
&lt;/li&gt;
&lt;li&gt;Rename references to copy or load different files
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Basically: &lt;strong&gt;no more endless tab flipping&lt;/strong&gt; when juggling small files.  &lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Why I made this
&lt;/h2&gt;

&lt;p&gt;I originally built MultiFile Canvas just for my own workflow, but I figured someone else might also find it useful.&lt;br&gt;&lt;br&gt;
It’s lightweight, simple, and does exactly what I needed.  &lt;/p&gt;

&lt;p&gt;You can check it out here:&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://marketplace.visualstudio.com/items?itemName=slobacartoonac.multifilecanvas" rel="noopener noreferrer"&gt;Marketplace link&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;If you give it a try, let me know what you think! Feedback is very welcome.&lt;br&gt;&lt;br&gt;
Please note this is my first extension, and I built it in just two days.&lt;/p&gt;

</description>
      <category>productivity</category>
    </item>
    <item>
      <title>Journal Transcriber: Write journal by dictating it</title>
      <dc:creator>Slobi</dc:creator>
      <pubDate>Mon, 25 Nov 2024 16:15:04 +0000</pubDate>
      <link>https://dev.to/slobodan4nista/journal-transcriber-write-journal-by-dictating-it-5f8e</link>
      <guid>https://dev.to/slobodan4nista/journal-transcriber-write-journal-by-dictating-it-5f8e</guid>
      <description>&lt;h2&gt;
  
  
  Hello
&lt;/h2&gt;

&lt;p&gt;Dear readers, today I am going to talk about a journal script I kind of wrote. 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem of Saving My Thoughts
&lt;/h2&gt;

&lt;p&gt;The problem I’m trying to solve is that I want to save my thoughts.&lt;/p&gt;

&lt;p&gt;I have no problem reading what I wrote, but I don’t enjoy waiting. I can dictate, but I don’t want to save or listen to my voice.&lt;/p&gt;

&lt;p&gt;Whenever I encounter such a situation, I get into engineering mode, and if it’s something I can tackle within a few hours of work, I go for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial Research
&lt;/h2&gt;

&lt;p&gt;First, I researched a voice-to-text library that’s easy to use, and I found Vosk. It has a huge library of models. I opted for two small ones because I want to use the app while I code. They give somewhat decent results.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Python Solution
&lt;/h2&gt;

&lt;p&gt;Then, with the magic of multiple AI models, I came to a solution in Python. It streams my microphone and system sound to the Vosk model, which provides a transcription written with timestamps in a file with the current date.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Prototype to Daily Usability
&lt;/h2&gt;

&lt;p&gt;It serves the purpose, but it’s not convenient for daily use. One of my mottoes is: if it’s not easy and instant, I won’t use it. So, I packed the script into a Python module and wrote a *.desktop file to register it as a regular Linux application in my case, Pop!_OS.&lt;br&gt;
Just a quick extra touch was adding a keyboard shortcut and behold the miracle it works!&lt;br&gt;
Notifications using notify-send are there to let you know the app's current state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Eliminating Console Clutter
&lt;/h2&gt;

&lt;p&gt;One thing that irritates me is when an application runs in the console because it clutters my workspace. To avoid this, I needed a simple way to start and stop the app without relying on the terminal. My solution was to implement a lock file system.&lt;/p&gt;

&lt;p&gt;When the app starts, it creates a lock file containing its process ID (PID). If the lock already exists, the script uses it to send a KeyboardInterrupt signal to stop the running instance and exits. This way, the first call starts the app and begins transcribing, while the second call stops it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving Problems the Inventive Way
&lt;/h2&gt;

&lt;p&gt;I hope this article sparked someone’s wish to solve their own problem in a unique, inventive, and somewhat polished way.&lt;/p&gt;

&lt;p&gt;Feel free to check my other similar article:&lt;br&gt;
&lt;a href="https://dev.to/slobodan4nista/automating-text-extraction-from-screenshots-with-tesseract-and-gnome-screenshot-maj"&gt;Automating Text Extraction from Screenshots&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also feel free to check out code:&lt;br&gt;
&lt;a href="https://github.com/slobacartoonac/pythonium/tree/master/journal_transcriber" rel="noopener noreferrer"&gt;on Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have a great day 🚀&lt;/p&gt;

</description>
      <category>voicetotext</category>
      <category>python</category>
      <category>productivity</category>
      <category>linux</category>
    </item>
    <item>
      <title>Journal Transcriber: Write journal by dictating it</title>
      <dc:creator>Slobi</dc:creator>
      <pubDate>Wed, 20 Nov 2024 10:58:49 +0000</pubDate>
      <link>https://dev.to/slobodan4nista/journal-transcriber-write-journal-by-dictating-it-293a</link>
      <guid>https://dev.to/slobodan4nista/journal-transcriber-write-journal-by-dictating-it-293a</guid>
      <description>&lt;h2&gt;
  
  
  Hello
&lt;/h2&gt;

&lt;p&gt;Dear readers, today I am going to talk about a journal script I kind of wrote. 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem of Saving My Thoughts
&lt;/h2&gt;

&lt;p&gt;The problem I’m trying to solve is that I want to save my thoughts.&lt;/p&gt;

&lt;p&gt;I have no problem reading what I wrote, but I don’t enjoy waiting. I can dictate, but I don’t want to save or listen to my voice.&lt;/p&gt;

&lt;p&gt;Whenever I encounter such a situation, I get into engineering mode, and if it’s something I can tackle within a few hours of work, I go for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial Research
&lt;/h2&gt;

&lt;p&gt;First, I researched a voice-to-text library that’s easy to use, and I found Vosk. It has a huge library of models. I opted for two small ones because I want to use the app while I code. They give somewhat decent results.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Python Solution
&lt;/h2&gt;

&lt;p&gt;Then, with the magic of multiple AI models, I came to a solution in Python. It streams my microphone and system sound to the Vosk model, which provides a transcription written with timestamps in a file with the current date.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Prototype to Daily Usability
&lt;/h2&gt;

&lt;p&gt;It serves the purpose, but it’s not convenient for daily use. One of my mottoes is: if it’s not easy and instant, I won’t use it. So, I packed the script into a Python module and wrote a *.desktop file to register it as a regular Linux application in my case, Pop!_OS.&lt;br&gt;
Just a quick extra touch was adding a keyboard shortcut and behold the miracle it works!&lt;br&gt;
Notifications using notify-send are there to let you know the app's current state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Eliminating Console Clutter
&lt;/h2&gt;

&lt;p&gt;One thing that irritates me is when an application runs in the console because it clutters my workspace. To avoid this, I needed a simple way to start and stop the app without relying on the terminal. My solution was to implement a lock file system.&lt;/p&gt;

&lt;p&gt;When the app starts, it creates a lock file containing its process ID (PID). If the lock already exists, the script uses it to send a KeyboardInterrupt signal to stop the running instance and exits. This way, the first call starts the app and begins transcribing, while the second call stops it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving Problems the Inventive Way
&lt;/h2&gt;

&lt;p&gt;I hope this article sparked someone’s wish to solve their own problem in a unique, inventive, and somewhat polished way.&lt;/p&gt;

&lt;p&gt;Feel free to check my other similar article:&lt;br&gt;
&lt;a href="https://dev.to/slobodan4nista/automating-text-extraction-from-screenshots-with-tesseract-and-gnome-screenshot-maj"&gt;Automating Text Extraction from Screenshots&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also feel free to check out code:&lt;br&gt;
&lt;a href="https://github.com/slobacartoonac/pythonium/tree/master/journal_transcriber" rel="noopener noreferrer"&gt;on Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have a great day 🚀&lt;/p&gt;

</description>
      <category>voicetotext</category>
      <category>python</category>
      <category>productivity</category>
      <category>linux</category>
    </item>
    <item>
      <title>Flipping Data Structures to optimize performance 🚀</title>
      <dc:creator>Slobi</dc:creator>
      <pubDate>Mon, 02 Sep 2024 14:08:06 +0000</pubDate>
      <link>https://dev.to/slobodan4nista/flipping-data-structures-to-optimize-performance-115m</link>
      <guid>https://dev.to/slobodan4nista/flipping-data-structures-to-optimize-performance-115m</guid>
      <description>&lt;h2&gt;
  
  
  What do I mean
&lt;/h2&gt;

&lt;p&gt;When we want a high performance system, we can greatly benefit by thinking in terms of efficient data organization. When we have multilayered maps or hash tables, sometimes a simple reorientation of data is all that we need.&lt;/p&gt;

&lt;p&gt;In my ECS system, I have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;_entities&lt;/code&gt; that map &lt;code&gt;id -&amp;gt; Entity(id)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_components&lt;/code&gt; that map &lt;code&gt;Entity.id -&amp;gt; Component.Type -&amp;gt; Set(Component())&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So when we query for all Entities that have a Component of a specific type, we list all entities and then filter out those that do not have a Component.Type entry or where the set size is 0.&lt;/p&gt;

&lt;p&gt;This works well enough to a certain point, but we can observe that this algorithm performs similarly when searching for both common and rare components, even though searching for a rare component should, intuitively be faster.&lt;/p&gt;

&lt;p&gt;One optimization we can implement is to flip the &lt;code&gt;_component&lt;/code&gt; map &lt;code&gt;Entity.id&lt;/code&gt; and &lt;code&gt;Component.Type&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;_components&lt;/code&gt; that map &lt;code&gt;Component.Type -&amp;gt; Entity.id -&amp;gt; Set(Component())&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The benefit is that when a component is rare, we only have to traverse a short list to check if the set is empty and filter those entities accordingly. This could be further improved by deleting the entity entry for a type when the set is empty. This way, our query can simply return a set.&lt;/p&gt;

&lt;p&gt;Here are the results of this optimization for &lt;code&gt;100_000&lt;/code&gt; eateries and &lt;code&gt;600&lt;/code&gt; rare Component instances:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;queryCommon: 51.256ms -&amp;gt; 16.161ms

queryRare: 58.081ms -&amp;gt; 0.346ms

getComponentsCommon: 37.668ms -&amp;gt; 34.671ms

getComponentsRare: 21.635ms -&amp;gt; 9.959ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By reorganizing how components are mapped within the ECS, we can significantly improve the performance of queries, especially for rare components. This simple yet effective change allows the system to handle query more efficiently.&lt;/p&gt;

&lt;p&gt;Hope this helps developers not to forget to handle their data appropriately even when using something like JavaScript.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>optimization</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>Intuition VS. Guesstimate - Why are projects more late than not.</title>
      <dc:creator>Slobi</dc:creator>
      <pubDate>Mon, 29 Jul 2024 14:08:42 +0000</pubDate>
      <link>https://dev.to/slobodan4nista/intuition-vs-guesstimate-why-are-projects-more-late-than-not-2ekh</link>
      <guid>https://dev.to/slobodan4nista/intuition-vs-guesstimate-why-are-projects-more-late-than-not-2ekh</guid>
      <description>&lt;p&gt;I have been in the IT industry long enough to feel that projects rarely go according to schedule.&lt;/p&gt;

&lt;p&gt;At first, I was in teams of young people with little to no experience. We did our jobs as best we could, but we missed our deadlines from time to time. We did all the engineering beforehand to give the best possible estimates with some buffer, but again we were wrong almost as much as we were when we were just eyeballing it.&lt;/p&gt;

&lt;p&gt;Then I moved on to some more advanced projects, organizations, and teams. I also gained more experience, but still, the pattern continued. I was unhappy about it, I thought that I was a terrible engineer, and managers were unhappy from time to time.&lt;/p&gt;

&lt;p&gt;My first line of defense was the thought that the software base we built on top of was bad, so we were struggling to fix the mess beneath our app layer, and that was the reason we frequently missed our deadlines.&lt;/p&gt;

&lt;p&gt;My second phase was the belief that people are not suited to do programming, but by some miracle, we managed to do it anyway. So, I felt pretty good when we made something work.&lt;/p&gt;

&lt;p&gt;Years passed, and I changed teams and talked to many people, but the pattern emerged everywhere. So, I started to suspect that it is not that simple. We can't just make up a story and call it a day, feeling good about our failure to meet deadlines. I owed it to myself to think of something better, so I did.&lt;/p&gt;

&lt;p&gt;In words, it goes something like this: When doing one task, it is pretty probable for it to be done somewhere around the standard deviation of the estimate, and that task goes pretty well. I view it as a probability density function to finish a task in any given moment, I am not a mathematician, so excuse my crudeness. But when a task goes wrong, when we get out of that nice and safe zone, we have a low chance to finish it at any of the next moments. Imagine a Gaussian distribution, but it has a tail that is very thin. There is a low chance of getting into that tail because there is much more surface before that, so our minds ignore it, and managers do too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ferbs8550aokp7vt7orxz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ferbs8550aokp7vt7orxz.png" alt="Gaussian distribution with tail" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My defense against that case was to give overestimates, and most people also do it, so our guess is always on the right side of the median, but regularly we finished our tasks on time, meaning early by our estimate. The reaction of management was that we were pressured to keep it real. But then, from time to time, there was a task or maybe a few that made everyone unhappy. We felt hopeless, missed deadlines even four times the estimate, and sometimes had to reorganize and redo the whole thing again.&lt;/p&gt;

&lt;p&gt;Still, when we look at one task at a time, it is not all that grim. There is a slight chance that we make a mistake, but with more work, it will get fixed. We are humans, and we can do one thing at a time, so let's assume that ideally we finish one thing and then move on to another. It turns out that we get into that unpleasant situation more frequently than we intuitively felt we should. It makes us doubt our path in software engineering. I can't feel bummed forever about such feelings, so I started making an excuse that when we combine multiple Gaussian distributions with that tiny tail, it grows. But I did not have time to sit down and do the homework, so I made my best predictions and moved on with my life.&lt;/p&gt;

&lt;p&gt;Recently, I was in a release situation that is still ongoing, and the feeling came back. So, I decided to do the work to get that thing calculated with my limited and rusted math knowledge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;The standard software procedure is if you can't define a thing well, you make a discrete approximation and grind numbers through a few for loops until you get integration, function product, or something you can't define but seems logical. In my mind, it's the same as simulation.&lt;/p&gt;

&lt;p&gt;So, the distribution approximation I came up with is:&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;function&lt;/span&gt; &lt;span class="nf"&gt;trail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&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;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tanh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tanh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mf"&gt;4.3&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;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;trailProb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tanh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mf"&gt;4.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;trailProb&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is not pretty, but it gives the top figure. The idea of using the hyperbolic tangent function came from an AI course for perception, where it is used as a quick fix for the Sigmoid function.&lt;/p&gt;

&lt;p&gt;Then I made it discrete like this:&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;let&lt;/span&gt; &lt;span class="nx"&gt;oneTask&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="mi"&gt;200&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="nx"&gt;oneTask&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="nf"&gt;trail&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="mi"&gt;10&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;I had a relative probability of finishing a task every 10% of a time estimate. It looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwoxqd4vaetire1mbrxk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwoxqd4vaetire1mbrxk.png" alt="Finishing task in a moment" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I had to come up with a way to combine tasks. Good thing it was discreet so I could reason about it and calculate it:&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="nf"&gt;combineTwoTasks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;task2&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;twoTasks&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="mi"&gt;100&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="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;j&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;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&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;y1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;task1&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;task2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&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;finalx&lt;/span&gt; &lt;span class="o"&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;j&lt;/span&gt;
            &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;finaly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;y1&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;y2&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;DEVIDEER&lt;/span&gt;
            &lt;span class="nx"&gt;twoTasks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;finalx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;twoTasks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;finalx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;twoTasks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;finalx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;finaly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;finaly&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;twoTasks&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, the x position is the added time of finishing the first task and the added time of finishing the second task, and the probability is the product of those two probabilities. Basically, it boils down to getting the sum of 7 when tossing two consecutive dice. In the end, you get all the ways you can finish at some moment. So, two tasks combined give another probability curve, going once again, you get 3 tasks, and so on.&lt;/p&gt;

&lt;p&gt;So the whole code looks like this:&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;let&lt;/span&gt; &lt;span class="nx"&gt;oneTask&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="mi"&gt;200&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="nx"&gt;oneTask&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="nf"&gt;trail&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="mi"&gt;10&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;twoTasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;combineTwoTasks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oneTask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;oneTask&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;threeTasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;combineTwoTasks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oneTask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;twoTasks&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;nTasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;oneTask&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="mi"&gt;7&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="nx"&gt;nTasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;combineTwoTasks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oneTask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nTasks&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="mi"&gt;200&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addPoint&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="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;oneTask&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addPoint&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="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;twoTasks&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#00ff00&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addPoint&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="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;threeTasks&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#0000ff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addPoint&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="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;nTasks&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#00ffff&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;For the first few tasks, the time and probability of finishing look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2yrrr0x9y7297nq7dw5a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2yrrr0x9y7297nq7dw5a.png" alt="tasks without a tail" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And it looks fine. We should be ashamed to do all this work and get a result that throws a wet towel in our faces and says we are all bad developers. But this is when all the variables are known when there is no unknown thing that can make that tedious tail. When we raise the chance to get into that awkward situation just a little bit, the results are a bit different:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmn5l5p8rkv0ulfmgiva.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmn5l5p8rkv0ulfmgiva.png" alt="tasks with a tail" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We see that a small tail of a task that is barely perceivable can impact us on the fourth task destructively. Something like barely 1-2% of the area under the curve becomes 20%-30%, and that is only for 4 tasks with an almost sure outcome. We have almost no chance to finish on time (&amp;lt;10%) and a good chance to overdo it by 1.5x of the original guesstimate. 2x is not far-fetched either.&lt;/p&gt;

&lt;p&gt;I wanted to play a little bit and see 7 sequential tasks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29d467kyxdtrhqklv36u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29d467kyxdtrhqklv36u.png" alt="seven sequential tasks" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The story continues, we should be done by 7, we are probably doing it by 9.5 estimates, and we have the same chance to finish after 13 estimates as we do to finish on time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Every task is different
&lt;/h3&gt;

&lt;p&gt;There are a lot of tasks that have much bigger tail sections due to various reasons. Only the tasks where all the variables are known and are in the pure Gaussian distribution form can be estimated and delivered repeatedly and reliably.&lt;/p&gt;

&lt;p&gt;I hope this helps fellow developers not to feel bad when things go wrong. It is the nature of the universe and helps organizations and managers adapt to the truth.&lt;/p&gt;

&lt;p&gt;You can check my few hours of coding mess here:&lt;br&gt;
&lt;a href="https://github.com/slobacartoonac/pythonium/tree/master/late" rel="noopener noreferrer"&gt;Github source&lt;/a&gt;&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>projectmanagement</category>
      <category>timeestimation</category>
      <category>programmingtips</category>
    </item>
    <item>
      <title>The Compounded Interest of Good Software: An example of Carousel Components</title>
      <dc:creator>Slobi</dc:creator>
      <pubDate>Mon, 15 Apr 2024 10:28:14 +0000</pubDate>
      <link>https://dev.to/slobodan4nista/the-compounded-interest-of-good-software-an-example-of-carousel-components-1cm6</link>
      <guid>https://dev.to/slobodan4nista/the-compounded-interest-of-good-software-an-example-of-carousel-components-1cm6</guid>
      <description>&lt;p&gt;While working on software there's a constant war between compounded interest and technical debt. Both have their places in the life-cycle of a project, but understanding when to leverage one over the other can make all the difference in the long run.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Need for a Carousel Component
&lt;/h2&gt;

&lt;p&gt;I am working on a website, and I need a carousel component that seamlessly transitions between images, accommodating both mouse and touch inputs. A seemingly simple task, but one that can quickly spiral into a mess if not handled properly.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Trap of Technical Debt
&lt;/h3&gt;

&lt;p&gt;In the past, I've fallen victim to the allure of technical debt. I'd hastily cobble together a carousel component, sacrificing long-term stability for short-term gains. Sure, it worked, but it was like building a house of cards, fragile and prone to 💩 at any moment. Ten years ago I worked on such component and I must confess that I got weeks of salary just on that functionality that barely worked.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Power of Compounded Interest
&lt;/h3&gt;

&lt;p&gt;Instead of falling to the temptation of using some over-bloated library like Bootsrap, or writing something from scratch, I decided to invest in compounded interest. I had previously written and maintained a library for touch and mouse abstraction, a foundational piece of code that I could leverage for future projects.&lt;/p&gt;

&lt;p&gt;The library in question is one that I already talked about the Touch, and the interface is straight forward:&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;// Init Touch with HTMLDivElement&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;touch&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Touch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;carouselOuter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// bind logic to event&lt;/span&gt;
&lt;span class="nx"&gt;touch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onForce&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt;&lt;span class="na"&gt;delta&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&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="nf"&gt;carouselByX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;carouselOuter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;carouselByY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;carouselOuter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&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;h2&gt;
  
  
  Building the Perfect Carousel
&lt;/h2&gt;

&lt;p&gt;Armed with my existing library, I set out to build the ultimate carousel component. It was a breeze with the hardest part of the work already done and tested, I was able to focus on refining the user experience and ensuring seamless functionality across all devices.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi96bfc9spo53ljtb6zo8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi96bfc9spo53ljtb6zo8.png" alt="Image of carousel" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Payoff
&lt;/h3&gt;

&lt;p&gt;In just a few hours, I had a carousel component that not only met my requirements but exceeded them. It seamlessly transitioned between images, gracefully handled both mouse and touch inputs, and added a touch of polish to my website that wasn't there before.&lt;/p&gt;

&lt;p&gt;The usage is and it just work:&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;// Init carousel by calling function&lt;/span&gt;
&lt;span class="c1"&gt;// pass the querySelector string&lt;/span&gt;
&lt;span class="c1"&gt;// I used &amp;lt;y class='carousel'&amp;gt;&lt;/span&gt;
&lt;span class="nf"&gt;initCarousel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.carousel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"carousel overflow-hidden some-style"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"carousel-inner more-style"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"item-style"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
       Example element
    &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;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;When it comes to software development, always strive to invest in compounded interest rather than accruing technical debt. Sure, it may require more upfront effort, but the dividends it pays in the long run are well worth it.&lt;/p&gt;

&lt;p&gt;Feel free to checkout GitHub: &lt;a href="https://github.com/slobacartoonac/js_lib/blob/main/fe/carousel/index.js"&gt;https://github.com/slobacartoonac/js_lib/blob/main/fe/carousel/index.js&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>development</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Automating Text Extraction from Screenshots with Tesseract and Gnome Screenshot</title>
      <dc:creator>Slobi</dc:creator>
      <pubDate>Mon, 12 Feb 2024 13:44:26 +0000</pubDate>
      <link>https://dev.to/slobodan4nista/automating-text-extraction-from-screenshots-with-tesseract-and-gnome-screenshot-maj</link>
      <guid>https://dev.to/slobodan4nista/automating-text-extraction-from-screenshots-with-tesseract-and-gnome-screenshot-maj</guid>
      <description>&lt;p&gt;Manually transcribing it can be tedious and time-consuming. However if you are on right system (Pop OS in this case), with the power of automation and the right tools, you can streamline this process and save yourself valuable time.&lt;/p&gt;

&lt;p&gt;In this article, I'll share with you how I created a simple yet effective script using Tesseract OCR (Optical Character Recognition) and Gnome Screenshot to extract text from any region of the screen and copy it to the clipboard. Let's dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting the Stage
&lt;/h2&gt;

&lt;p&gt;Before we get started, it's important to note that you'll need to have both Gnome Screenshot and Tesseract installed on your system. These tools are readily available on most Linux distributions and can be easily installed using your package manager of choice. Once you have them installed, you're ready to proceed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Script
&lt;/h2&gt;

&lt;p&gt;The script I've crafted combines the functionalities of Gnome Screenshot and Tesseract to capture a selected area of the screen, extract the text from it, and copy it to the clipboard. Here's a breakdown of what each part of the script does:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="c"&gt;# Create a temporary directory&lt;/span&gt;&lt;br&gt;
&lt;span class="nv"&gt;TMPDIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;mktemp&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="c"&gt;# Take a screenshot of a selected area and save it as screenshot.png in the temporary directory&lt;/span&gt;&lt;br&gt;
gnome-screenshot &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;$TMPDIR&lt;/span&gt;/screenshot.png&lt;/p&gt;

&lt;p&gt;&lt;span class="c"&gt;# Process the screenshot with Tesseract and save the result to a text file in the temporary directory&lt;/span&gt;&lt;br&gt;
tesseract &lt;span class="nv"&gt;$TMPDIR&lt;/span&gt;/screenshot.png &lt;span class="nv"&gt;$TMPDIR&lt;/span&gt;/output&lt;/p&gt;

&lt;p&gt;&lt;span class="c"&gt;# Copy the result to the clipboard&lt;/span&gt;&lt;br&gt;
&lt;span class="c"&gt;# ignore all non-ASCII characters&lt;/span&gt;&lt;br&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="nv"&gt;$TMPDIR&lt;/span&gt;/output.txt |&lt;br&gt;
    &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-cd&lt;/span&gt; &lt;span class="s1"&gt;'\11\12\15\40-\176'&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; | perl &lt;span class="nt"&gt;-pe&lt;/span&gt; &lt;span class="s1"&gt;'chomp if eof'&lt;/span&gt; |&lt;br&gt;
    xclip &lt;span class="nt"&gt;-selection&lt;/span&gt; clipboard&lt;/p&gt;

&lt;p&gt;&lt;span class="c"&gt;# Optionally, remove the temporary directory when done&lt;/span&gt;&lt;br&gt;
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nv"&gt;$TMPDIR&lt;/span&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  How It Works&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;The script starts by creating a temporary directory to store the screenshot and its processed output. It then uses Gnome Screenshot to capture a selected area of the screen and save it as "screenshot.png" in the temporary directory.&lt;/p&gt;

&lt;p&gt;Next, the script utilizes Tesseract to process the screenshot and extract any text present in it. The extracted text is saved to a file named "output.txt" in the same temporary directory.&lt;/p&gt;

&lt;p&gt;The script then cleans up the extracted text, removing any non-ASCII characters, and copies it to the clipboard using the xclip command.&lt;/p&gt;

&lt;p&gt;Finally, the temporary directory is removed to tidy up after the process is complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enhancements and Customizations
&lt;/h2&gt;

&lt;p&gt;Personally I made this script runable by using &lt;code&gt;chmod +x screenshot_to_clipboard.sh&lt;/code&gt;. Then I added ti to &lt;code&gt;/usr/local/bin/screenshot_to_clipboard.sh&lt;/code&gt; so it is available to all users terminals. Also I did added keyboard shortcut to Ctrl+Q using GUI settings on PosOS but it should be straight forward for all gnome based systems.&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%2Fkqog2o775xiojsbe6d1m.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%2Fkqog2o775xiojsbe6d1m.png" alt="Image of adding shortcut on Pop-OS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;The process of using it is fairly straight forward, you click shortcut, the area selector is automatically initiated, when you select the area all readable text is copied to clipboard, the script is over and you can continue using your computer normally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With the Tesseract OCR and Gnome Screenshot combo, extracting text from images or screenshots is a breeze! This script isn't just simple it's customizable too. Set it up once, hit a shortcut, and boom! Text is in your clipboard, ready to go. It's like magic for your productivity! 🚀&lt;/p&gt;

</description>
      <category>linux</category>
      <category>automation</category>
      <category>gnome</category>
      <category>ocr</category>
    </item>
    <item>
      <title>Independent on my journey</title>
      <dc:creator>Slobi</dc:creator>
      <pubDate>Thu, 11 Jan 2024 16:12:35 +0000</pubDate>
      <link>https://dev.to/slobodan4nista/independent-on-my-journey-e0d</link>
      <guid>https://dev.to/slobodan4nista/independent-on-my-journey-e0d</guid>
      <description>&lt;p&gt;I want to emphasize my love for this the blogging space, where I can express my thoughts and projects that I am working on. However, I found myself at the mercy of moderators who can be triggered by any comment. One bad experience stands out when I commented on a particularly controversial article. The article drew an inappropriate comparison, likening company preferences for TypeScript to how certain groups of people strongly favor a particular religion.&lt;/p&gt;

&lt;p&gt;I attempted to steer the conversation towards a more technical discussion, disregarding the sensitive religious aspect. To my surprise, a few hours later, I received two notifications. One was a reply to my comment, and the writer was rude. The other notification informed me that one of my blog posts violated the terms of service due to the use of a particular tag.&lt;/p&gt;

&lt;p&gt;It dawned on me that I could lose all my content on this platform simply by upsetting the wrong person. In response, I took the precaution of downloading all my posts in Markdown format, along with all associated images. Subsequently, I added all the blogs to my personal website and established a secure and controlled environment for hosting my blogs, ensuring their safety and integrity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech Stack I Use:
&lt;/h2&gt;

&lt;p&gt;For the technical infrastructure of my self-hosted blog, I opted for a robust set of tools:&lt;/p&gt;

&lt;h3&gt;
  
  
  Webpack with EJS:
&lt;/h3&gt;

&lt;p&gt;I leverage Webpack in conjunction with EJS for efficient bundling and rendering of my blog pages. EJS provides a flexible templating engine, allowing me to structure my content seamlessly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Markdown to EJS Conversion:
&lt;/h3&gt;

&lt;p&gt;I've developed a script that converts Markdown files to EJS, ensuring compatibility with my chosen templating engine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Metadata Extraction:
&lt;/h3&gt;

&lt;p&gt;Using regular expressions, I extract key-value pairs from the headers of my Markdown files. This process enables me to gather essential metadata such as titles, covers, and other relevant information.&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;// Regular expression to match key-value pairs&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\b([&lt;/span&gt;&lt;span class="sr"&gt;a-zA-Z0-9_&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;([\s\S]&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;?)(?=\n&lt;/span&gt;&lt;span class="sr"&gt;|$&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Markdown Rendering:
&lt;/h3&gt;

&lt;p&gt;I utilize the markdown-it library to render Markdown content, enhancing the readability of my blog posts. Additionally, I employ highlight.js for syntax highlighting, with the Atom One Dark theme for a visually appealing code presentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customization with mila:
&lt;/h3&gt;

&lt;p&gt;The markdown-it-link-attributes (mila) extension allows me to customize link attributes, providing an extra layer of control over the appearance and behavior of hyperlinks in my blog posts.&lt;br&gt;
Here's a snippet of included libraries:&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;MarkdownIt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;markdown-it&lt;/span&gt;&lt;span class="dl"&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;hljs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;highlight.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;mila&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;markdown-it-link-attributes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;// Linking to the highlight.js Atom One Dark theme
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"../../node_modules/highlight.js/styles/atom-one-dark.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've found this setup to be exceptionally effective in creating and maintaining my blog, providing a seamless and personalized experience for both me and my readers.&lt;/p&gt;

&lt;p&gt;It took me about 2 afternoons:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8yrlgjnfd4kry52by7oi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8yrlgjnfd4kry52by7oi.png" alt="Image of self hosted blog" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And I think that result is decent given that I am full stack developer that works on business and service software.&lt;/p&gt;

&lt;p&gt;Please let me know what you think and feel free to read my other articles while they are here ;)&lt;/p&gt;

&lt;p&gt;Or there is a backup &lt;a href="https://itmrav.com/blogs.html" rel="noopener noreferrer"&gt;Backup Link (other half)&lt;/a&gt; but mainly here&lt;/p&gt;

</description>
      <category>selfhostingjourney</category>
      <category>creativefreedom</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Coding Plane of Programming Languages and Programmers by AI</title>
      <dc:creator>Slobi</dc:creator>
      <pubDate>Sat, 16 Dec 2023 15:44:45 +0000</pubDate>
      <link>https://dev.to/slobodan4nista/navigating-the-2d-coding-cosmos-of-ai-generated-programming-languages-and-programmers-4ei0</link>
      <guid>https://dev.to/slobodan4nista/navigating-the-2d-coding-cosmos-of-ai-generated-programming-languages-and-programmers-4ei0</guid>
      <description>&lt;p&gt;In the vast plain of programming languages, selecting the right one can be similar to navigating an unknown cosmic terrain. This journey becomes even more unknown when tailored to different programmer types. Let's jump on a three minute exploration into the unique universe of 2D projection, where the closeness between programmers and languages reveals the effort required to reach coding nirvana, all within the context of AI-generated properties.&lt;/p&gt;

&lt;p&gt;The Force Field of Programming:&lt;/p&gt;

&lt;p&gt;Imagine a force field governed by an enigmatic formula — (x-1)*(x^-1). In this coding cosmos, if a language and a programmer find themselves too close (&amp;lt;1), an invisible force urges them to diverge, to maintain a healthy distance. Conversely, if separated by vast expanses, a subtle force beckons them to draw near, inviting collaboration. This force field encapsulates the essence of our exploration.&lt;/p&gt;

&lt;p&gt;Mapping the Cosmic Landscape:&lt;/p&gt;

&lt;p&gt;Our journey commences with the unique touch of AI-generated properties. The parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;learning curve,&lt;/li&gt;
&lt;li&gt;syntax complexity, &lt;/li&gt;
&lt;li&gt;and &lt;code&gt;'similarity_to_other_languages', 'syntax_complexity', 'community_support', 'ecosystem', 'performance', 'distance_from_machine_code', 'parameter_strictness', 'prevention_of_runtime_bugs'&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;become constellations in this cosmic map. These properties, meticulously crafted by artificial intelligence, shape the 2D landscape. The distances between points signify the effort, the cosmic energy, required for a programmer to traverse from one language to another or vice versa.&lt;/p&gt;

&lt;p&gt;Unveiling Relationships in 2D:&lt;/p&gt;

&lt;p&gt;As the cosmic map takes shape, intricate relationships between AI-generated languages and programmers unfold. Each entity competes for its celestial spot, guided by the properties that define it. The graphical representation not only showcases the unique bond between a programmer and a language but also paints a broader picture of the cosmic dynamics within the programming landscape.&lt;/p&gt;

&lt;p&gt;Symphony of diverse coding elements, all driven by the artistic touch of artificial intelligence. Testing our cosmic model reveals patterns resembling a cosmic symphony, each note representing the nuanced relationships between languages and programmers.&lt;/p&gt;

&lt;p&gt;Here is the space frontier:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmrf3amyqu4wo7x3ndjc2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmrf3amyqu4wo7x3ndjc2.png" alt="space frontier of programming languages" width="800" height="971"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The detailed for beginners so you don't wonder into dark and far places in space:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuzvg9kc5hfwr7sleb2rb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuzvg9kc5hfwr7sleb2rb.png" alt="beginner space frontier of programming languages" width="800" height="643"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to see for yourself:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://slobacartoonac.github.io/pythonium/languages-cluster/public/index.html"&gt;Live demo example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please note that we have 9D world projected into 2D so the representation is not always accurate but it is surely informative.&lt;/p&gt;

&lt;p&gt;Conclusion: Navigating the Cosmic Coding Odyssey:&lt;/p&gt;

&lt;p&gt;In conclusion, our 2D odyssey through the cosmic coding landscape, with its AI-generated properties, provides a unique lens for understanding the relationships between programming languages and programmers. Beyond traditional metrics, this cosmic approach offers a holistic view, guiding developers toward informed and efficient coding choices. As we continue to chart the cosmic coding realms, the force field of (x-1)*(x^-1) remains our guiding light in this AI-infused cosmic odyssey. May your coding journey be filled with celestial discoveries and effortless traversals across the cosmic expanse.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>languages</category>
      <category>career</category>
    </item>
    <item>
      <title>Tag Recommendation to Game Design: A True Story of Word-Difference-Calculator</title>
      <dc:creator>Slobi</dc:creator>
      <pubDate>Thu, 07 Dec 2023 19:13:51 +0000</pubDate>
      <link>https://dev.to/slobodan4nista/step-by-step-evaluation-of-code-10ik</link>
      <guid>https://dev.to/slobodan4nista/step-by-step-evaluation-of-code-10ik</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;A while back I made an app that tracks my spending&lt;br&gt;
and after a while I realized that my tag system was lacking because I had multiple tags that were similar but letter case were different or I had a missing letter. That made my statistical evaluation of my spending go nuts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6vnqhjsa1qlxhvu2i7u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6vnqhjsa1qlxhvu2i7u.png" alt="Old app preview" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was promoted to make a solution and from that the "word-difference-calculator" was born.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxxxf6i1xasz1t7l9kc7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxxxf6i1xasz1t7l9kc7.png" alt="Tag editor" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Evaluating Missed Letter Cases
&lt;/h2&gt;

&lt;p&gt;When typing on PC first letter is small by default, and I like my tags that way, but on mobile phone first letter is upper case by default and that is annoying.&lt;br&gt;
So I addressed that problem with following code:&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;letter1&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;letter2&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;letter1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;letter2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;weightedDifference&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;caseWeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// case difference&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;h2&gt;
  
  
  Evaluating Missed or Added Letter
&lt;/h2&gt;

&lt;p&gt;Sometime while I type i forget to type one letter so that case must be covered, I did it using word horizontal search for missing letter.&lt;/p&gt;

&lt;p&gt;Code goes something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get(first, second, index){
 look for letter first[index] in second[min delta index]
 return min delta index
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When that is done we keep the returned index so we don't penalize one missing or added letter for all remaining letters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keyboard misses
&lt;/h2&gt;

&lt;p&gt;While typing on keyboard I frequently miss my keys so that was also accounted by:&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;rowDirection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;firstLetter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;secondLetter&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rowDiff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rowDirection&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;rowAdjust&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rowDirection&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.5&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;colDiff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pos1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;col&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;rowAdjust&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;pos2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;col&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;rowDiff&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;colDiff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now I can fat finger my keyboard I much as I want and there was not a problem in suggesting right tags from the list that is already defined.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Tests with Realistic Scenarios
&lt;/h2&gt;

&lt;p&gt;How to test something like this, well I tested it partial and in general:&lt;br&gt;
Partial test would be:&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;// Test for distance on eyboard&lt;/span&gt;
&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getKeyboardDistance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&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="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getKeyboardDistance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&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="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getKeyboardDistance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&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="s1"&gt;s&lt;/span&gt;&lt;span class="dl"&gt;'&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="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getKeyboardDistance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&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="s1"&gt;d&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getKeyboardDistance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;b&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="s1"&gt;t&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getKeyboardDistance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;q&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="s1"&gt;m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whole test would be:&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="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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;second&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;tests&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;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computeWordDifference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mf"&gt;0.03&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;second&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; e: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; v: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;val&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;h2&gt;
  
  
  Integration into an Application for Tag Recognition
&lt;/h2&gt;

&lt;p&gt;When I got to the app integration, it was easy, I just searched all the tags on every key, if any of the tags is similar I would showed it.&lt;/p&gt;

&lt;p&gt;There were few unexpected behaviors that required some work so I had to make an idea of the problem, while classical method would not give results I turned to some unorthodox approaches. &lt;/p&gt;

&lt;h2&gt;
  
  
  Large-Scale Testing with 4000 Words
&lt;/h2&gt;

&lt;p&gt;A while back I made an app that combines text typing game with tetris game so I had a pretty good word library and I figured that I can test every word with another and find the similar ones or the ones that brake my code. It gave me some results that looked like Gaussian bell function:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fszo08h0puow7q2k5wsx2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fszo08h0puow7q2k5wsx2.png" alt="Gaussian bell function off word differnce" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I learned how to make this graph but I learned nothing about my project, so I wanted to see more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Graphical Representation
&lt;/h2&gt;

&lt;p&gt;I wanted to see every relation of every word to another in 2d, I had an physics/game engine laying around that is easily extendable since it is ECS system, and I have a chain system implemented for testing chain mold effect:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh74z5z013tgnhtqwezqk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh74z5z013tgnhtqwezqk.png" alt="Chain mould" width="800" height="605"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://slobacartoonac.github.io/pythonium/chain_mould_effect/index.html"&gt;Interactive chain mold sim&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the other hand had perfect interface with new interaction function reedy to be employed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxghidb9wcs81pjaswj2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwxghidb9wcs81pjaswj2.png" alt="Words competing for place" width="800" height="522"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://slobacartoonac.github.io/pythonium/math-plot/public/index.html"&gt;Interactive math plotter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The force function &lt;code&gt;(x-1)*(x^-1)&lt;/code&gt; in my system, and it says if something is too close &amp;lt;1 then push it hard, if something is too far then try to attract it slightly.&lt;/p&gt;

&lt;p&gt;After just few hours I had something that I can play with, it was interesting to watch, but it was not enough. I added one input and my word from input would join all the words that were competing to be at the right spot in relation to its neighbors.&lt;/p&gt;

&lt;p&gt;The end result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2g19yyfcr7os7ynmpex2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2g19yyfcr7os7ynmpex2.png" alt="Grouping of the words" width="800" height="797"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://slobacartoonac.github.io/pythonium/word-cluster/public/index.html"&gt;Interactive words 2d&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Sometimes you just don't know where one project could lead. "word-difference-calculator" was part of one project, then it become a toy and a headache, then it inspired me to do some data science in the end it got its own game.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;I feel very lucky that things panned out in this way, many project were touched in this journey, I had what was needed because I choose infrastructure and stick to it trough 10+ projects and 2+ years.&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>softwaredevelopment</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>The Way I Wished JavaScript Went - A New Year's Wish 🌲</title>
      <dc:creator>Slobi</dc:creator>
      <pubDate>Tue, 05 Dec 2023 13:42:14 +0000</pubDate>
      <link>https://dev.to/slobodan4nista/the-way-i-wished-javascript-went-a-new-years-wish-49ce</link>
      <guid>https://dev.to/slobodan4nista/the-way-i-wished-javascript-went-a-new-years-wish-49ce</guid>
      <description>&lt;p&gt;As we approach the new year, let's dive in a programming fantasy and evolution of JavaScript that seamlessly blends its prototype-based nature with a cleaner, more expressive syntax influenced by Rust. Picture a world where defining objects maintains the familiar prototype structure but is enriched with a syntax that brings joy to developers.&lt;/p&gt;

&lt;p&gt;ES5-style Prototype Definition:&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;function&lt;/span&gt; &lt;span class="nf"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;print&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;In the well-known ES5-style prototype definition, we create a Person function and enhance its prototype with a print method. While this has been the JavaScript convention for a while, imagine infusing it with a syntax that's both cleaner and more expressive.&lt;/p&gt;

&lt;h1&gt;
  
  
  On JavaScript's Evolution
&lt;/h1&gt;

&lt;p&gt;I think that JavaScript, post-ES5, went off course with its current definition. Unfortunately, I can't turn back time, and the inertia from other languages, combined with the current state of JavaScript, is too great. People tend to favor what is familiar, a landscape is filled with millions of packages and hundreds of super-set languages attempting to address the complexities that are created by a "bad patch".&lt;br&gt;
But that can't stop us wishing!&lt;/p&gt;

&lt;h1&gt;
  
  
  The New Year's Wish:
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Prototype Definition&lt;/span&gt;
&lt;span class="nx"&gt;prototype&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Trait Declaration&lt;/span&gt;
&lt;span class="nx"&gt;trait&lt;/span&gt; &lt;span class="nx"&gt;Printable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Trait Implementation for Person&lt;/span&gt;
&lt;span class="nx"&gt;trait&lt;/span&gt; &lt;span class="nx"&gt;Printable&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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="c1"&gt;// Type-checked,converted and sanitized&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;myPerson&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; 
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myPerson&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// this allow for recommendation&lt;/span&gt;
&lt;span class="c1"&gt;// of all objects in scope that support print&lt;/span&gt;
&lt;span class="c1"&gt;// To avoid ambiguity, opt.:&lt;/span&gt;
&lt;span class="nx"&gt;print&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Printable&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;myPerson&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// This should be allowed&lt;/span&gt;
&lt;span class="nx"&gt;myPerson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this wishful vision, the Person prototype is defined in a concise and readable manner using explicit syntax, eliminating constructor boilerplate. To maintain JavaScript's extensibility and composability, traits are introduced.&lt;/p&gt;

&lt;h1&gt;
  
  
  Traits in JavaScript?
&lt;/h1&gt;

&lt;p&gt;Yes, imagine traits seamlessly integrated into JavaScript. In this wish, we use the trait keyword to declare a Printable trait with a print method. We then apply this trait to the Person prototype, allowing it to inherit and implement the behavior.&lt;/p&gt;

&lt;h1&gt;
  
  
  Type Checking
&lt;/h1&gt;

&lt;p&gt;The usage example demonstrates not only a cleaner syntax but also introduces type checking. The variable &lt;code&gt;myPerson&lt;/code&gt; is explicitly declared as a Person type, ensuring type safety during compilation/interpretation (who knows!). Additionally, the print function showcases how type ambiguity can be resolved, offering a more robust and predictable development experience.&lt;/p&gt;

&lt;p&gt;This syntax harmoniously combines the best of both worlds, returning the prototype-based structure familiar to older JavaScript developers while introducing a clean and expressive syntax. The result? A wishful JavaScript that's not only powerful but also a joy to write and read.&lt;/p&gt;

&lt;p&gt;Who knows what the future holds for JavaScript? Perhaps wishes like these might find their way into the language, making the developer experience even more delightful. 🍀&lt;/p&gt;

&lt;p&gt;I know this proposition can be unfavorable to many, so bring your toughs to the table and lets discuss. 🔥 &lt;/p&gt;

&lt;p&gt;Until then, let's keep dreaming and coding! 🚀✨&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
