<?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: Aemie Jariwala</title>
    <description>The latest articles on DEV Community by Aemie Jariwala (@aemiej).</description>
    <link>https://dev.to/aemiej</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%2F219080%2Fa66f2080-89f7-4619-9c59-fcc18b231d68.jpg</url>
      <title>DEV Community: Aemie Jariwala</title>
      <link>https://dev.to/aemiej</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aemiej"/>
    <language>en</language>
    <item>
      <title>Illuminating Unnoticed Efficiency Pitfalls with AtomicLongMap</title>
      <dc:creator>Aemie Jariwala</dc:creator>
      <pubDate>Sat, 13 Apr 2024 12:52:22 +0000</pubDate>
      <link>https://dev.to/aemiej/illuminating-unnoticed-efficiency-pitfalls-with-atomiclongmap-c1m</link>
      <guid>https://dev.to/aemiej/illuminating-unnoticed-efficiency-pitfalls-with-atomiclongmap-c1m</guid>
      <description>&lt;h3&gt;
  
  
  &lt;em&gt;Benchmark testing for AtomicLongMap&lt;/em&gt;
&lt;/h3&gt;




&lt;h4&gt;
  
  
  Why am I doing this benchmark test?
&lt;/h4&gt;

&lt;p&gt;It's important to verify if a particular change for a package, in this case &lt;code&gt;Google Guava&lt;/code&gt; performs in an optimized manner within a multi-threaded environment and doesn't trigger a thread contention state. Well, I came across one such change in the implementation for &lt;code&gt;AtomicLongMap&lt;/code&gt; which suffers from thread contention with the new releases. &lt;/p&gt;

&lt;h4&gt;
  
  
  Which method within AtomicLongMap is suffering from thread contention?
&lt;/h4&gt;

&lt;p&gt;The underlying method -  &lt;code&gt;addAndGet(K key, int delta)&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  When was a new implementation introduced for &lt;code&gt;addAndGet&lt;/code&gt; method in Google Guava?
&lt;/h4&gt;

&lt;p&gt;Google Guava - v21.0&lt;/p&gt;

&lt;h4&gt;
  
  
  Why was this change introduced?
&lt;/h4&gt;

&lt;p&gt;According to the &lt;a href="https://github.com/google/guava/wiki/Release21"&gt;release notes&lt;/a&gt;: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;AtomicLongMap: added a number of methods such as accumulateAndGet(K, LongBinaryOperator) that take advantage of new Java functional types.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  How did I notice it?
&lt;/h4&gt;

&lt;p&gt;I bumped my java package to use &lt;code&gt;GoogleGuava - v32.0.0&lt;/code&gt; from &lt;code&gt;GoogleGuava - v20.0&lt;/code&gt; and my package blew up on load-testing. It took me a bit of digging through profiling and monitoring and was able to pinpoint that the trigger for the issue is none other than &lt;code&gt;AtomicLongMap&lt;/code&gt;! This sparked the curiousity into understanding why did a new release start suffering from thread contention and that's the reason for the benchmark testing. &lt;/p&gt;

&lt;h3&gt;
  
  
  Enough story time, let's dig into the implementation difference
&lt;/h3&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%2Fox6eajx7zuxfgl0xerj5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fox6eajx7zuxfgl0xerj5.gif" alt="Image description" width="480" height="480"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://giphy.com/gifs/computador-gu-tecnology-bGgsc5mWoryfgKBx1u"&gt;via Giphy&lt;/a&gt;&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;em&gt;Google Guava 20.0 Implementation Flow [Psuedo]&lt;/em&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Link to code:&lt;/strong&gt; &lt;a href="https://github.com/google/guava/blob/65f6b4f4b132a051616403bcf74e4034a19d92a1/guava/src/com/google/common/util/concurrent/AtomicLongMap.java#L107"&gt;AtomicLongMap.java&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;addAndGet&lt;span class="o"&gt;(&lt;/span&gt;K key, int delta&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; atomic &lt;span class="o"&gt;=&lt;/span&gt; map.putIfAbsent&lt;span class="o"&gt;(&lt;/span&gt;key, delta&lt;span class="o"&gt;)&lt;/span&gt; 
&lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;if  &lt;/span&gt;atomic.get&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; 0 : 
       map.replace&lt;span class="o"&gt;(&lt;/span&gt;atomic.get&lt;span class="o"&gt;()&lt;/span&gt;, atomic, delta&lt;span class="o"&gt;)&lt;/span&gt; 
       &lt;span class="k"&gt;return &lt;/span&gt;delta
&lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt;: 
        val &lt;span class="o"&gt;=&lt;/span&gt; atomic.get&lt;span class="o"&gt;()&lt;/span&gt;
        atomic.compareAndSet&lt;span class="o"&gt;(&lt;/span&gt;val, val + delta&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return &lt;/span&gt;val + delta
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;em&gt;Google Guava 32.0.0 Implementation Flow [Psuedo]&lt;/em&gt;
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Upon back-tracking, the below implementation flow was introduced in Google Guava v21.0 so this degradation is existing since v21.0 : &lt;a href="https://github.com/google/guava/wiki/Release21"&gt;https://github.com/google/guava/wiki/Release21&lt;/a&gt; however the benchmark testing is carried out using Google Guava v32.0.0&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Link to code:&lt;/strong&gt; &lt;a href="https://github.com/google/guava/blob/6b1f97ced922d48f071153ad9e631d06383033a4/guava/src/com/google/common/util/concurrent/AtomicLongMap.java#L110"&gt;AtomicLongMap.java&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;addAndGet&lt;span class="o"&gt;(&lt;/span&gt;K key, int delta&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; accumulateAndGet&lt;span class="o"&gt;(&lt;/span&gt;key, delta, Long::sum as aFunc&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
updateAndGet&lt;span class="o"&gt;(&lt;/span&gt;key, o -&amp;gt; aFunc.applyAsLong&lt;span class="o"&gt;(&lt;/span&gt;o, delta&lt;span class="o"&gt;)&lt;/span&gt; as uFunc&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
map.compute&lt;span class="o"&gt;(&lt;/span&gt;key, &lt;span class="o"&gt;(&lt;/span&gt;k, x&lt;span class="o"&gt;)&lt;/span&gt; -&amp;gt; uFunc.applyAsLong&lt;span class="o"&gt;(&lt;/span&gt;x &lt;span class="o"&gt;==&lt;/span&gt; null ? 0 : x.longValue&lt;span class="o"&gt;()))&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;em&gt;What's the possible difference in their behavior within a multi-threaded environment?&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;It is use of the specific underlying method of ConcurrentMap that is being utilised and the impact in their performance is majorly driven by how well it behaves in highly contended environment. &lt;/p&gt;

&lt;p&gt;In case of &lt;strong&gt;Google Guava 20.0&lt;/strong&gt;, &lt;code&gt;putIfAbsent&lt;/code&gt; is utilised and when using putIfAbsent, the operation succeeds only if the key is not already present in the map. If the key is present, the operation does not perform any update and returns the existing value associated with the key. This behavior helps reduce contention because it avoids the need for complex coordination between threads when updating values. This is followed by using &lt;code&gt;compareAndSet&lt;/code&gt; which is another atomic operation which may offer better performance in a multi-threaded environment compared to the compute method, especially when you're dealing with atomic updates on a single shared variable. This is because &lt;code&gt;compareAndSet&lt;/code&gt; operates directly on a single atomic variable and doesn't involve the overhead of interacting with a concurrent data structure like a map.&lt;/p&gt;

&lt;p&gt;In case of &lt;strong&gt;Google Guava 32.0.0&lt;/strong&gt;, &lt;code&gt;compute&lt;/code&gt; method is utilized and using &lt;code&gt;compute&lt;/code&gt; method &lt;br&gt;
with an accumulator function involves a more complex operation. It requires reading the current value associated with the key, applying the accumulatorfunction to compute a new value based on the old value (if any) and the input, &lt;br&gt;
and then updating the map with the new value. In highly contended scenarios, multiple threads attempting to perform such operations concurrently may lead to increased contention and synchronization overhead, potentially affecting performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  LET'S GET INTO TESTING !!
&lt;/h2&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%2Fzxz26045afawxxw5qxac.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxz26045afawxxw5qxac.gif" alt="Image description" width="500" height="363"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://giphy.com/gifs/bugs-bunny-running-exercise-QJvwBSGaoc4eI"&gt;via Giphy&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note: Setup of the testing is present in the End of the blog&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h4&gt;
  
  
  &lt;em&gt;Case 1 : NumThreads = 2&lt;/em&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Who won the battle?&lt;/strong&gt; Google Guava v20.0&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What's the difference in performance?&lt;/strong&gt; 78.6%&lt;/li&gt;
&lt;/ol&gt;




&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Version = 20.0&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trial&lt;/th&gt;
&lt;th&gt;Time to Execute (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Average&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Version = 32.0.0&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trial&lt;/th&gt;
&lt;th&gt;Time to Execute (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Average&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h4&gt;
  
  
  &lt;em&gt;Case 2 : NumThreads = 10&lt;/em&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Who won the battle?&lt;/strong&gt; Google Guava v20.0&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What's the difference in performance?&lt;/strong&gt; 73.2%&lt;/li&gt;
&lt;/ol&gt;




&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Version = 20.0&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trial&lt;/th&gt;
&lt;th&gt;Time to Execute (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;73&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;73&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;73&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;74&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;73&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Average&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;73.2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Version = 32.0.0&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trial&lt;/th&gt;
&lt;th&gt;Time to Execute (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;126&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;126&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;127&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;127&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Average&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;126.8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h4&gt;
  
  
  &lt;em&gt;Case 3 : NumThreads = 32&lt;/em&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Who won the battle?&lt;/strong&gt; Google Guava v20.0&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What's the difference in performance?&lt;/strong&gt; 72.5% &lt;/li&gt;
&lt;/ol&gt;




&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Version = 20.0&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trial&lt;/th&gt;
&lt;th&gt;Time to Execute (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;236&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;235&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;234&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;234&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;235&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Average&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;234.8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Version = 32.0.0&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trial&lt;/th&gt;
&lt;th&gt;Time to Execute (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;403&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;405&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;401&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;410&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;406&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Average&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;405&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h4&gt;
  
  
  &lt;em&gt;Case 4 : NumThreads = 64&lt;/em&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Who won the battle?&lt;/strong&gt; Google Guava v20.0&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What's the difference in performance?&lt;/strong&gt; 70.7%&lt;/li&gt;
&lt;/ol&gt;




&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Version = 20.0&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trial&lt;/th&gt;
&lt;th&gt;Time to Execute (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;474&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;474&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;473&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;473&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;472&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Average&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;473.2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Version = 32.0.0&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trial&lt;/th&gt;
&lt;th&gt;Time to Execute (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;804&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;811&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;809&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;809&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;805&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Average&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;807.6&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&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%2Fc5gi1pnf2c1xfdwvhdty.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc5gi1pnf2c1xfdwvhdty.gif" alt="Image description" width="499" height="366"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://giphy.com/gifs/the-end-thats-all-folks-lD76yTC5zxZPG"&gt;via Giphy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Google Guava v20.0&lt;/code&gt; has a simplified implementation which performs 70% better than the later releases for &lt;code&gt;AtomicLongMap.java&lt;/code&gt;. Will love to hear other people's opinion on the same and why do you think the new implementation of &lt;code&gt;AtomicLongMap&lt;/code&gt; is suffering from thread contention! &lt;/p&gt;

&lt;h2&gt;
  
  
  Setup of the test
&lt;/h2&gt;

&lt;p&gt;It is a simple benchmark test to test the performance of the 2 GoogleGuava releases &lt;code&gt;addAndGet()&lt;/code&gt; method defined within the &lt;code&gt;AtomicLongMap&lt;/code&gt; class in a multi-threaded environment&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Main.java
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.time.Clock&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;main.java.com.benchmark.Benchmark&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.concurrent.ExecutorService&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.concurrent.Executors&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.concurrent.TimeUnit&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Clock&lt;/span&gt; &lt;span class="n"&gt;clock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Clock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;systemDefaultZone&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Benchmark&lt;/span&gt; &lt;span class="n"&gt;benchmark&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;Benchmark&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="no"&gt;NUM_CALLS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000000000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="no"&gt;NUM_THREADS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;millis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Current time : "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;ExecutorService&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Executors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newFixedThreadPool&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;NUM_THREADS&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;IncrementTask&lt;/span&gt; &lt;span class="n"&gt;task&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;IncrementTask&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;benchmark&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;NUM_CALLS&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;threadPool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;threadPool&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;NUM_THREADS&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;threadPool&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shutdown&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;awaitTermination&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MAX_VALUE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TimeUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MILLISECONDS&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;completed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;millis&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;difference&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;completed&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Completed time: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;completed&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Time difference for Google Guava: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;difference&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" seconds."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IncrementTask&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Runnable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Benchmark&lt;/span&gt; &lt;span class="n"&gt;benchmark&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;numCalls&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;IncrementTask&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Benchmark&lt;/span&gt; &lt;span class="n"&gt;benchmark&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;numCalls&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;benchmark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;benchmark&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;numCalls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numCalls&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;threadId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;threadName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;currentThread&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Task executed by Thread "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;threadId&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" ("&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;threadName&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;")"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="kd"&gt;synchronized&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;benchmark&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;trial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;trial&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;numCalls&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;trial&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;benchmark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Benchmark.java
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Benchmark&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;AtomicLongMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;counters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nc"&gt;AtomicLongMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Key"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;counters&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAndGet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;KEY&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>java</category>
      <category>softwareengineering</category>
      <category>google</category>
      <category>testing</category>
    </item>
    <item>
      <title>The essential pillar stones to become a software engineer</title>
      <dc:creator>Aemie Jariwala</dc:creator>
      <pubDate>Tue, 15 Feb 2022 08:05:42 +0000</pubDate>
      <link>https://dev.to/aemiej/the-essential-pillar-stones-to-become-a-software-engineer-5h4d</link>
      <guid>https://dev.to/aemiej/the-essential-pillar-stones-to-become-a-software-engineer-5h4d</guid>
      <description>&lt;p&gt;A software engineer is curious to come up with an efficient and scalable solution depending upon the problem. Let's say you're a software engineer who has basic knowledge and hence can come up with a simple solution. That is cool but what about a &lt;strong&gt;scalable solution&lt;/strong&gt;! With more clients, you need to scale up. To come up with that, software engineers should familiarize themselves with the &lt;strong&gt;pillar stones&lt;/strong&gt; of software engineering.&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%2Fi0.wp.com%2Fblog.securly.com%2Fwp-content%2Fuploads%2F2017%2F09%2Fsecurly-horizontal-scaling-gif-1.gif%3Ffit%3D2529%252C1875%26ssl%3D1" 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%2Fi0.wp.com%2Fblog.securly.com%2Fwp-content%2Fuploads%2F2017%2F09%2Fsecurly-horizontal-scaling-gif-1.gif%3Ffit%3D2529%252C1875%26ssl%3D1" alt="meme gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't get scared by hearing the term essential pillar stones, they just help in simplifying the concepts that would once seem complex. As an additional bonus, these pillars will help you in your interviews for sure. Without any further chit-chat, we will dig into the pillars! &lt;/p&gt;

&lt;p&gt;Let's disclose the name of the pillars now! The pillars are Operating Systems, Network and Web Security, Database Engineering, System Design, and last being data structure and algorithms. I will be only focusing on the first 4 and at the end of the blog, I will provide a small piece of information on how I try to improve my DSA skills. Operation System and Network and Web Security create the basic foundation and understanding the concepts for those two pillars will further help in understanding the concepts of the other 2 pillars. &lt;/p&gt;

&lt;h2&gt;
  
  
  1. Operation System
&lt;/h2&gt;

&lt;p&gt;We all have heard of windows, Linux, Apple macOS. They're the existing operating system that manages hardware and software resources. Did you ever wonder how the multiple huge processes fit into the main memory and how the CPU schedules the various tasks? Understanding CPU scheduling tasks, pagination, and segmentation, the concepts of virtual memory will blow your mind!  It will provide you with an idea of how your processes and various applications function so efficiently on your devices.&lt;/p&gt;

&lt;p&gt;In my opinion, you can certainly dig real deep as you want but as a software engineer, a few concepts are essential to know and thus I have curated a playlist with all the OS concepts for a software engineer - &lt;a href="https://www.youtube.com/playlist?list=PLOU7PAjLVz8omogw4JDw5eeQEVfHOmHTu" rel="noopener noreferrer"&gt;https://www.youtube.com/playlist?list=PLOU7PAjLVz8omogw4JDw5eeQEVfHOmHTu&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The playlist covers the following topics - &lt;br&gt;
➡️ Process v/s Threads&lt;br&gt;
➡️ Multi-processing and Multi-threading&lt;br&gt;
➡️ Virtual Memory &lt;br&gt;
➡️ Paging &lt;br&gt;
➡️ Translation Lookaside Buffer&lt;br&gt;
➡️ Deadlocks, Semaphores &amp;amp; Mutex&lt;br&gt;
➡️ CPU Scheduling (Preemptive &amp;amp; Non-preemptive) &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Network and Web Security
&lt;/h2&gt;

&lt;p&gt;This is one of the most interesting topics for me. I am not a network engineer of course hence as a software engineer I try to understand the concepts at a good surface-level which can further help me with understanding complex system design theory.&lt;/p&gt;

&lt;p&gt;Now under this section, I believe it is extremely essential for understanding TCP and UDP protocols, the classic OSI model, TLS, DNS, and endless protocols that help in understanding how the connection of the client to server happens even (I am fangirling but it's all so exciting). Thus, within my playlist there also includes a video on what happens when you enter google.com in the browser (super interesting) - &lt;a href="https://youtube.com/playlist?list=PLOU7PAjLVz8qfmiqTYxHED-kCXW7eYtVx" rel="noopener noreferrer"&gt;https://youtube.com/playlist?list=PLOU7PAjLVz8qfmiqTYxHED-kCXW7eYtVx&lt;/a&gt;&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%2Fc.tenor.com%2F2eyipqVX9DQAAAAC%2Fmovie-animation.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fc.tenor.com%2F2eyipqVX9DQAAAAC%2Fmovie-animation.gif" alt="Fangirling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The playlist covers the following topics - &lt;br&gt;
➡️ OSI Model (The famous classic)&lt;br&gt;
➡️ TCP, TCP 3-way handshake, TCP slow start, UDP&lt;br&gt;
➡️ Hypertext Transfer Protocol (HTTP) &lt;br&gt;
➡️ Transfer Layer Security (TLS)&lt;br&gt;
➡️ Server Name Indication (relative to TLS)&lt;br&gt;
➡️ Network Address Translation (NAT)&lt;br&gt;
➡️ Address Resolution Protocol (ARP)&lt;br&gt;
➡️ Virtual Private Network (VPN)&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Database Engineering
&lt;/h2&gt;

&lt;p&gt;This is my favorite pillar (not going to deny it). I have always found backend engineering interesting but at the start, it was all about using a single database (SQL or NoSQL) based on my interest and not taking scaling into account. &lt;strong&gt;SUCH A WRONG APPROACH&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you want to learn database engineering which is so useful for backend engineering, you need to be able to understand the ACID transactions. There is also a clear difference between SQL and NoSQL and it is very essential to understand it to choose based on a project. Apart from this, scaling a database is advanced and there are so many methods including indexing, partitioning, and sharding (too important concepts). Not scaring you off but with the playlist, I have curated, I am certain the concepts will become easy for you - &lt;a href="https://youtube.com/playlist?list=PLOU7PAjLVz8qwdYWCd6qi4IeUTypQKqyZ" rel="noopener noreferrer"&gt;https://youtube.com/playlist?list=PLOU7PAjLVz8qwdYWCd6qi4IeUTypQKqyZ&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The playlist covers the following topics - &lt;br&gt;
➡️ ACID Properties&lt;br&gt;
➡️ Conflict and view serializability&lt;br&gt;
➡️ Database Indexing&lt;br&gt;
➡️ BTree, B+Tree, Log-Structured Merge (LSM) Tree&lt;br&gt;
➡️ Bloom Filters&lt;br&gt;
➡️ Database Replication&lt;br&gt;
➡️ Storing tables on disk&lt;br&gt;
➡️ Long Polling&lt;br&gt;
➡️ Database Partition&lt;br&gt;
➡️ Column v/s Row Oriented Database&lt;br&gt;
➡️ SQL v/s NoSQL, SQL Joins, SQL Injection Attack&lt;br&gt;
➡️ Concurrency Control, MVCC&lt;br&gt;
➡️ Keys in DBMS, Normalization&lt;br&gt;
➡️ Database Sharding &lt;br&gt;
➡️ Connection polling &lt;br&gt;
➡️ Web Sockets&lt;br&gt;
➡️ Redis&lt;/p&gt;

&lt;h2&gt;
  
  
  4. System Design
&lt;/h2&gt;

&lt;p&gt;We've come down to the last pillar! System design comes in plenty of interviews along with OS but the concepts of system design are so extremely important for any job you enter 'cause you need to build a scalable and either a highly consistent or highly available product. &lt;/p&gt;

&lt;p&gt;You might have heard of the term &lt;strong&gt;load balancing&lt;/strong&gt; and don't know what exactly it is and so many algorithms attached to it. Within the playlist, it sequentially covers proxy, reverse proxy, load balancing, rate limiting and so many fancy terms you will hear definitely when building a scalable product. Thus, my curated list will help you certainly and it also involves a few system design interview videos which I found very helpful - &lt;a href="https://youtube.com/playlist?list=PLOU7PAjLVz8rFA-Atn-mEQ2IGaMWVitu7" rel="noopener noreferrer"&gt;https://youtube.com/playlist?list=PLOU7PAjLVz8rFA-Atn-mEQ2IGaMWVitu7&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The playlist covers the following topics - &lt;br&gt;
➡️ Proxy v/s Reverse Proxy&lt;br&gt;
➡️ Sidecar Proxy, HTTP Proxy, service mesh proxy&lt;br&gt;
➡️ Load Balancing, Consistent Hashing&lt;br&gt;
➡️ Layer 4 v/s layer 7 load balancing&lt;br&gt;
➡️ Rate Limiting&lt;br&gt;
➡️ Fail-over and high-availability&lt;br&gt;
➡️ Active-active and active-passive cluster&lt;br&gt;
➡️ Pub-Sub, Two generals' problem, Message Queue&lt;br&gt;
➡️ CAP Theorem&lt;br&gt;
➡️ Distributed Caching&lt;br&gt;
➡️ Content Delivery Networks (CDN)&lt;br&gt;
➡️ Cross-Origin Resource Sharing (CORS)&lt;br&gt;
➡️ Distributed locks, distributed consensus, PAXOS algorithm&lt;br&gt;
➡️ Protocol Buffers&lt;br&gt;
➡️ Remote Procedure Call (RPC)&lt;/p&gt;

&lt;p&gt;This covers the 4 major pillars of software engineering and the playlist will be helpful as it will reduce your search time and you can focus on broadening your knowledge (a bit easy peasy). Also, this playlist will continue to update as I find more concepts to learn so I will just keep adding and updating (so save the playlist!). If you think I have missed out on a topic, please mention it within the comments as well. &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%2Ftechnerds.com%2Fwp-content%2Fuploads%2F2021%2F05%2FHollowShockedGerenuk-max-1mb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftechnerds.com%2Fwp-content%2Fuploads%2F2021%2F05%2FHollowShockedGerenuk-max-1mb.gif" alt="easy-peasy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Coming to the last pillar i.e Data Structures and algorithms, for this well, I focus on data types such as Linked List, Hash Map, Trie, BST, and sorting algorithms. Every week you could practice easy to medium Leetcode questions and when you feel confident try out a hard one. Also, there is no shame in checking out the solution or the hints after you have given 15-20 minutes of your time on solving the problem. Learn and grow, that's what the motto of any software engineer should be. Adios 👋🏼&lt;/p&gt;

</description>
      <category>career</category>
      <category>programming</category>
    </item>
    <item>
      <title>Top 10 Chrome Extensions I can't live without</title>
      <dc:creator>Aemie Jariwala</dc:creator>
      <pubDate>Thu, 01 Apr 2021 14:03:27 +0000</pubDate>
      <link>https://dev.to/aemiej/top-10-chrome-extensions-i-can-t-live-without-2bdf</link>
      <guid>https://dev.to/aemiej/top-10-chrome-extensions-i-can-t-live-without-2bdf</guid>
      <description>&lt;p&gt;Chrome extensions are simple extension tools that help with coordinating one's work. I have been a growing developer and for me, a productive chrome extension that helps me improvise my understanding of website and API, enhancing productivity is really important to me.&lt;/p&gt;

&lt;p&gt;In this blog, I will be including the top 10 chrome extensions that I make use of as a developer frequently and I believe every developer must make use of those as well. I will also provide you the reason why you should continue reading: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A detailed understanding of how and when the extension can be made use of&lt;/li&gt;
&lt;li&gt; Personal rating for each along with the reasoning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, a brief review of each of my top 10 extensions.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Reader Mode
&lt;/h2&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%2F9xp6ap7smjpkghbgz8qu.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%2F9xp6ap7smjpkghbgz8qu.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9xp6ap7smjpkghbgz8qu.png" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reader Mode is an extension that helps in removing any redundant/unnecessary sections from the webpage such as overflowing advertisements. Reader Mode gives in layman terms, a kindle-reading-like experience. Besides, it provides various features and to list a few:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom Theme Styles&lt;/li&gt;
&lt;li&gt;Removes any redundant section from the webpage such as advertisements - This is convenient as advertisements block parts of the webpage and you can't give 100% focus to reading. With this feature, you can give 100% of your focus.&lt;/li&gt;
&lt;li&gt;Text to Speech - This is my personal favorite as when I am tired I would love to just have an audiobook-like feeling.&lt;/li&gt;
&lt;li&gt;You can save the articles you've edited in the reader mode and go to the dashboard to view them later as well - Just like a personal library, easy to manage, and plenty easy to re-read your saved articles.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Where &amp;amp; when can I use Reader Mode?
&lt;/h3&gt;

&lt;p&gt;I have a habit of reading plenty of blogs and articles for understanding different concepts. Let's take, for instance, geeks for geeks is a website overflowing with advertisements and I want a seamless reading experience without the navbar or the advertisements or any useless sections of the webpage.&lt;/p&gt;

&lt;p&gt;In such cases, I have the reader mode extension and I just click on it and voila, I have a neat paper view that provides a seamless reading experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Original View
&lt;/h3&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%2Fa6bmbdk529bpm2pm8in7.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%2Fa6bmbdk529bpm2pm8in7.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a6bmbdk529bpm2pm8in7.png" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ReaderMode View
&lt;/h3&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%2Fi7d194dgnvv4drmi0xra.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%2Fi7d194dgnvv4drmi0xra.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i7d194dgnvv4drmi0xra.png" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the picture comparison, it makes it quite clear whether you want to read directly from the website or use the Reader Mode extension to do so!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Link For Extension&lt;/strong&gt; - &lt;a href="https://bit.ly/3u7wcDY"&gt;https://bit.ly/3u7wcDY&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Personal Rating&lt;/strong&gt; - 4/5&lt;/p&gt;

&lt;p&gt;The only thing is most features are premium however even with the free features you can have an amazing experience. ✨&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Talend API Tester
&lt;/h2&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%2Fuer8nn5xfk089ipjbazc.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%2Fuer8nn5xfk089ipjbazc.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uer8nn5xfk089ipjbazc.png" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Talend Cloud API Tester allows you to interact with REST services. In simpler words, it provides functionality similar to postman however Talend API tester exists as a chrome extension tool on the web.&lt;/p&gt;

&lt;p&gt;In my experience, it can work well on small-scale projects and is the best alternative for me over postman in a few scenarios. It was really easy for me to set up and start working with it. To list the few basic features of Talend API tester, it includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create environments based on your project&lt;/li&gt;
&lt;li&gt;Import a JSON file and get all the API endpoints in hand - I find this an amazing feature and also, you can edit and test as you want&lt;/li&gt;
&lt;li&gt;Create API endpoints, include your team, and export the endpoints as a JSON file as well&lt;/li&gt;
&lt;/ul&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%2Ffvnmr6grakz310bud7jc.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%2Ffvnmr6grakz310bud7jc.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fvnmr6grakz310bud7jc.png" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the figure, it does give a feel as that of the postman itself and helps with working with API endpoints through the web directly. The reason I would use Talend API over postman could be during scenarios when I want to make use of the web directly instead of opening separate applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Link&lt;/strong&gt; - &lt;a href="https://bit.ly/3diaTJ5"&gt;https://bit.ly/3diaTJ5&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Personal Rating&lt;/strong&gt; - 3.5/5&lt;/p&gt;

&lt;p&gt;Even if it does provide flexibility and easy working with API endpoints through the web, it doesn't match up to the flexibility provided by the postman.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Redux DevTools
&lt;/h2&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%2Facy13m9rapa8pp8lfd6n.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%2Facy13m9rapa8pp8lfd6n.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/acy13m9rapa8pp8lfd6n.png" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Redux is a JavaScript library for managing application state. One majorly uses it along with React JS or AngularJS. When you want to explore how the state is being managed, you don't want to continuously do &lt;code&gt;console.log&lt;/code&gt; it gets frustrating. An alternate approach and a more desirable one is to see visually how the state changes on user interaction with the application.&lt;/p&gt;

&lt;p&gt;This visualization is possible with the Redux DevTools extension. After this extension is installed in your browser,  you add a one liner configuration when creating your store in your codebase. In case of ReactJS, you do the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="cm"&gt;/* preloadedState, */&lt;/span&gt;
        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__REDUX_DEVTOOLS_EXTENSION__&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;__REDUX_DEVTOOLS_EXTENSION__&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;When you run your application either using &lt;code&gt;yarn start&lt;/code&gt; or &lt;code&gt;npm run start&lt;/code&gt; along with your default dev tools you will observe one for &lt;code&gt;Redux&lt;/code&gt; as well. The features that this extension provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inspector to track which state is changing from one value to another&lt;/li&gt;
&lt;li&gt;The individual state's list is also provided where you can see the current state of each in the application&lt;/li&gt;
&lt;li&gt;A diff section to showcase the difference in the state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Link&lt;/strong&gt; - &lt;a href="https://bit.ly/2Oc6qPS"&gt;https://bit.ly/2Oc6qPS&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Personal Rating&lt;/strong&gt; - 4.5/5&lt;/p&gt;

&lt;h2&gt;
  
  
  4. ColorZilla
&lt;/h2&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%2Fa0lxg2w7op4gwzz4cfi3.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%2Fa0lxg2w7op4gwzz4cfi3.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a0lxg2w7op4gwzz4cfi3.png" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Colors are really important in a website as they need to be of the proper amount of contrast based on the rules defined and along with it, you need to choose a combination of colors that will act as a unique color palette for your website. ColorZilla is an amazing chrome extension that provides an amazing set of features, to list a few:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Picks the entire color palette from the current web page&lt;/li&gt;
&lt;li&gt;Provides a color gradient generator and the code to include it directly on our website&lt;/li&gt;
&lt;li&gt;Pick any color from the page - My favorite feature&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The way I use ColorZilla mainly is the color picker feature. Sometimes, choosing a color palette is not enough for your website, it may/may not fit the contrast rule. Thus, I believe that the colors are related to the logo of the website, and in a logo lies a variety of colors. With ColorZilla, I can easily pick the color I want! It just doesn't stop there, of course, you can make use of ColorZilla in numerous useful ways including the method I use it for.&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%2Fgc35yfdo2i8i50jvqfgi.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%2Fgc35yfdo2i8i50jvqfgi.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gc35yfdo2i8i50jvqfgi.png" width="800" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the figure, I have just shown the proper for analyzing the colors of the webpage, one of its amazing features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Link&lt;/strong&gt; - &lt;a href="https://bit.ly/39sjiIW"&gt;https://bit.ly/39sjiIW&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Personal Rating&lt;/strong&gt; - 4.5/5&lt;/p&gt;

&lt;p&gt;I can't provide it 5 for the only reason that I would like it to have the additional features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It analyses the color palette of the webpage and generates a similar palette as well&lt;/li&gt;
&lt;li&gt;Based on the color picked from the webpage, generate a palette combination for the same&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. CSS Peeper
&lt;/h2&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%2Fz8yty50baitdxv1c7nae.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%2Fz8yty50baitdxv1c7nae.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z8yty50baitdxv1c7nae.png" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A chrome extension tool that analyses the CSS of the complete webpage. It is an amazing chrome extension and the major reason is that when you're analyzing the webpage you need to go to dev tools and under elements, hover over a component, and then get its CSS property and assets all by YOURSELF!&lt;/p&gt;

&lt;p&gt;This extension does the entire work for you. It provides the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All the font-family used in the webpage&lt;/li&gt;
&lt;li&gt;The entire color palette of the webpage and the ability to copy each color separately&lt;/li&gt;
&lt;li&gt;Each asset image is generated from the webpage - Love this feature as it is such one-click access to all the images of the webpage&lt;/li&gt;
&lt;li&gt;Access property of the components in the website by hovering over the individual components&lt;/li&gt;
&lt;/ul&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%2F52vgadx3rfmc8vja67lx.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%2F52vgadx3rfmc8vja67lx.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/52vgadx3rfmc8vja67lx.png" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the figure, you can see how the property of the selected component is given, one of the best features of CSS Peeper. Similarly, move to the webpage you want to directly inspect and click on the extension, you can then experience the amazing features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Link&lt;/strong&gt; - &lt;a href="https://bit.ly/3wmzjdo"&gt;https://bit.ly/3wmzjdo&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Personal Rating&lt;/strong&gt; - 5/5&lt;/p&gt;

&lt;p&gt;I simply find all the features highly useful for analyzing the CSS of the webpage. Just simply neat and amazing ✨&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Web Developer Checklist
&lt;/h2&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%2Fq9kyz8exz3bpuxvrf7zw.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%2Fq9kyz8exz3bpuxvrf7zw.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q9kyz8exz3bpuxvrf7zw.png" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Checklists are very efficient in my opinion. For any important task, I make sure to create a checklist and keep track of all the tasks I am performing based on it. This applies to my daily life tasks but I also require a checklist when I create a website as a developer to keep my website score up. That's when this extension comes in handy!&lt;/p&gt;

&lt;p&gt;When one creates the website, one checks the Audits in the dev tools provided to check the score for accessibility, SEO, and such and edit the website to improve it continuously.&lt;/p&gt;

&lt;p&gt;The web developer checklist helps in majorly analyzing the violations of any best practices in terms of the web application. Few of the items it performs a check on includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SEO&lt;/li&gt;
&lt;li&gt;Usability including friendly URLs and HTML Validation&lt;/li&gt;
&lt;li&gt;Accessibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The method I use is for a website I create, I run this extension against it and check for any specific errors or tasks I might have missed out on regarding the best practices.  After I am done with the checklist, I run it once against my Audit to check the score. (it increases!)&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%2Fwusfampdd6hj7n4xkioz.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%2Fwusfampdd6hj7n4xkioz.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wusfampdd6hj7n4xkioz.png" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the figure, it's observable that despite creating a neat website, I missed out on a few aspects while creating the DSC, NIT Surat website. It's simple to make changes as per that and maintain a good audit score as well!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Link&lt;/strong&gt; - &lt;a href="https://bit.ly/3frpKUd"&gt;https://bit.ly/3frpKUd&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Personal Rating&lt;/strong&gt; - 4/5&lt;/p&gt;

&lt;h2&gt;
  
  
  7. CheckMyLinks
&lt;/h2&gt;

&lt;p&gt;Let's paint a scenario where you understand the importance of this extension. Let's say you are responsible for maintaining a highly documented website such as the camel website or the bootstrap website. In the case of the camel website, there exists several versions and based on it, documentation for each. It is important to check if there are any broken links on the webpage as older version docs wouldn't be highly maintained or checked. Thus, to validate all the links on your webpage, the extension comes into major use.&lt;/p&gt;

&lt;p&gt;This feature can certainly be used for your website as well because it is always better to cross-check with the extension for any broken links! Let's list the features of this extension:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checks all the links on the webpage for validity&lt;/li&gt;
&lt;li&gt;For any warning, it provides the warning in the console&lt;/li&gt;
&lt;li&gt;It checks thoroughly for any broken links on the webpage and provides the option to copy all the broken links altogether from the console&lt;/li&gt;
&lt;li&gt;When it identifies a broken link on the webpage, it marks it red and along with it shows its respective status code&lt;/li&gt;
&lt;/ul&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%2Fdp40mps04uhm1sdaj4g2.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%2Fdp40mps04uhm1sdaj4g2.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dp40mps04uhm1sdaj4g2.png" width="800" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the figure, it is observable that a link is invalid and the extension easily caught it. When you check your console in dev tools, it prints the invalid URL as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Link&lt;/strong&gt; - &lt;a href="https://bit.ly/39uRPGr"&gt;https://bit.ly/39uRPGr&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Personal Rating&lt;/strong&gt; - 4/5&lt;/p&gt;

&lt;p&gt;The one thing I dislike about this extension is that once, I have checked my webpage for the links and I close the extension, the highlighted links remain (I don't like it). Due to this, I need to refresh my page which is not an ideal option if I am way down the webpage.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Enhanced Github
&lt;/h2&gt;

&lt;p&gt;I am just going to put it into the plate even if not related to the extension, I am an active Github user and I love GitHub. Github is an amazing platform however there are some features it doesn't provide and that's when the amazing GitHub-related extension makes me happy and satisfied with Github.&lt;/p&gt;

&lt;p&gt;Let's layout the features provided by the extension on top of the Github platform:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Displays repo size - this is beneficial in my case, as I like to understand the amount of storage required by a repo beforehand itself&lt;/li&gt;
&lt;li&gt;Displays the size of each file in a branch&lt;/li&gt;
&lt;li&gt;Provides feature to either download a file or copy the entire file to clipboard - I just love this feature cause I come across a file in a repo let's say a competitive repo and I want a solution reference. With this extension, I can easily just copy the file to the clipboard with 1 click instead of clicking on raw and then copy-pasting (it's a drag for me, honestly)&lt;/li&gt;
&lt;/ul&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%2F3kso1igv4x1pdt4hhp8q.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%2F3kso1igv4x1pdt4hhp8q.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3kso1igv4x1pdt4hhp8q.png" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To enable the extension as seen in the figure, you do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the chrome extension to your browser &amp;amp; then click the extension&lt;/li&gt;
&lt;li&gt;On clicking, you will be asked to give the access token&lt;/li&gt;
&lt;li&gt;For providing the access token, you create the access token for the extension through this &lt;a href="https://www.notion.so/%5B%3Chttps://github.com/settings/tokens%3E%5D(%3Chttps://github.com/settings/tokens%3E)"&gt;link&lt;/a&gt; and generate a new token for the same&lt;/li&gt;
&lt;li&gt;Use this new token and give it to the extension&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this, you have the extension working on any of your repos! Voila ✨&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Link&lt;/strong&gt; - &lt;a href="https://bit.ly/2QV5b8D"&gt;https://bit.ly/2QV5b8D&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Personal Rating&lt;/strong&gt; - 3.5/5&lt;/p&gt;

&lt;p&gt;This is certainly a useful extension however I think it could be included with more amount of features. To include a few, according to my opinion:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide the starting date on which the first commit was made and the latest commit date to understand the period of the project&lt;/li&gt;
&lt;li&gt;When I am looking through the repo list of a user, it should show the total size info along with the number of stars and forks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  9. daily.dev
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://daily.dev/"&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%2Flxmycsnncohrt4dpijk3.png" alt="daily.dev website" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am going to say it one more time, I love reading blogs and articles that are interesting enough or closely related to the domains I love. I mostly use &lt;a href="http://dev.to"&gt;dev.to&lt;/a&gt; for finding out and reading software-related blogs but I also prefer reading technology-related and sometimes it's just hard to find the right blog for you. &lt;/p&gt;

&lt;p&gt;That's why I make use of this amazing extension. It has such a clean UI design and gives a library-like feeling and it's as if when I open the extension which furthers redirects to a new page makes it feel like those are tiny flashcards with interesting topics and I just want to read a few. I manage to read at least 2 blogs every morning varying domain-wise or just specifically related to open-source news or technology news. &lt;/p&gt;

&lt;p&gt;daily.dev is indeed the easiest way to stay updated on the latest programming news and I recommend it if you like reading. 🖖🏻&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Link -&lt;/strong&gt; &lt;a href="https://bit.ly/2QKDWNS"&gt;https://bit.ly/2QKDWNS&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Personal Rating&lt;/strong&gt; - 4.5/5&lt;/p&gt;

&lt;h2&gt;
  
  
  10.  Momentum
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://momentumdash.com/"&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%2Fi0ngbqvxx0ndb4ylrfos.png" alt="momentum website" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Momentum is a productivity extension tool and honestly, among productivity my second most favorite tool after ReaderMode. This extension takes into account the idea that inspiration and soothing images sets the user on a proper path (wanting to work!) and provides encouragement and will to work continuously and complete your to-dos. &lt;/p&gt;

&lt;p&gt;Apart from soothing images and quotes, the extension provides other features as well which includes: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Weather &amp;amp; forecast&lt;/li&gt;
&lt;li&gt;To-Dos - I love a soothing application that provides to-dos, gives me the feeling to work more!&lt;/li&gt;
&lt;li&gt;Search &amp;amp; Linking feature&lt;/li&gt;
&lt;li&gt;Option to add your widgets as well to the momentum webpage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Link&lt;/strong&gt; - &lt;a href="https://bit.ly/3sEIHqv"&gt;https://bit.ly/3sEIHqv&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Personal Rating&lt;/strong&gt; - 5/5 &lt;/p&gt;

&lt;p&gt;I am not much positive person but I also want to be motivated to work most of the time without being distracted and this extension helps plenty! ✨&lt;/p&gt;

&lt;p&gt;These 10 are my favorite extensions I love to make use of however there will be bonus +2 extensions as well! Those 2 are: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://chrome.google.com/webstore/detail/github-gloc/kaodcnpebhdbpaeeemkiobcokcnegdki/"&gt;Github Gloc&lt;/a&gt; - This extension creates a badge indicating the number of lines for each visible repository on Github for the user &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://chrome.google.com/webstore/detail/wakatime/jnbbnacmeggbgdjgaoojpmhdlkkpblgi"&gt;Wakatime&lt;/a&gt; - Tracks the amount of time I spend on applications such as VS Code, XCode, and chrome. It helps me keep track of the amount of time I spend on different projects &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I hope this was informative enough to understand the use case of each extension. Which one is your favorite extension and how is it useful for you? 🤔&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>developer</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Save your favorite dev.to posts offline!</title>
      <dc:creator>Aemie Jariwala</dc:creator>
      <pubDate>Fri, 22 Jan 2021 14:00:22 +0000</pubDate>
      <link>https://dev.to/devunf/save-your-favorite-dev-to-posts-offline-45nb</link>
      <guid>https://dev.to/devunf/save-your-favorite-dev-to-posts-offline-45nb</guid>
      <description>&lt;p&gt;&lt;em&gt;It takes too much time to copy-paste &amp;amp; then edit the blog I like on devto&lt;/em&gt;&lt;br&gt;
~ Me to Myself&lt;/p&gt;

&lt;p&gt;As a developer, I love reading plenty of blogs on &lt;a href="https://dev.to/"&gt;dev.to&lt;/a&gt; but prefer to save it on my machine. This has its perks which I will list down for you.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;When I read a blog, I want to edit some of the content as per my wish without affecting the original content on the same page itself. This edited content I prefer to save on my local machine so I can view it later. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When I have no network connection, I can read the blogs on my machine easily. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The best thing, this will be super &lt;strong&gt;productive&lt;/strong&gt; for you to save the content the way you like and read it when you want.&lt;/p&gt;

&lt;p&gt;To make you believe how useful and easy it's let's see the small demo before moving further: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi5yj331xdnjwlq52rrlj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fi5yj331xdnjwlq52rrlj.gif" alt="demo" width="600" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have pretty good knowledge of javascript and DOM. With that knowledge, I just came up with a method to go to the particular blog which I enjoyed reading and focus on editing the blog while removing other elements such as navbar, footer, and others.&lt;/p&gt;

&lt;p&gt;It's quite simple you just need to edit the CSS properties of the elements using DOM. You can certainly do this on your own as well however I have made that job easier for you by collecting all the tags within the HTML whose CSS properties we want to change!&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisities
&lt;/h2&gt;

&lt;p&gt;Just open your console in your favorite browser and simply copy-paste the javascript DOM code. It's this easy!&lt;/p&gt;
&lt;h2&gt;
  
  
  Let's remove the surrounding elements of the blog! ⚒️
&lt;/h2&gt;

&lt;p&gt;It's time to get to work, thus we will first remove the surrounding elements around the blog that you enjoyed reading and want to save on your machine! &lt;/p&gt;

&lt;p&gt;By surrounding elements, I mean user profile, navbar, footer, comment section, the moderator badge, and every other element which doesn't involve the contents of the blog.&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;tags&lt;/span&gt; &lt;span class="o"&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;header&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;div.crayons-article-actions&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;div.spec__tags&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;div.crayons-article__subheader&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;section#comments&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;section.crayons-card&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;aside.crayons-layout__sidebar-right&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;footer.crayons-footer&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;moderatorTag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.mod-actions-menu-btn&lt;/span&gt;&lt;span class="dl"&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;moderatorTag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;moderatorTag&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;These are the only list of tags that come under surrounding elements for the blog! Now after you have included this code in your console, just include 3 more lines to remove all of them!&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="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tag&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&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;Voila! All the surrounding elements have disappeared. 💨&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's edit the content as per our liking! ✍🏻
&lt;/h2&gt;

&lt;p&gt;This is the main part where you get the power to edit the content of the blog without affecting the original blog. In this, you just have to include one line in your console then you can edit the content on the page as you wish.&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contenteditable&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;true&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;h2&gt;
  
  
  Time to save the contents on our machine 💽
&lt;/h2&gt;

&lt;p&gt;After you've completed editing the blog content, you want to save it as a pdf on your local machine. We can do this with a simple &lt;code&gt;window.print()&lt;/code&gt; however this might clip off some content. &lt;/p&gt;

&lt;p&gt;We want to save our content in the most accurate way possible thus we got to edit further properties of the &lt;code&gt;body&lt;/code&gt; tag. For this, include in your console the 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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;border&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;padding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;static&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;margin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0px 5%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you've added this, you just got to add &lt;code&gt;window.print()&lt;/code&gt; &amp;amp; save it as a pdf on your local machine.&lt;/p&gt;

&lt;p&gt;One more query would arise that I have to always copy-paste the code and the answer to that is obviously a big NO! Just create a simple function as shown here, add it to your local storage as shown.&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;cleanAndEdit&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;tags&lt;/span&gt; &lt;span class="o"&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;header&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;div.crayons-article-actions&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;div.spec__tags&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;div.crayons-article__subheader&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;section#comments&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;section.crayons-card&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;aside.crayons-layout__sidebar-right&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;footer.crayons-footer&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;moderatorTag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.mod-actions-menu-btn&lt;/span&gt;&lt;span class="dl"&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;moderatorTag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;moderatorTag&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tag&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// editing content on the page&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contenteditable&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;true&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// for printing content accurately&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;border&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;padding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;static&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;margin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0px 5%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;editable-dev&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cleanAndEdit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you've done this within the console, you can re-use this function any time you want by doing as followed in the console:&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;func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;editable-dev&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;cleanAndEdit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, you can edit the content and save it with the method already discussed!&lt;/p&gt;

&lt;p&gt;I hope you enjoyed saving your most loved blog content on your machine based on your edits! You can refer to this code on &lt;a href="https://github.com/devunf/devto-clean-and-end"&gt;Github&lt;/a&gt; as well. Till then enjoy reading and continue learning. ✨&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>A simplified notion on Image Processing</title>
      <dc:creator>Aemie Jariwala</dc:creator>
      <pubDate>Thu, 21 Jan 2021 13:34:32 +0000</pubDate>
      <link>https://dev.to/devunf/getting-familiarized-with-image-processing-its-implementation-using-pil-2j9a</link>
      <guid>https://dev.to/devunf/getting-familiarized-with-image-processing-its-implementation-using-pil-2j9a</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;b&gt;Digital image processing&lt;/b&gt; is the use of a &lt;a href="https://en.wikipedia.org/wiki/Computer#Digital_computers" rel="noopener noreferrer"&gt;digital computer&lt;/a&gt; to process &lt;a href="https://en.wikipedia.org/wiki/Digital_image" rel="noopener noreferrer"&gt;digital images&lt;/a&gt; through an &lt;a href="https://en.wikipedia.org/wiki/Algorithm" rel="noopener noreferrer"&gt;algorithm&lt;/a&gt;.&lt;/em&gt; &lt;br&gt;
~ Definition right off the page from Wikipedia &lt;/p&gt;

&lt;p&gt;Let's begin by simplifying the understanding of &lt;strong&gt;Image Processing&lt;/strong&gt; and moving on further with Image algorithms and different processes followed by implementing them using the &lt;strong&gt;PIL&lt;/strong&gt; library (quite a popular package of Python!). &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%2Fi%2F0fp3kweid3a1xjx2yvoi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0fp3kweid3a1xjx2yvoi.gif" alt="excited"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;GIF Credits: Google&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Image processing&lt;/strong&gt; is just a simple way to look at a digital image, be it grey scaled or colored or any different mode and performing various operations/processes like image scaling/resizing, rotation, cropping and adjusting contrast, and many such familiar operations/processes.&lt;/p&gt;

&lt;h1&gt;
  
  
  🏃‍♀️ Table of Contents 🏃‍♂️
&lt;/h1&gt;

&lt;p&gt;Providing the entire content table so you're free to choose which topic you want to read! Enjoy reading. 😁&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Prerequistes&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;About the PIL&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Image Respresentation &amp;amp; its modes&lt;/em&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;PIL Implementation&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;em&gt;Image Processing Principles&lt;/em&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Nearest Neighbor&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Bilinear Interpolation&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Bicubic Interpolation&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Convolution Method&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;em&gt;Transformation with PIL&lt;/em&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Resizing Image&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Rotating Image&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  Before starting anything, do this!
&lt;/h2&gt;

&lt;p&gt;In this tutorial to perform different image processing on various images, we're using the PIL python library. Now certainly PIL is not just pre-installed on your machine. Thus we got to install &lt;strong&gt;python&lt;/strong&gt;, &lt;strong&gt;&lt;a href="https://pypi.org/project/pip/" rel="noopener noreferrer"&gt;pip&lt;/a&gt;&lt;/strong&gt; and last and the most important, &lt;strong&gt;PIL&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have &lt;a href=""&gt;anaconda&lt;/a&gt; installed on your machine, you don't have to do any of the steps mentioned below.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When you download &lt;a href="https://www.python.org/downloads/" rel="noopener noreferrer"&gt;python&lt;/a&gt;, PIP is installed along with it.  &lt;/p&gt;

&lt;p&gt;For installing PIL, we will install Pillow (Pillow is a maintained fork of PIL): &lt;/p&gt;

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

&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;Pillow


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

&lt;/div&gt;

&lt;p&gt;If you want to code side by side along with this blog, I would suggest doing the following in your terminal: &lt;/p&gt;

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

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;pil-image-processing &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;pil-image-processing
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;images


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

&lt;/div&gt;

&lt;p&gt;We will be writing the programs within the &lt;code&gt;pil-image-processing&lt;/code&gt; directory. You can use any code editor however I will make use of &lt;code&gt;vim&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Also, if you want to use the same images as I have in this blog, you can download the &lt;a href="https://github.com/devunf/pil-image-processing/blob/main/images/image.png" rel="noopener noreferrer"&gt;youtube icon&lt;/a&gt; and &lt;a href="https://github.com/devunf/pil-image-processing/blob/main/images/sunset.png" rel="noopener noreferrer"&gt;sunset picture&lt;/a&gt; and place them in your &lt;code&gt;images&lt;/code&gt; folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  PIL Library
&lt;/h2&gt;

&lt;p&gt;I will give a brief on what the PIL library is and what we'll cover with it.&lt;/p&gt;

&lt;p&gt;PIL library is quite a popular package provided by Python that handles all the image processing and functions that I mentioned earlier. It's in short called &lt;em&gt;Pillow&lt;/em&gt; also(I don't know why!). &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pillow is the “friendly” PIL fork by Alex Clark and Contributors.&lt;/em&gt; &lt;br&gt;
~ As mentioned in the &lt;a href="https://pypi.org/project/Pillow/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Image Representation &amp;amp; its modes
&lt;/h2&gt;

&lt;p&gt;Pixel is the smallest &amp;amp; the most important component of an image. A collection of pixels makes an image altogether. A pixel value always ranges from &lt;em&gt;0-255&lt;/em&gt;. &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%2Fi%2Fbdo2tzhjgw9pofythze0.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%2Fi%2Fbdo2tzhjgw9pofythze0.png" alt="pixel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Picture Credits: Google&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An image always has a width (w) and height (h) and can be understood by its comparison through a matrix with w rows and h columns. &lt;/p&gt;

&lt;p&gt;We'll move on a step further to understand the different modes of images. Earlier I mentioned an image can be represented through a matrix. A matrix is 2-dimensional and this single matrix forms a single &lt;strong&gt;channel of the image&lt;/strong&gt;. That's a new term alert! &lt;/p&gt;

&lt;p&gt;When we fill the matrix in the single-channel with values ranging from &lt;em&gt;0-255&lt;/em&gt;, it will form a &lt;strong&gt;greyscale image&lt;/strong&gt;. Great so now we reached a level where we created a greyscale image. Greyscale image size is simply represented with &lt;code&gt;width x height&lt;/code&gt; format.&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%2Fi%2F7wfdxsmh8zmvrvho2muh.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%2Fi%2F7wfdxsmh8zmvrvho2muh.png" alt="greyscale"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Picture Credits: Google&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's move on to form the colored digital images observed these days.&lt;/p&gt;

&lt;p&gt;For understanding the colored images, we'll go to legos. In legos, we build a tower by placing one lego over another. In this manner, each lego is like a single-channel. In RGB/colored images, we've 3 channels that are placed on top of each other to create a single image. &lt;/p&gt;

&lt;p&gt;In RGB, we have got the Red, Green, and Blue channels. Each of these channels is filled with values ranging from 0-255. Together, when these channels are together placed, we get a colored image. It's as simple as that theoretically. In practice, we know that an image has a width (w) represented as rows and height (h) represented as columns but in an RGB image, we also need to mention the channels (c). &lt;/p&gt;

&lt;p&gt;The RGB image size is represented as &lt;code&gt;width x height x channels&lt;/code&gt;.&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%2Fi%2F819su7ssi3af8io2nvnv.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%2Fi%2F819su7ssi3af8io2nvnv.png" alt="RGB"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Picture Credits: Google&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are various other modes apart from RGB &amp;amp; greyscale such as CYMK and RGBA (and so many others). &lt;/p&gt;

&lt;h4&gt;
  
  
  RGBA =&amp;gt; RGB + Alpha lchannel (handles opacity of the image)
&lt;/h4&gt;

&lt;h3&gt;
  
  
  PIL Implementation for different modes
&lt;/h3&gt;

&lt;p&gt;In PIL, there are several shortcodes for &lt;a href="https://pillow.readthedocs.io/en/latest/handbook/concepts.html#modes" rel="noopener noreferrer"&gt;modes&lt;/a&gt; in their documentation with which we will refer and perform simple operations. &lt;/p&gt;

&lt;h4&gt;
  
  
  1. Convert any image format to greyscale format
&lt;/h4&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;PIL&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/image.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;LA&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/greyscale.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now, this just converted our colored image to greyscale, damn! I will explain what this code does: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Import the &lt;code&gt;Image&lt;/code&gt; package from the PIL library to use the in-built functions.&lt;/li&gt;
&lt;li&gt;We open the image apply the &lt;strong&gt;LA&lt;/strong&gt; mode to convert to greyscale and assign it to the variable &lt;code&gt;img&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We save this new image by specifying the path.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;LA is not Los Angeles guys but a mode specified by PIL in their documentation. &lt;/p&gt;
&lt;/blockquote&gt;

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

L -  (8-bit pixels, black, and white)
LA (L with alpha)


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

&lt;/div&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%2Fi%2Fxs3re41fhv72vx07x83c.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%2Fi%2Fxs3re41fhv72vx07x83c.png" alt="result-1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Picture taken from Google, updated by myself&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  2. Splitting colored image to their respective channel
&lt;/h4&gt;

&lt;p&gt;Here, a colored image has 3 layers as mentioned before: Red, Green &amp;amp; Blue. What we'll do is extract each channel separately from the image and save those individual channels. Simple!!&lt;/p&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;PIL&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getdata&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


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

&lt;/div&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%2Fi%2F28gruvj96s1se2wbn7kt.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%2Fi%2F28gruvj96s1se2wbn7kt.png" alt="original"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Picture Credits: Google&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here, we open the image and assign it to variable img. After that, we're extracting the data of a colored image. We also mentioned before that a channel of an image is formed through a matrix that encompasses the pixel values ranging from 0-255. &lt;/p&gt;

&lt;p&gt;Now for one channel, we've one matrix filled with pixel values. But in a colored image, we've 3 channels (red, green &amp;amp; blue) so we've three matrixes filled with a pixel value. &lt;/p&gt;

&lt;p&gt;Again, a matrix is represented in a 2-D array with rows and columns. Now we've to include the values of 3 matrixes so we do it using a 3-D array and it comes in this format. &lt;/p&gt;

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

[[
  [r(0,0), g(0,0), b(0,0)], [r(0,1), g(0,1), b(0,1)]], 
  [[r(1,0), g(1,0), b(1,0)], [r(1,1), g(1,1), b(1,1)]
]] 


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

&lt;/div&gt;

&lt;p&gt;This format is better understood diagrammatically as shown:&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%2Fi%2Fxprae0j4h2tcs3jg5409.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%2Fi%2Fxprae0j4h2tcs3jg5409.png" alt="diagram-format"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thus, the data we extract from the image will be of the format: &lt;/p&gt;

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

[[[202 112 104]
 [202 112 104]
 [202 112 104]
 ...
 [200 111 105]
 [200 111 105]
 [199 110 104]]

 [[202 112 104]
 [202 112 104]
 [202 112 104]
 ...
 [200 111 103]
 [200 111 103]
 [199 110 102]]]


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

&lt;/div&gt;

&lt;p&gt;Let's use this data and split this data so we can get the r pixel values for the red channel, g pixel values for the green channel, and b pixel values for the blue channel.&lt;/p&gt;

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

&lt;span class="n"&gt;red&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="n"&gt;pixel&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pixel&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;green&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pixel&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pixel&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;blue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pixel&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pixel&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;As we have seen the data is of 3-D array format, thus let's focus on extracting only the red matrix for now. In the 3-D array, the internal array is of the format &lt;code&gt;[r, g, b]&lt;/code&gt; and we need to take the first value of this array to get the red pixel values. We do this similarly for creating the green matrix and blue matrix.&lt;/p&gt;

&lt;p&gt;Let's use these 3 matrixes and save them. We can then see the separate red, green, and blue channels of the original image.&lt;/p&gt;

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

&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;putdata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;red&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/red_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;putdata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/blue_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;putdata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;green&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/green_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Here, we use the &lt;code&gt;putdata()&lt;/code&gt; in-built function to copy the matrix content into the original image and then saving it.&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%2Fi%2Fxbfz5b3s9nhuwjgv2zsa.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%2Fi%2Fxbfz5b3s9nhuwjgv2zsa.png" alt="result-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Image Processing - Behind The Scene Principles
&lt;/h2&gt;

&lt;p&gt;For image processing techniques such as rescaling/resizing and rotation are formed based on principals of - nearest neighbor, bilinear transformation &amp;amp; other principles I will explain in detail.&lt;/p&gt;

&lt;p&gt;Let's start with the simplest principle and climb up with more complex ones. Just note that all these principles I will be explaining theoretically in the simplest form and not mathematically. &lt;/p&gt;

&lt;h3&gt;
  
  
  1. Nearest Neighbor Principle
&lt;/h3&gt;

&lt;p&gt;In this principle, we have an original image(A) and we apply an image processing technique to convert it to a modified image(B).&lt;/p&gt;

&lt;p&gt;I will explain this by resizing an image from A (3x3) to B (9x9). The first step to do is take the coordinates of the A image, multiple it by 3, then we will get a coordinate in the B image. This new coordinate of image B will have the same pixel value as the original coordinate in image A had.&lt;/p&gt;

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

A(0, 0) =&amp;gt; 110
A(0, 1) =&amp;gt; 120  
&amp;gt;&amp;gt;&amp;gt; x3 &amp;lt;&amp;lt;&amp;lt;
B(0, 0) =&amp;gt; 110
B(0, 3) =&amp;gt; 120 


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

&lt;/div&gt;

&lt;p&gt;Now, we need to find the pixel value B(0, 1), and to do that we do as followed: &lt;/p&gt;

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

B(0, 1) =&amp;gt; ? 
&amp;gt;&amp;gt;&amp;gt; /3 &amp;lt;&amp;lt;&amp;lt; 
A(0, 1/3) =&amp;gt; no such coordinate exists, right?


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

&lt;/div&gt;

&lt;p&gt;You're right no such coordinate exists but the nearest neighbor asks that is &lt;strong&gt;A(0, 1/3)&lt;/strong&gt; closer to &lt;strong&gt;A(0, 0)&lt;/strong&gt; or &lt;strong&gt;A(0, 1)&lt;/strong&gt;. Here, it is closer to &lt;strong&gt;A(0, 1)&lt;/strong&gt; thus the pixel value of &lt;strong&gt;B(0, 1)&lt;/strong&gt; will be the same as &lt;strong&gt;A(0, 0)&lt;/strong&gt;. Similarly, other coordinates are calculated as well! This is not so efficient, certainly!&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Bilinear Interpolation
&lt;/h3&gt;

&lt;p&gt;As you would have understood if we use the nearest neighbor principle to resize or rotate an image, it won't produce an accurate output and will be pixelated. Thus, we use another principle - Bilinear Transformation.&lt;/p&gt;

&lt;p&gt;Let's take the sample example of resizing an image A(3x3) to image B(9x9). &lt;/p&gt;

&lt;p&gt;Before we understand bilinear transformation, we need to understand linear transformation. We'll take the same example as we did in the nearest neighbor. So we need to find &lt;strong&gt;B(0, 1)&lt;/strong&gt; and the way we do it is found &lt;strong&gt;A(0, 1/3)&lt;/strong&gt; and the manner we do it is: &lt;/p&gt;

&lt;p&gt;We have the pixel value &lt;strong&gt;A(0, 0)&lt;/strong&gt; and &lt;strong&gt;A(0, 1)&lt;/strong&gt; so first we find &lt;code&gt;1/3 * value @ A(0, 1)&lt;/code&gt; and &lt;code&gt;2/3 * value @ A(0, 0)&lt;/code&gt;. Add those up and round it, you got the pixel value for &lt;strong&gt;A(0, 1/3)&lt;/strong&gt; and that's your value for &lt;strong&gt;B(0, 1)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We use this method to find any coordinate between 2 given coordinates. In bilinear, we make use of 4 consecutive coordinates in the original image A. With these coordinates, we calculate an ideal coordinate in image A and scale it to a coordinate in image B. &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%2Fi%2Foxl53kljkvx7xqyub33o.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%2Fi%2Foxl53kljkvx7xqyub33o.png" alt="bilinear"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We have pixel values of &lt;strong&gt;A(0, 0)&lt;/strong&gt;, &lt;strong&gt;A(0, 1)&lt;/strong&gt;,  &lt;strong&gt;A(1, 0)&lt;/strong&gt;, and &lt;strong&gt;A(1, 1)&lt;/strong&gt;. First, we find the coordinates of the square blocks between the 2 coordinates of image A using the linear interpolation method.&lt;/li&gt;
&lt;li&gt;With the coordinates of the 2 square blocks, we can interpolate and find the coordinate of the triangle block(the chosen one!). &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once we find the coordinate of the triangle block, we just map it to image B.&lt;/p&gt;

&lt;p&gt;So that's the basic idea of how bilinear works. In this manner, we can find any coordinate between 2 coordinates in our image B. With this principle, we can get much accurate pixel values and a smoother modified image. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. Bicubic Interpolation
&lt;/h2&gt;

&lt;p&gt;In bicubic interpolation, we make use of a cubic equation. However, as I have mentioned before we'll focus on the theoretical rather than the mathematical understanding of the principle. &lt;/p&gt;

&lt;p&gt;Let's look back at linear/bilinear interpolation to transform from image A to image B.&lt;/p&gt;

&lt;p&gt;The below diagram in the 2-D plane shows that b/w any 2 given coordinate is just a line and you can find any coordinate between those 2 using the linear interpolation method:&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%2Fi%2F4i0rdd4nvrquwnpepu7d.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%2Fi%2F4i0rdd4nvrquwnpepu7d.png" alt="deep-explanation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, this linear interpolation doesn't always provide a highly accurate or smooth result. Thus, we make use of bicubic. &lt;/p&gt;

&lt;p&gt;From this diagram, if I use the bicubic method, what it implies is if there are 2 given coordinates and there is the line joining those 2, then we will use the tangent/derivative at those 2 coordinates and make the curve and find any coordinate between those 2.&lt;/p&gt;

&lt;h3&gt;
  
  
  How are we calculating the derivatives at the coordinates?
&lt;/h3&gt;

&lt;p&gt;For calculating the tangent at those 2 given coordinates, we need the neighboring coordinates of those 2 as well! So easy, right? &lt;/p&gt;

&lt;p&gt;We use the linear interpolation method to calculate the ideal coordinate in bilinear interpolation using 4 coordinates.&lt;/p&gt;

&lt;p&gt;If we want to find the ideal coordinate between those 4 using bicubic, we'll need to use the extension as shown in the diagram. &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%2Fi%2Fp0k1s1rx6e4oamfgss13.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%2Fi%2Fp0k1s1rx6e4oamfgss13.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For bicubic, we'll do as followed: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For each row, we will find the coordinate (square blocks) between 2 given coordinates and we need to find the tangent at those 2 given coordinates using the neighbor of the given 2.&lt;/li&gt;
&lt;li&gt;Once the coordinates of the square blocks are calculated, we use the same method in 1 and get the ideal coordinate of the triangle block.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The coordinate of the triangle block is scaled to the coordinate in image B. This gives a much smoother transformation as compared to bicubic interpolation. &lt;/p&gt;

&lt;p&gt;Let's cover our last principle before we jump to implementation using PIL. &lt;/p&gt;

&lt;h2&gt;
  
  
  4. Convolution method
&lt;/h2&gt;

&lt;p&gt;This is an &lt;strong&gt;important&lt;/strong&gt; principle! It's important 'cause today principles like bi-cubic, bilinear is based upon the convolution principle itself.&lt;/p&gt;

&lt;p&gt;Let's begin by understanding convolution. In convolution let's say we have an image I(7x7) and what we'll do here is slide a kernel window K(3x3) over the image I such that we'll get a new image J(5x5) = I(7x7) * K(3x3)&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%2Fi%2F90ik1m65ww0no1qzi2gx.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%2Fi%2F90ik1m65ww0no1qzi2gx.png" alt="convolution"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Picture Credits: Google&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the diagram, we see that the kernel K slides over image I. &lt;br&gt;
Then when the kernel K is over a section of image I, it multiplies the pixel values of K and I and then adds them all up in the section, and we get a convoluted image pixel value. I know this sounds confusing so we'll understand this with an example. &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%2Fi%2Ffbefcneze73ehhw9q208.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%2Fi%2Ffbefcneze73ehhw9q208.png" alt="convolution"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In that image, we have a section of image I and we've our kernel K. From the diagram, it's understandable how the 9-pixel values result in a 1 convoluted pixel value. In this manner, we continue to slide the kernel K over the entire image I and get a convoluted image J (I * K). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is a heavy process, don't let anyone tell you different!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before moving further, I would like to clarify that these methods that I specified are used as filters to perform the transformation in images.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing transformation with a simple PIL
&lt;/h2&gt;

&lt;p&gt;According to the documentation of PIL: &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image resizing methods &lt;code&gt;resize()&lt;/code&gt; and &lt;code&gt;thumbnail()&lt;/code&gt; take a resample argument, which tells which filter should be used for resampling. Possible values are &lt;code&gt;PIL.Image.NEAREST&lt;/code&gt;, &lt;code&gt;PIL.Image.BILINEAR&lt;/code&gt;, &lt;code&gt;PIL.Image.BICUBIC&lt;/code&gt; and &lt;code&gt;PIL.Image.ANTIALIAS&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;~&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The upscaling performance of the LANCZOS filter has remained the same. For the BILINEAR filter, it has improved by 1.5 times and for BICUBIC by four times.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;From those 2 contexts from documentation, we know what Nearest, Bilinear, and Bicubic are, so that's cool! Now, what's Antialias and Lanczos? &lt;br&gt;
Antialias is a high-quality filter based on convolutions (we learned this!). Now Antilias filter is just an alias of Lanczos. So Lanczos and antialias are based on convolution.&lt;/p&gt;

&lt;p&gt;Let's implement resizing using these filters with PIL. &lt;/p&gt;

&lt;p&gt;In the documentation, for using the filters while resizing and rotation we can use their names explicitly or the number assigned for them.&lt;/p&gt;

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

NEAREST = NONE = 0
BILINEAR = LINEAR = 2
BICUBIC = CUBIC = 3
LANCZOS = ANTIALIAS = 1


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  1. Resizing an image using different filters
&lt;/h3&gt;

&lt;p&gt;We're going to re-use the &lt;a href="https://github.com/devunf/pil-image-processing/blob/main/images/sunset.png" rel="noopener noreferrer"&gt;sunset&lt;/a&gt; image that we did while splitting the image into different channels. Let's get coding!&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;PIL&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;350&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;550&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;nearest_resize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&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="n"&gt;lanczos_resize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&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="n"&gt;bilinear_resize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&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="n"&gt;bicubic_resize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&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="n"&gt;nearest_resize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/nearest_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;lanczos_resize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/lanczos_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bilinear_resize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/bilinear_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bicubic_resize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/bicubic_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 


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

&lt;/div&gt;

&lt;p&gt;Here, we're resizing the original image using different filters. With the current image, you may not be able to see much difference as shown. &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%2Fi%2Fwn4n1bi26pvyj5ug9mby.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%2Fi%2Fwn4n1bi26pvyj5ug9mby.png" alt="result-resize"&gt;&lt;/a&gt;&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%2Fi%2Fy4g5e60dopfcdzvse28j.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%2Fi%2Fy4g5e60dopfcdzvse28j.png" alt="result-resize-observable"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, this particular image provides a good difference between resizing between different filters. I would suggest looking at the filters that have been used by us in this blog and observe the difference.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Rotating an image using different filters
&lt;/h3&gt;

&lt;p&gt;We'll be using the filters to rotate an image by any degree we wish to. However, there is a problem when rotation happens to let's say 30 or 45 degrees, the edges get clipped off. If we don't want that we'll be setting &lt;code&gt;expand=true&lt;/code&gt; which will prevent that! &lt;/p&gt;

&lt;p&gt;In resizing, we used numbers to depict what kind of filter we want to use over the image while resizing. Here, we'll explicitly type their names out and again use the same &lt;a href="https://github.com/devunf/pil-image-processing/blob/main/images/sunset.png" rel="noopener noreferrer"&gt;sunset&lt;/a&gt; image. &lt;/p&gt;

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

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;PIL&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;nearest_rotate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resample&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NEAREST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bilinear_rotate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resample&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BILINEAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bicubic_rotate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resample&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BICUBIC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;nearest_rotate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/nearest_rotate_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bilinear_rotate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/bilinear_rotate_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bicubic_rotate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;images/bicubic_rotate_sunset.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 


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

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Here, the &lt;strong&gt;Lanczos&lt;/strong&gt; filter can't be used for rotation as it is not implemented by PIL itself and quite a heavy process so doesn't hold any advantage over &lt;strong&gt;bicubic&lt;/strong&gt; for now.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;PIL is not limited to just resizing, rotation, splitting images but it can do so much more. Everything you perform on photo editing tools such as crop, copy-pasting, merging 2 images can be achieved through PIL just through few lines of code. In this, I have only used the &lt;code&gt;Image&lt;/code&gt; module but there are many modules for PIL itself.&lt;/p&gt;

&lt;p&gt;For any additional resources for PIL, just look through their &lt;a href="https://pillow.readthedocs.io/en/stable/reference/index.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;, and certainly if stuck, stack overflow always provides every answer. PIL is an effective library and I have covered the 2 most commonly used operations and the principles that reside behind the transformation.&lt;/p&gt;

&lt;p&gt;The sources for each code is present on &lt;a href="https://github.com/devunf/pil-image-processing" rel="noopener noreferrer"&gt;Github&lt;/a&gt; as well, so you can refer from there and code side by side too! &lt;/p&gt;

&lt;p&gt;If any questions arise regarding PIL or anything mentioned in the article, feel free to mention it in the comments! Till then, goodbye. 👋 &lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Nginx concepts I wish I knew years ago</title>
      <dc:creator>Aemie Jariwala</dc:creator>
      <pubDate>Mon, 11 Jan 2021 13:58:03 +0000</pubDate>
      <link>https://dev.to/aemiej/nginx-concepts-i-wish-i-knew-years-ago-23o0</link>
      <guid>https://dev.to/aemiej/nginx-concepts-i-wish-i-knew-years-ago-23o0</guid>
      <description>&lt;p&gt;&lt;em&gt;Nginx is a web server that is used as a reverse proxy, load balancer, mail proxy, and HTTP cache and follows the Master-Slave Architecture.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Woah! A complicated term and a confusing definition filled with big confusing words, right? Don't worry, I can help out with first understanding the basic barebones of the architectures &amp;amp; terms in Nginx. Then we'll move on to installing and creating &lt;strong&gt;Nginx&lt;/strong&gt; configurations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffbj8exwkli91ord2xscz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffbj8exwkli91ord2xscz.gif" alt="Confused" width="358" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To keep things easy, just remember: &lt;em&gt;Nginx is an amazing web server&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Web server, in simple terms, is like a middleman. Let's say for instance you want to go to dev.to so you type the address &lt;code&gt;https://dev.to&lt;/code&gt;, your browser finds out the address of a webserver for &lt;code&gt;https://dev.to&lt;/code&gt; and then direct it to a backend server which will give back the response to the client.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proxy v/s Reverse Proxy
&lt;/h3&gt;

&lt;p&gt;The underlying feature of Nginx is proxies. So it's required to understand what is proxy and reverse proxy now.&lt;/p&gt;

&lt;h4&gt;
  
  
  Proxy
&lt;/h4&gt;

&lt;p&gt;Alright, so we have clients (&amp;gt;= 1), an intermediate web server(in this case, we call it proxy), and a server. The main thing that happens in this is that the server doesn't know which client is requesting. Bit confusing? Let me explain with a diagrammatic sketch. &lt;/p&gt;

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

&lt;p&gt;In this, let client1  &amp;amp; client2 send requests request1 &amp;amp; request2 to the server through the Proxy server. Now the backend server will not know whether request1 is sent by client1 or client2 but performs the operation. &lt;/p&gt;

&lt;h4&gt;
  
  
  Reverse Proxy
&lt;/h4&gt;

&lt;p&gt;In simplest terms, a reverse proxy is a reverse of what a proxy does. Here, we will have let's say a single client, an intermediate web server, and several backend servers (&amp;gt;=1). Let's do this with a diagrammatic sketch as well!&lt;/p&gt;

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

&lt;p&gt;In this, a client will send a request through the webserver. Now the webserver will direct to any of the many servers through an algorithm, one being round-robin (the cutest one!), and send back the response through the webserver to the client. So here, the client isn't aware which backend server it is interacting with.&lt;/p&gt;

&lt;h3&gt;
  
  
  Load Balancing
&lt;/h3&gt;

&lt;p&gt;Damn another new term but this term is simpler to understand as it is one instance application of &lt;strong&gt;reverse proxy&lt;/strong&gt; itself.&lt;/p&gt;

&lt;p&gt;Let's go with the basic difference. In load balancing, you must have 2 or more backend servers but in reverse proxy setup, that's not a necessity. It can work with even 1 backend server.&lt;/p&gt;

&lt;p&gt;Let's look at it from behind the scene, if we have a lot of requests from the clients this load balancer checks the status of each backend server and distributes the load of the requests, and sends a response faster to the client.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stateful v/s Stateless Applications
&lt;/h3&gt;

&lt;p&gt;Okay, guys, I promise I am real close to starting with the Nginx code. Let's get all the barebones clear! &lt;/p&gt;

&lt;h4&gt;
  
  
  Stateful Applications
&lt;/h4&gt;

&lt;p&gt;This application store an additional variable for saving the information that can work for a single instance of a server only. &lt;/p&gt;

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

&lt;p&gt;What I mean is if for a backend server &lt;em&gt;server1&lt;/em&gt; some information is stored it won't be stored for the server &lt;em&gt;server2&lt;/em&gt; thus the client (here Bob) interacting may/may not get the desired result as it could be interacting with server1 or server2. In this case, server1 will allow Bob to view the profile but server2 won't. Thus, even if it prevents many API calls with the database and is faster, it can lead to this problem across different servers.&lt;/p&gt;

&lt;h4&gt;
  
  
  Stateless Applications
&lt;/h4&gt;

&lt;p&gt;Now stateless is more API calls with the database but fewer problems exist when it comes to the interaction of the client with different backend servers. &lt;/p&gt;

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

&lt;p&gt;I know you didn't get what I mean. It's simple if I send a request from a client to let's say backend server &lt;em&gt;server1&lt;/em&gt; through web server it will provide a token back to the client to use to access any further requests. The client can use the token and send a request to the webserver. This web server will send the request along with the token to any of the backend servers and each will provide the same desired output.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Nginx?
&lt;/h3&gt;

&lt;p&gt;Nginx is the web server and I have been using the term web server in the entire blog till now. It's like a &lt;strong&gt;middleman&lt;/strong&gt; honestly. &lt;/p&gt;

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

&lt;p&gt;The diagram isn't confusing, it's just a combination of all the concepts I have explained till now. In this, we have 3 backend servers running at port 3001, 3002, 3003 and all these backend servers use the same database running at port 5432. &lt;/p&gt;

&lt;p&gt;Now when a client sends a requests &lt;code&gt;GET /employees&lt;/code&gt; on &lt;code&gt;https://localhost&lt;/code&gt; (by default on port 443), it will pass this requests to any of the backend server based on the algorithm and take the information from the database and send the JSON back to the Nginx web server and sent back to the client. &lt;/p&gt;

&lt;p&gt;If we're to use an algorithm such as &lt;strong&gt;round-robin&lt;/strong&gt;, what it'll do is let's say client 2 has sent a request to &lt;code&gt;https://localhost&lt;/code&gt; then the Nginx server will pass the request first to port 3000 and send the response back to the client. For another request, Nginx will pass the request to 3002 and so on. &lt;/p&gt;

&lt;p&gt;Too much information right! But by this point, you have a clear understanding of what Nginx is and the terms used with Nginx. Now we'll move on the understanding the installation and configuration techniques.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation Process
&lt;/h3&gt;

&lt;p&gt;We're here at last! I am so proud if you've understood the concept to reach the coding part of Nginx at last. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4mju73ad1f22gy1ni3gu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4mju73ad1f22gy1ni3gu.gif" alt="proud" width="434" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, let me just tell you the installation process is super duper easy on any system just one-liner honestly. I am a Mac OSX user, so will be writing the commands based on it. But it will be done similarly for &lt;a href="https://ubuntu.com/tutorials/install-and-configure-nginx#2-installing-nginx"&gt;ubuntu&lt;/a&gt; and &lt;a href="https://www.maketecheasier.com/install-nginx-server-windows/"&gt;windows&lt;/a&gt; and other Linux distros.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;Nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is only required and you have Nginx on your system now! Amazing I am sure! &lt;/p&gt;

&lt;h4&gt;
  
  
  So easy to run! 😛
&lt;/h4&gt;

&lt;p&gt;To run this and check if Nginx is working on your system, it's again way too simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;nginx 
&lt;span class="c"&gt;# OR &lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, go on your favorite browser and check out &lt;code&gt;http://localhost:8080/&lt;/code&gt; and you'll get the below-observed screen!&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Basic Configuration Setup &amp;amp; Example
&lt;/h3&gt;

&lt;p&gt;Okay, we will be doing an example and seeing the magic of Nginx. &lt;br&gt;
First, create the directory structure in the local machine as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
├── nginx-demo
│  ├── content
│  │  ├── first.txt
│  │  ├── index.html
│  │  └── index.md
│  └── main
│    └── index.html
└── temp-nginx
  └── outsider
    └── index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, include basic context within the &lt;strong&gt;html&lt;/strong&gt; and &lt;strong&gt;md&lt;/strong&gt; files.&lt;/p&gt;

&lt;h4&gt;
  
  
  What we're trying to achieve?
&lt;/h4&gt;

&lt;p&gt;Here, we have two separate folders &lt;code&gt;nginx-demo&lt;/code&gt; and &lt;code&gt;temp-nginx&lt;/code&gt;, each containing static HTML files. We're going to focus on running both these folders on a common port and set rules that we like. &lt;/p&gt;

&lt;p&gt;Coming back on track now. For making any changes to the Nginx default configuration, we will make a change in the &lt;code&gt;nginx.conf&lt;/code&gt; that is located in the &lt;code&gt;usr/local/etc/nginx&lt;/code&gt; path. Also, I have vim in my system so I make changes using vim but you're free to use your editor of choice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/local/etc/nginx
&lt;span class="nv"&gt;$ &lt;/span&gt;vim nginx.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will open a file with the default nginx configuration which I really don't want to use. Thus, the way I normally do is make a copy of this configuration file and then make changes to the main file. We'll be doing the same as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cp &lt;/span&gt;nginx.conf copy-nginx.conf
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;rm &lt;/span&gt;nginx.conf &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; vim nginx.conf 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will now open an empty file and we'll be adding our configuration for it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add a basic setup of configuration. It is a must requirement to add the &lt;code&gt;events {}&lt;/code&gt; as it is generally used to mention the number of workers for Nginx architecture. We are using &lt;code&gt;http&lt;/code&gt; here to tell Nginx that we'll be working at layer 7 of the &lt;a href="https://bit.ly/2LGdbYB"&gt;OSI model&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this, we've told nginx to listen on port 5000 and to point to the static file mentioned within the main folder.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;  &lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

     &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/path/to/nginx-demo/main/&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;events&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We'll add additional rules next for the &lt;code&gt;/content&lt;/code&gt; and &lt;code&gt;/outsider&lt;/code&gt; URL where &lt;strong&gt;outsider&lt;/strong&gt; will be pointing to a directory outside the root directory mentioned in the 1st step. &lt;/p&gt;

&lt;p&gt;Here &lt;code&gt;location /content&lt;/code&gt; signifies that whichever root I define in the leaf directory for this, the &lt;strong&gt;content&lt;/strong&gt; sub URL will be added to the end of the root URL defined.  Thus, here when I specify root as &lt;code&gt;root /path/to/nginx-demo/&lt;/code&gt; it simply means that I am telling Nginx at &lt;code&gt;http://localhost:5000/path/to/nginx-demo/content/&lt;/code&gt; show me the content of the static files within the folder.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;  &lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/path/to/nginx-demo/main/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/path/to/nginx-demo/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;   

        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/outsider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/path/temp-nginx/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;events&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;blockquote&gt;
&lt;p&gt;Pretty cool! Now Nginx is not only limited to defining URL roots but also to set rules such that I can block the client from accessing certain files. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We're going to write an additional rule within our main server defined to block any &lt;strong&gt;.md&lt;/strong&gt; files from being accessed. We can use regex in Nginx so we'll define the rule as follows:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;   &lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt; &lt;span class="sr"&gt;.md&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;403&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;/li&gt;
&lt;li&gt;
&lt;p&gt;Let's end this by learning the popular command &lt;code&gt;proxy_pass&lt;/code&gt;. Now we've learned what a proxy and reverse proxy is so here we'll begin by defining another backend server running at port 8888. So now we've got 2 backend servers running at port 5000 and 8888. &lt;/p&gt;

&lt;p&gt;What we'll do is that when the client accesses port 8888 through Nginx we'll pass this request to port 5000 &amp;amp; send the response back to the client!&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;   &lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;8888&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

       &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://localhost:5000/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;

       &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://localhost:5000/outsider/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Let's see the final complete code altogether! 😁
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;   &lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/path/to/nginx-demo/main/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

            &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/path/to/nginx-demo/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;   

            &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/outsider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/path/temp-nginx/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

                    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt; &lt;span class="sr"&gt;.md&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;403&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="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;8888&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

           &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://localhost:5000/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
           &lt;span class="p"&gt;}&lt;/span&gt;

           &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://localhost:5000/outsider/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
           &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;events&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this code using &lt;code&gt;sudo nginx&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extra Nginx Commands!
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;To start an Nginx web server for the first time.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nv"&gt;$ &lt;/span&gt;nginx 
  &lt;span class="c"&gt;#OR &lt;/span&gt;
  &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To reload a running Nginx web server.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nv"&gt;$ &lt;/span&gt;nginx &lt;span class="nt"&gt;-s&lt;/span&gt; reload
  &lt;span class="c"&gt;#OR &lt;/span&gt;
  &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nginx &lt;span class="nt"&gt;-s&lt;/span&gt; reload
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To stop a running Nginx web server.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nv"&gt;$ &lt;/span&gt;nginx &lt;span class="nt"&gt;-s&lt;/span&gt; stop
  &lt;span class="c"&gt;#OR &lt;/span&gt;
  &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nginx &lt;span class="nt"&gt;-s&lt;/span&gt; stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To know which processes of Nginx are running on your system.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nv"&gt;$ &lt;/span&gt;ps &lt;span class="nt"&gt;-ef&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;Nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The 4th command is important when by any chance the first 3 commands lead to some error, what you can normally do is find all running Nginx processes using the 4th command and kill the processes, and start it again.&lt;/p&gt;

&lt;p&gt;To kill a process, you need the PID and then kill it using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nt"&gt;-9&lt;/span&gt; &amp;lt;PID&amp;gt;
&lt;span class="c"&gt;#OR &lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo kill&lt;/span&gt; &lt;span class="nt"&gt;-9&lt;/span&gt; &amp;lt;PID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before ending this post, I've used diagrams and visuals from google images and couple of youtube tutorials by &lt;a href="https://www.youtube.com/user/GISIGeometry"&gt;Hussein Nasser&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We've come to an end with the basic understanding of Nginx and its configuration. If you're interested in the advanced configuration of Nginx, do let me know through comments. Till then enjoy coding and explore the magic of Nginx! 👋&lt;/p&gt;

</description>
      <category>nginx</category>
      <category>tutorial</category>
      <category>systems</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Dockerizing my way through graphics</title>
      <dc:creator>Aemie Jariwala</dc:creator>
      <pubDate>Tue, 05 Jan 2021 17:58:08 +0000</pubDate>
      <link>https://dev.to/aemiej/dockerizing-my-way-through-graphics-3hoo</link>
      <guid>https://dev.to/aemiej/dockerizing-my-way-through-graphics-3hoo</guid>
      <description>&lt;p&gt;&lt;em&gt;Docker is hard and so weird and complicated and doesn't have plenty of resources to learn from even!&lt;/em&gt; ~ my very first thoughts when I wanted to step into the Docker world to try something new. &lt;/p&gt;

&lt;p&gt;Now, &lt;strong&gt;Docker&lt;/strong&gt; seems like a complicated term and makes you wonder, where and why, and what should I even use Docker for ?! I am not going to answer all these questions, these are the beginner steps for which I landed across an amazing video on youtube and I will be putting the link for the same as well.&lt;/p&gt;

&lt;p&gt;Best Docker 101 (60 min) video - &lt;a href="https://bit.ly/3bfhh4v"&gt;https://bit.ly/3bfhh4v&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftgo1b4dg4ldlnjisp8aj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftgo1b4dg4ldlnjisp8aj.gif" alt="thinking" width="448" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What am I going to cover in this blog?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fizodvcrc75pcvj3d53hc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fizodvcrc75pcvj3d53hc.png" alt="docker" width="800" height="205"&gt;&lt;/a&gt;&lt;br&gt;
I will explain in layman's terms or try my best. Docker is great when it comes to dealing with building images, running them as containers, and managing the virtual packages/services created but what if I want to run a program that requires the use of GUI? In normal cases, it will run the docker image but in the terminal and that gives an undesired output! So the blog aims to connect the docker image with a GUI.&lt;/p&gt;
&lt;h2&gt;
  
  
  From where did I land on this topic? 😅
&lt;/h2&gt;

&lt;p&gt;This is going to sound silly but just going to give a tiny background story on how I landed on the topic. Well, being an undergrad at NIT Surat, currently reached my 6th semester (phew!), we have a subject &lt;strong&gt;Computer Graphics&lt;/strong&gt; for which they required us to use an outdated library that only worked on ubuntu and using code blocks (out of the question even) on Windows. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgw7jovh3vzuxjfo36gll.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgw7jovh3vzuxjfo36gll.gif" alt="college stuff" width="245" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the only OS I've are Fedora, Mac OSX, and Windows and I am neither going to install Ubuntu nor use code blocks just for this. So my only left choices were using a ubuntu docker image or using a VM. I felt to make use of docker image as it seemed a better alternative use to avoid heat load up and slowing down my CPU. Now, this is all new to me, docker and such but still managed to connect my docker image with GUI and figured out it can be done for any docker images. For now, I could do a successful setup for only &lt;strong&gt;Mac OSX&lt;/strong&gt; and &lt;strong&gt;Linux Distros&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Enough of storytelling, let's get on track with how to connect Docker Images with GUI.&lt;/p&gt;
&lt;h2&gt;
  
  
  Connecting libgraph with GUI using the ubuntu docker image
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Libgraph&lt;/strong&gt; is an implementation of the TurboC graphics API (graphics. h) on GNU/Linux using SDL. Let me warn you, this is quite old! It was hard to find working solutions on the net for this 🙁&lt;/p&gt;

&lt;p&gt;I have created a docker image named &lt;a href="https://hub.docker.com/repository/docker/aemiej/compgraphics"&gt;compgraphics&lt;/a&gt; and pushed it to the docker hub which encompasses all the initial setup to install &lt;code&gt;sudo&lt;/code&gt; and &lt;code&gt;libgraph&lt;/code&gt; on your system. &lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Create a docker file to use one of the C files to produce the image
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM aemiej/compgraphics:latest 

LABEL maintainer="Aemie Jariwala"

WORKDIR "/libgraph-1.0.2"

RUN gcc -o sample sample.c -lgraph

CMD ["./sample"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 2: Specifically for MAC OSX Users
&lt;/h3&gt;

&lt;p&gt;For Mac, you require additional applications for the GUI to work. They are &lt;code&gt;socat&lt;/code&gt; and &lt;code&gt;Xquartz&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ brew install socat
$ brew install xquartz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Remember to restart your PC after this, it's a must else it won't work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Open two terminals, where on one your socat will continue to run and others you will containerize your docker images.&lt;/p&gt;

&lt;p&gt;Socat allows for bidirectional data transfers from one location to another. It listens to the docker image running and then displays the image in Xquartz, a GUI application&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Terminal 1&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Terminal 2&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ open -a Xquartz # within preferences =&amp;gt; security, tick both checkboxes 

$ git clone https://github.com/AemieJ/ubuntu-docker-libgraph.git

$ cd ubuntu-docker-libgraph

$ docker build --pull --rm -f "Dockerfile" -t ubuntudockerlibgraph:latest "."

$ docker run -d -e DISPLAY=192.168.1.11:0 ubuntudockerlibgraph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;DISPLAY=192.168.1.11&lt;/code&gt; will vary for each user and can be found from &lt;code&gt;ifconfig en0&lt;/code&gt; &amp;amp; you'll get &lt;code&gt;inet X netmask&lt;/code&gt; similar to this where X address will replace the value with DISPLAY key. &lt;/p&gt;

&lt;p&gt;After this, an application will open with the output (pretty cute!). &lt;/p&gt;

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

&lt;p&gt;Similar to this, you can run any docker images that are pre-built such as firefox, chrome, Spotify, Skype, and just way too many 👻. All these images can be found from the git repository - &lt;a href="https://github.com/jessfraz/dockerfiles"&gt;https://github.com/jessfraz/dockerfiles&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tiny example on how to open Spotify GUI using docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run -d -e DISPLAY=192.168.1.11:0 jess/spotify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Similarly, you can do the same for other images as well!&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Specifically for any Linux Distro
&lt;/h3&gt;

&lt;p&gt;The steps for this are relatively easier than for Mac OSX. The requirement of a single terminal and an additional package only required to be installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/AemieJ/ubuntu-docker-libgraph.git
$ cd ubuntu-docker-libgraph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the &lt;strong&gt;Dockerfile&lt;/strong&gt; by adding &lt;code&gt;EXPOSE 8887&lt;/code&gt; before the &lt;code&gt;CMD ["./sample"]&lt;/code&gt; line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo docker build --name ubuntudockerlibgraph --pull --rm -f "Dockerfile" -t ubuntudockerlibgraph:latest "."
$ sudo apt-get -y install xauth
$ xauth list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On running &lt;code&gt;xauth list&lt;/code&gt;, you get an output of the following &lt;code&gt;username/unix:0 MIT-MAGIC-COOKIE-1 8fe8efc75454dbf178bbe00442689406&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo docker run -ti --net=host -e DISPLAY -v /tmp/.X11-unix ubuntudockerlibgraph bash
$ xauth add username/unix:0 MIT-MAGIC-COOKIE-1 8fe8efc75454dbf178bbe00442689406
# you'll receive an error =&amp;gt; `./Xauthority file doesn't exist` =&amp;gt; disregard it
$ /sample
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Damn! We're done with the instructions for the Linux distros as well. 😄&lt;br&gt;
The output of this will be the same as shown within the instructions of dockerizing through graphics in Mac OSX.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F73qhrndrhavlbgmb1uf9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F73qhrndrhavlbgmb1uf9.jpg" alt="end" width="551" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the end of this long article but I hope you found it useful and continue to dockerize your way through everything!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>writing</category>
      <category>linux</category>
      <category>devops</category>
    </item>
    <item>
      <title>The Best Web Development Courses</title>
      <dc:creator>Aemie Jariwala</dc:creator>
      <pubDate>Wed, 30 Dec 2020 08:59:54 +0000</pubDate>
      <link>https://dev.to/aemiej/the-best-web-development-courses-3hgm</link>
      <guid>https://dev.to/aemiej/the-best-web-development-courses-3hgm</guid>
      <description>&lt;p&gt;When you want to develop a new website,  you need to make sure of the frameworks you'll use for making the front-end and back-end of the application. The requirement for making a choice is based on knowledge of the frameworks and implementing them accurately. &lt;/p&gt;

&lt;p&gt;Let's begin this blog with a brief on the importance of web development. &lt;/p&gt;

&lt;h2&gt;
  
  
  Importance of Web Development for a developer
&lt;/h2&gt;

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

&lt;p&gt;All the applications, developed to date began with a train of thoughts and logic. The logic could be incorporated within the application directly through lines of codes. However, this application is understandable by the respective developers themselves but not the users. Hence, to make it a flexible application for everyone, the concept of user interface crawls in. So the equation for creating a web development is simple. &lt;/p&gt;

&lt;h4&gt;
  
  
  USER INTERFACE + FRAMEWORKS = FRONT-END
&lt;/h4&gt;

&lt;h4&gt;
  
  
  LOGIC + FRAMEWORKS = BACK-END
&lt;/h4&gt;

&lt;h4&gt;
  
  
  FRONT-END + BACK-END = WEB APPLICATION
&lt;/h4&gt;

&lt;p&gt;Now the basic understanding of web development is done hence let's move forward with the courses that I went through to familiarize myself with web development.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Corey Schafer Flask &amp;amp; Django Tutorial
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgfgmocstngj7swf09626.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgfgmocstngj7swf09626.png" alt="Django + Flask" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My first baby steps into the web development portal were to start with the back-end frameworks to incorporate the business/app logic. In the beginning, I had a real good grip with the python language and thus I decided to learn &lt;strong&gt;Flask&lt;/strong&gt; and &lt;strong&gt;Django&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8sqexx5rl1xo92rsszqw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8sqexx5rl1xo92rsszqw.gif" alt="Baby steps" width="344" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Certainly, I went through plenty of tutorials on youtube before I could end up on real good and satisfying one and it was the playlist by &lt;strong&gt;Corey Schafer&lt;/strong&gt;. In this playlist for both flask and Django, he takes on by creating a project using both the frameworks step by step and in the end, he also explains the deployment of this web application using Linode, etc.&lt;/p&gt;

&lt;p&gt;In my opinion, I will suggest first learn flask and then Django. The reason being that the flask is easier to get a grip on and can be used to create a simple application. After you're done creating a project using this playlist, I suggest you try to create another project of your own to get familiarized.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Playlist link for Flask - &lt;a href="https://bit.ly/3rAXy54"&gt;https://bit.ly/3rAXy54&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Playlist link for Django - &lt;a href="https://bit.ly/34V5kNt"&gt;https://bit.ly/34V5kNt&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Javascript Web Frameworks &amp;amp; Libraries
&lt;/h2&gt;

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

&lt;p&gt;Frankly, after I learned flask &amp;amp; Django, I became confident in using them however it didn't seem easy to configure with front-end libraries like &lt;strong&gt;ReactJs&lt;/strong&gt;. So I decided to learn a new back-end framework &lt;strong&gt;Node &amp;amp; ExpressJS&lt;/strong&gt;. It seemed much easier to integrate with the front-end but I had to decide on a different database such as MySQL or NoSQL (the cliche). In the beginning, I learned NodeJS with MongoDB (NoSQL database) through documentation and a video by &lt;strong&gt;Derek Banas&lt;/strong&gt; on youtube.&lt;/p&gt;

&lt;p&gt;After this, I moved on to using &lt;strong&gt;firebase&lt;/strong&gt; with &lt;strong&gt;Node&lt;/strong&gt; due to its easy use and integration. For this, I made no use of any video but solely dependent on the documentation and stack overflow for any queries. The documentation for firebase is well explained and doesn't require any external videos for understanding. &lt;/p&gt;

&lt;p&gt;Let's move on to &lt;strong&gt;ReactJS&lt;/strong&gt; and &lt;strong&gt;Redux&lt;/strong&gt;. ReactJS is a front-end library that provides beautiful UI components. It doesn't use as much space as AngularJS and it provides extensive features. Redux is the state management used in the front-end along with ReactJS. To learn the beginner course on React and Redux, I went through &lt;strong&gt;Mosh Hamedani's video&lt;/strong&gt; and, for further understanding, I went through the documentation and created personal projects.  I haven't done a course on AngularJS yet so can't give my opinion on it (sorry about that, you can provide your source if any in the comments).&lt;/p&gt;

&lt;p&gt;The recent course I did was on &lt;strong&gt;Typescript&lt;/strong&gt;, an udemy course I found. &lt;strong&gt;Deno&lt;/strong&gt; is known to replace Node however I haven't explored that yet as well so on exploration, I can provide further suggestions/courses on it in the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  The youtube &amp;amp; documentation links to start with!
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;NodeJS With MongoDB - &lt;a href="https://bit.ly/38GMydM"&gt;https://bit.ly/38GMydM&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;NodeJS With MySQL - &lt;a href="https://www.mysqltutorial.org/mysql-nodejs/"&gt;https://www.mysqltutorial.org/mysql-nodejs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;NodeJS With Firebase &amp;amp; Firestore - &lt;a href="https://bit.ly/3hpZHvQ"&gt;https://bit.ly/3hpZHvQ&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ReactJS - &lt;a href="https://bit.ly/3pxAiDd"&gt;https://bit.ly/3pxAiDd&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Redux - &lt;a href="https://bit.ly/2JuO765"&gt;https://bit.ly/2JuO765&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Understanding Typescript - &lt;a href="https://bit.ly/3aSz4hD"&gt;https://bit.ly/3aSz4hD&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On an ending note, if any additional course suggestion is required, please ask so. For now, ending this long blog and hope you enjoyed reading it and it was useful to you! &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>javascript</category>
      <category>django</category>
    </item>
    <item>
      <title>Sound-Muter extension</title>
      <dc:creator>Aemie Jariwala</dc:creator>
      <pubDate>Mon, 07 Sep 2020 14:21:37 +0000</pubDate>
      <link>https://dev.to/aemiej/noise-canceling-extension-52fd</link>
      <guid>https://dev.to/aemiej/noise-canceling-extension-52fd</guid>
      <description>&lt;h2&gt;
  
  
  The need.
&lt;/h2&gt;

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

&lt;p&gt;Let me describe the need for this through an instance. Let's say you've multiple events to attend through online mode and these have collided at the same time. You've to focus on prioritizing one but be present for each. What will you do now? The answer is pretty simple for the particular timestamp mute one tab while listening to the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  The birth of the idea.
&lt;/h2&gt;

&lt;p&gt;Well, with the hopes that I could concentrate on my development while attending online classes. A few classes are uninteresting for me and I want to explore a development topic at the same time. So I would mute the Google meet tab and focus on hearing the other YouTube videos.&lt;/p&gt;

&lt;h2&gt;
  
  
  The usage of the browser extension.
&lt;/h2&gt;

&lt;p&gt;An extension is easily accessible and it continues to run within the background and keep track of the tabs that have been selected to toggle with the extension. There was no usage of any external database just simple communication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code time. Best time.
&lt;/h2&gt;

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

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;The knowledge of basic components required within a chrome extension is required. Please read the docs to get the basic idea for the code I am going to show you. &lt;/p&gt;

&lt;h3&gt;
  
  
  manifest.json
&lt;/h3&gt;

&lt;p&gt;This file, in simple words, is responsible for stating the rules for the chrome extension you'll add to the browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "name": "Mute Tab &amp;amp; Record",
    "version": "1.0",
    "description": "Mute individual tabs, keep the record of tabs and also availability to record the audio from the particular tab",
    "permissions": ["cookies", "contextMenus", "storage", "declarativeContent", "activeTab", "tabs"],
    "browser_action": {},
    "background": {
        "scripts": ["src/background.js"],
        "persistent": false
    },
    "content_scripts": [{
        "matches": [
          "https://*/*",
          "http://*/*"
        ],
        "js": ["src/content.js"],
        "run_at": "document_end"
      }],
      "icons": {
        "16": "icons/volume.png",
        "48": "icons/volume.png",
        "128": "icons/volume.png"

      },
    "manifest_version": 2
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Backbone of the code - background &amp;amp; content
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;background&lt;/strong&gt; is the script that will run as long as the extension is enabled and each time you're using the browser.&lt;/p&gt;

&lt;p&gt;While the &lt;strong&gt;content&lt;/strong&gt;  is the script that only allows operations that are focused on the messaging with the browser. &lt;/p&gt;

&lt;p&gt;In this code, there is continuous communication between the background and content. Let's describe how this communication takes place before jumping into code. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;When the extension is clicked from a tab, a message from background to content is sent regarding the tab Id and a click count. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Here, click count keeps track of whether to mute or unmute a tab.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; background.js
 let clickCount = 0, filePath;
 chrome.runtime.onInstalled.addListener(() =&amp;gt; {
   chrome.browserAction.onClicked.addListener(tab =&amp;gt; {
     chrome.tabs.sendMessage(tab.id, {message: "clicked", 
     tab: tab.id, count: clickCount++ });  
   });
 });
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After the content receives the message from the background, it a chrome storage &lt;strong&gt;history&lt;/strong&gt; is accessed. This history keeps the detail of whether the tab is mute or not state and the tab id.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; content.js

 chrome.runtime.onMessage.addListener((req, sender, 
 sendResponse) =&amp;gt; {
   if (req.message === "clicked") {
     if (req.count === 0) chrome.storage.sync.set({ 
     history: [] });
     chrome.storage.sync.get(["history"], result =&amp;gt; {
        if (!result.history.length) {
            result.history[0] = { isMute: true, tabId: 
            req.tab };   
            chrome.storage.sync.set({ history: 
            result.history });
        } else {
            if (tabIdExist(result.history, req.tab)) {
                let arr = toggleMute(result.history, 
                req.tab);
                chrome.storage.sync.set({ history: arr 
                });
            } else {
                result.history.push({ isMute: true, 
                tabId: req.tab });
                chrome.storage.sync.set({ history: 
                result.history });
            }
        }

        console.log(result.history);
        let detailsTab = 
        fetchParticularTab(result.history, req.tab);
        chrome.runtime.sendMessage(detailsTab);
        });
      }
 });
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After this history is updated, the content sends a message to the background stating it is updated. Based on this data, for the recent tab you're on, if its state is mute, the code will run a script to unmute the tab and if its state is not mute, the code will run a script to mute the tab.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; background.js
 chrome.runtime.onMessage.addListener((req, sender, 
 sendResponse) =&amp;gt; {
   if (req.isMute) filePath = "src/scripts/mute.js";
   if (!req.isMute) filePath = "src/scripts/unmute.js";

   chrome.tabs.executeScript(req.tabId, {
    file:  filePath
  });
 });  
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Additional scripts and functions are trivial and can be accomplished if you've got the basic logic understanding and are capable of writing code in javascript. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Drawbacks &amp;amp; alternatives.
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Problem: You require the information on the coverage of video for each tab even if it's muted. &lt;/p&gt;

&lt;p&gt;Alternative: An additional feature using javascript can be included to record the contents of the video even if it's muted.  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Problem: Your presence has been called by the organizer of the call to speak. With the mute tab, you would be unaware of whether your name has been called.&lt;/p&gt;

&lt;p&gt;Alternative:  As the recording of the message will be included, we can use it to alter the user when their name is used in the context along with a summarized context using a keyboard before the user's name came up within the online meeting which had been muted.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;In conclusion, this extension can be useful in certain cases. With the additional features, it could be an amazing extension as a whole. What're your thoughts on it?&lt;/p&gt;

&lt;p&gt;The entire codebase is present on my &lt;a href="https://github.com/AemieJ/mute-and-record"&gt;github profile&lt;/a&gt;. It includes the additional DOM scripts that mute and unmute a tab. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>womenintech</category>
    </item>
    <item>
      <title>Use Github Real-Time Status to Improve Your Profile</title>
      <dc:creator>Aemie Jariwala</dc:creator>
      <pubDate>Sat, 08 Aug 2020 06:46:08 +0000</pubDate>
      <link>https://dev.to/aemiej/use-github-real-time-status-to-improve-your-profile-554m</link>
      <guid>https://dev.to/aemiej/use-github-real-time-status-to-improve-your-profile-554m</guid>
      <description>&lt;p&gt;On your &lt;strong&gt;personal portfolio&lt;/strong&gt; or the &lt;strong&gt;secret&lt;/strong&gt; feature of profile on &lt;strong&gt;Github&lt;/strong&gt;, publicizing ( in other words, showing-off ) your &lt;strong&gt;GitHub real-time status&lt;/strong&gt; will create an impact. Also, in addition, you can be proud of yourself or get the motivation to work more, it is a win-win for you itself. &lt;/p&gt;

&lt;h2&gt;
  
  
  What will be included in the real-time status?
&lt;/h2&gt;

&lt;p&gt;Well, it will include the languages you mostly make use for, and other than that, showcase the number of stars on your repos, PR, and issue creation, and the number of open-source contributions will be displayed too. The open-source contribution is the best thing about Github, so you can start exploring Github to improve your status of course.&lt;/p&gt;

&lt;p&gt;Below is my real-time status, I am proud of it but I am going to make it better. In addition to it, I have included in my &lt;a href="https://github.com/AemieJ"&gt;Github Profile&lt;/a&gt; as well!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyyabdujsekl9e31rtruw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fyyabdujsekl9e31rtruw.png" alt="Aemie Real-Time Status" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to create your own real-time status by using the API?
&lt;/h2&gt;

&lt;p&gt;This amazing feature can be found through another &lt;a href="https://github.com/anuraghazra/github-readme-stats"&gt;public repo&lt;/a&gt; on Github. You can use their personal API however once the number of requests crosses a certain limit, it would stop working ( personal-experience ) so we will create our own domain to use this &lt;a href="https://github-readme-stats.vercel.app/api?username=AemieJ"&gt;API&lt;/a&gt; so there will be a rare chance it would ever stop functioning. &lt;/p&gt;

&lt;h3&gt;
  
  
  Method to create a personal domain for using API
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Fork the &lt;a href="https://github.com/anuraghazra/github-readme-stats"&gt;repo&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Create an account on &lt;a href="//vercel.com"&gt;vercel&lt;/a&gt; using your Github account. This will be the platform used to deploy the API and create a personal domain. &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Import the forked repo on vercel. Direct deployment link can be accessed as &lt;code&gt;https://vercel.com/import/git?s=https%3A%2F%2Fgithub.com%2F&amp;lt;github-username&amp;gt;%2Fgithub-readme-stats&amp;amp;c=1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here, &lt;code&gt;&amp;lt;github-username&amp;gt;&lt;/code&gt; is filled with your Github Username. My direct deployment link can be accessed from &lt;a href="https://vercel.com/import/git?s=https%3A%2F%2Fgithub.com%2FAemieJ%2Fgithub-readme-stats&amp;amp;c=1"&gt;here&lt;/a&gt;. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Once you have reached the page of Import repository as shown in step 3, the following box will appear:&lt;/p&gt;

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

&lt;p&gt;Click Continue to proceed to the next step!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A dashboard will appear where you have to just add the Environment variable, name it as &lt;strong&gt;PAT_1&lt;/strong&gt; and its value can be generated from &lt;a href="https://github.com/settings/tokens/new"&gt;github&lt;/a&gt;. After this, just click deploy and your work is done and you can use your personal domain to use the API. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdi5d03tgzpuittqwt49r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdi5d03tgzpuittqwt49r.png" alt="Dashboard Domain" width="637" height="741"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Demo Purpose
&lt;/h3&gt;

&lt;p&gt;I am currently posting my link down here for demo purposes. Here, you can check the status of your &lt;a href="https://github-readme-stats.aemiej.vercel.app/api?username=AemieJ"&gt;profile&lt;/a&gt; by changing the username in the link &amp;amp; the &lt;a href="https://github-readme-stats.aemiej.vercel.app/api/top-langs/?username=AemieJ"&gt;language&lt;/a&gt; following the same change in username.&lt;/p&gt;

&lt;p&gt;Give it a try amigos! It's good to show off sometimes.&lt;/p&gt;

</description>
      <category>github</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Git Rebase Is Not The Devil</title>
      <dc:creator>Aemie Jariwala</dc:creator>
      <pubDate>Fri, 12 Jun 2020 19:09:17 +0000</pubDate>
      <link>https://dev.to/aemiej/git-rebase-is-not-the-devil-5fpa</link>
      <guid>https://dev.to/aemiej/git-rebase-is-not-the-devil-5fpa</guid>
      <description>&lt;p&gt;Alerting the readers from before, this blog will share my personal experience and provide professional tips on &lt;strong&gt;git rebase&lt;/strong&gt;, so if you want to advance yourself with the knowledge in the git, I recommend giving it a read.&lt;/p&gt;

&lt;p&gt;First comes the experience now. I love the idea of open source and love indulging myself in contributing to the organizations on Github. Currently, I am an outreachy intern in Apache, and the past week, I worked on an issue that required learning of new concepts, and in the way, my mentor kept advising me to rebase my branch to avoid merge conflicts. But guess what, &lt;strong&gt;rebase&lt;/strong&gt; scares the hell out of me only 'cause when I did try rebasing I lost all my commits for the issues and that freaked me out and I decided to just avoid it. Of course, I can't just give up so I tried it one more time carefully and voila, it happened perfectly and I understood the concept at last.&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%2Fi%2Fp4ubdiix8xo155k89ohy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp4ubdiix8xo155k89ohy.gif" alt="Happiness"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the tips, half of you know what rebasing might be and still be afraid to use it. I am going to define it just for those who don't know it yet. So rebasing helps you to put the commits of one branch on top of another branch to avoid any merge conflicts, that's its major use. The image will give a straightforward explanation.&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%2Fi%2Fly7del5gfgyk11gas5nl.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%2Fi%2Fly7del5gfgyk11gas5nl.png" alt="Git Rebase"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Beginning the journey to guide you, let's use a rebase for what it's mostly used. Creating the scenario, we have forked the example repo from Twelfth-Hour organization and we've got the feature branch for our example repo. After committing to it, it's no longer in par the master branch from the example repo on the Twelfth-Hour org, and from the image, we know what's the merge base i.e the intersecting commit for the two branches. Now giving you the step by step guide so that your feature is in par with the master branch of the main repo without losing your commits - &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;git checkout feature&lt;/code&gt;&lt;br&gt;
This is the branch that we need to add the new commits of the master to.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;git remote add example https://github.com/Twelfth-Hour/example.git&lt;/code&gt; &lt;br&gt;
Here, we create a remote from the main repo that we have forked for this scenario.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;git fetch example&lt;/code&gt;&lt;br&gt;
This will fetch the entire codebase with all its branches from the example repo on Twelfth-Hour org.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;git rebase example/master&lt;/code&gt; &lt;br&gt;
Now it will do its process to get your branch in par with the main branch. However, there could be conflicts so it might abort in middle, don't freak out, just resolve those conflicts and continue the process of rebasing. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This might be the end of the blog but not the end to what rebase is capable of doing.&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Decentralized WebNet</title>
      <dc:creator>Aemie Jariwala</dc:creator>
      <pubDate>Thu, 09 Jan 2020 08:36:57 +0000</pubDate>
      <link>https://dev.to/aemiej/decentralized-webnet-5ana</link>
      <guid>https://dev.to/aemiej/decentralized-webnet-5ana</guid>
      <description>&lt;h3&gt;
  
  
  Blockchain : The mind behind the project
&lt;/h3&gt;

&lt;p&gt;The project focuses on using the idea of blockchain to create a social website network where the client has the ability to create , view and tip any post on the ethereum network . Blockchain is a trending topic and the idea of how it provides a secure way to store the personalized information using sha256 and other encryption algorithms and proof of work algorithms all combined together , it's just amazing . This project however doesn't work on the main ethereum network but on the ropsten test network in metamask . Wondering now what Metamask is ? You sure should .&lt;/p&gt;

&lt;h3&gt;
  
  
  Metamask , Truffle ,  Infura and Ganache CLI
&lt;/h3&gt;

&lt;p&gt;The Ethereum site provides certain frameworks to work with so that the transactions that actually happens are easily kept tracked of in the blockchain . To begin with , I have used &lt;strong&gt;truffle&lt;/strong&gt; which does the necessary setup to write contracts , migrations and test for your blockchain to work with . It creates your project  using &lt;strong&gt;truffle init&lt;/strong&gt; . The truffle migrations are used to compile and deploy the contracts written . The test have been written in javascript using &lt;strong&gt;chai&lt;/strong&gt; &amp;amp; &lt;strong&gt;mocha&lt;/strong&gt; . The test in truffle works asynchronously , hence makes use of &lt;strong&gt;async&lt;/strong&gt; &amp;amp; &lt;strong&gt;await&lt;/strong&gt;. Moving to metamask , it is a chrome extension that connects your blockchain to the frontend and allows the client to perform transaction , you can import accounts by providing the private key . Metamask also offers the option of various test network and provides the feature to add your personal local network . This local network can be used for testing purpose and it is the done using Ganache-CLI . &lt;/p&gt;

&lt;p&gt;Now new term Ganache !! Well , Ganache provides you a quickstart that gives you 10 free accounts with 100 ether in each , this is fake ether and not real ether , you can't use it in the &lt;strong&gt;main ethereum network&lt;/strong&gt;. Last but not the least , what is Infura !! Infura was used in this project so that I was able to deploy the blockchain created to the ropsten network . It can be used to connect to the other test network and the main ethereum network as well. &lt;/p&gt;

&lt;h3&gt;
  
  
  Web3 and React
&lt;/h3&gt;

&lt;p&gt;Web3 and React were majorily used to connect the blockchain to the front-end to provide an easy manner for the client/user to interact with the blockchain . Web3 is majorily used to loadBlockchainData and access the functions within the contract. &lt;/p&gt;

&lt;h3&gt;
  
  
  Heroku
&lt;/h3&gt;

&lt;p&gt;Heroku was used in this project to deploy the entire project . &lt;/p&gt;

&lt;h3&gt;
  
  
  Links
&lt;/h3&gt;

&lt;p&gt;Even though there are a minor issues within the project , I will love to know your review on it .&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://devfolio.co/submissions/decentralized-webnet"&gt;Devfolio Link for Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://dweb-net.herokuapp.com/"&gt;Dweb-Net Website&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>blockchain</category>
      <category>react</category>
      <category>javascript</category>
      <category>heroku</category>
    </item>
  </channel>
</rss>
