<?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: Ajisafe Victor Oluwapelumi</title>
    <description>The latest articles on DEV Community by Ajisafe Victor Oluwapelumi (@ajipelumi).</description>
    <link>https://dev.to/ajipelumi</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%2F939563%2F90307064-d576-4ab6-92ec-275088e80425.jpeg</url>
      <title>DEV Community: Ajisafe Victor Oluwapelumi</title>
      <link>https://dev.to/ajipelumi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ajipelumi"/>
    <language>en</language>
    <item>
      <title>Understanding Value and Pointer Receivers in Go: Building a Crypto Tracker</title>
      <dc:creator>Ajisafe Victor Oluwapelumi</dc:creator>
      <pubDate>Thu, 06 Nov 2025 00:56:05 +0000</pubDate>
      <link>https://dev.to/ajipelumi/understanding-value-and-pointer-receivers-in-go-building-a-crypto-tracker-lkn</link>
      <guid>https://dev.to/ajipelumi/understanding-value-and-pointer-receivers-in-go-building-a-crypto-tracker-lkn</guid>
      <description>&lt;p&gt;I picked up Go recently while building the backend of a crypto tracker. This tracker allows users to manage their cryptocurrency holdings and calculate their wallet value in real-time. One of my favorite learnings so far is value receivers and pointer receivers, and how everything works under the hood.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Go Passes Arguments
&lt;/h2&gt;

&lt;p&gt;Go passes arguments by value, not by reference. This means it creates a copy of the argument and passes that copy to the function. Understanding this is crucial to writing efficient Go code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Value Receivers: Working with Copies
&lt;/h3&gt;

&lt;p&gt;When you use a value receiver, Go creates a copy of the struct. Any modifications you make inside the function only affect the copy, not the original.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Wallet&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;User&lt;/span&gt;       &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;TotalValue&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Value receiver - receives a copy&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;UpdateValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newValue&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newValue&lt;/span&gt;  &lt;span class="c"&gt;// Only modifies the copy&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Inside function:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;wallet&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"pelumi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TotalValue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1000.0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UpdateValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5000.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Outside function:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalValue&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;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Inside &lt;span class="k"&gt;function&lt;/span&gt;: 5000
Outside &lt;span class="k"&gt;function&lt;/span&gt;: 1000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The original &lt;code&gt;wallet.TotalValue&lt;/code&gt; remains 1000 because we modified a copy. When the function returns, the copy is discarded (removed from the stack), and our changes are lost.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pointer Receivers: Modifying the Original
&lt;/h3&gt;

&lt;p&gt;Pointer receivers solve this by passing the memory address of the struct instead of a copy. When you pass an address, Go still passes it by value, but now you have an address that points to the original data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Pointer receiver - receives a pointer (address)&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;UpdateValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newValue&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newValue&lt;/span&gt;  &lt;span class="c"&gt;// Modifies the original&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Inside function:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;wallet&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"pelumi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TotalValue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1000.0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UpdateValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5000.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;// Go automatically passes &amp;amp;wallet&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Outside function:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;wallet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalValue&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;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Inside &lt;span class="k"&gt;function&lt;/span&gt;: 5000
Outside &lt;span class="k"&gt;function&lt;/span&gt;: 5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now both print 5000 because we modified the original through its address. Go automatically handles the dereferencing (you don't need to write &lt;code&gt;(*w).TotalValue&lt;/code&gt;), making the syntax clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Example: My Crypto Tracker
&lt;/h2&gt;

&lt;p&gt;In my crypto tracker, I use pointer receivers when updating wallet data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Wallet&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;         &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;User&lt;/span&gt;       &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;TotalValue&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;
    &lt;span class="n"&gt;Holdings&lt;/span&gt;   &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Holding&lt;/span&gt;
    &lt;span class="n"&gt;UpdatedAt&lt;/span&gt;  &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Pointer receiver because we need to modify the wallet&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;CalculateTotalValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;priceService&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;PriceService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0.0&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;holding&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Holdings&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;priceService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FetchCoinPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;holding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Coin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;holding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Amount&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;      &lt;span class="c"&gt;// Modifies the original wallet&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UpdatedAt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c"&gt;// Updates timestamp&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If I used a value receiver here, the calculated &lt;code&gt;TotalValue&lt;/code&gt; and &lt;code&gt;UpdatedAt&lt;/code&gt; would never be saved to the original wallet.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack vs Heap Trade-off
&lt;/h2&gt;

&lt;p&gt;Here's where it gets interesting. Value receivers are faster because they use the stack, but pointer receivers can be slower because they may require the heap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stack (Fast)
&lt;/h3&gt;

&lt;p&gt;When you use value receivers, Go allocates the copy on the stack. The stack is fast because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Memory is automatically managed (allocated and freed when functions return)&lt;/li&gt;
&lt;li&gt;Memory is local and cache-friendly&lt;/li&gt;
&lt;li&gt;No garbage collector involvement
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;GetUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;  &lt;span class="c"&gt;// Fast: uses stack memory&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Heap (Slower, but Necessary)
&lt;/h3&gt;

&lt;p&gt;When you use pointer receivers, Go might allocate the variable on the heap if it "escapes" the function scope. This happens because the address could be referenced later in the program, so Go can't safely discard it when the function returns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;UpdateAndReturn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Wallet&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;  &lt;span class="c"&gt;// Address escapes, so w lives on the heap&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The heap is slower because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The garbage collector must track and clean up these allocations&lt;/li&gt;
&lt;li&gt;Memory access is less cache-friendly&lt;/li&gt;
&lt;li&gt;Allocation and deallocation take more time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, this trade-off is usually worth it when you need to modify large structs or avoid expensive copies.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use Each
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Value Receivers When:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You don't need to modify the struct&lt;/li&gt;
&lt;li&gt;The struct is small (a few fields)&lt;/li&gt;
&lt;li&gt;You want maximum performance for read-only operations
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;IsEmpty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Holdings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;  &lt;span class="c"&gt;// Just reading, no modifications&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;GetUserInfo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User: %s, Value: $%.2f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use Pointer Receivers When:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You need to modify the struct&lt;/li&gt;
&lt;li&gt;The struct is large (copying would be expensive)&lt;/li&gt;
&lt;li&gt;You want consistency (if some methods use pointers, use them everywhere)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;AddHolding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;holding&lt;/span&gt; &lt;span class="n"&gt;Holding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Holdings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Holdings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;holding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c"&gt;// Modifies original&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;ClearHoldings&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Holdings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Holding&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;  &lt;span class="c"&gt;// Modifies original&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  A Common Pattern: Mixing Both
&lt;/h3&gt;

&lt;p&gt;In practice, if you have any pointer receiver methods, it's best to use pointer receivers for all methods on that type for consistency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Wallet&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;User&lt;/span&gt;       &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;TotalValue&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Even though this doesn't modify, use pointer for consistency&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;GetUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// This modifies, so it needs a pointer&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Wallet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;SetUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Coming from C, I understood pointers conceptually, but Go's implementation adds an interesting layer. The automatic dereferencing makes pointer receivers feel natural to use, and the compiler's escape analysis intelligently decides when to use the heap vs stack.&lt;/p&gt;

&lt;p&gt;The key insight: value receivers are best when you don't intend to modify the argument, while pointer receivers are perfect when you want to modify a passed argument or when you want to avoid copying large values.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>go</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Virtual Environments: My "Aha!" Moment</title>
      <dc:creator>Ajisafe Victor Oluwapelumi</dc:creator>
      <pubDate>Tue, 25 Feb 2025 14:34:43 +0000</pubDate>
      <link>https://dev.to/ajipelumi/virtual-environments-my-aha-moment-3hi7</link>
      <guid>https://dev.to/ajipelumi/virtual-environments-my-aha-moment-3hi7</guid>
      <description>&lt;p&gt;This is going to seem weird, but I have seen "virtual environments" flying around since I started coding in 2022. Yet, I only just &lt;em&gt;got&lt;/em&gt; the hang of them. For the longest time, they looked like some overly complex sorcery, and I would shy away every time someone mentioned them.&lt;/p&gt;

&lt;p&gt;Fast forward to now, I am sitting here wondering how I have been surviving without them all this time.&lt;/p&gt;

&lt;p&gt;Do not get me wrong, I had used virtual environments before. I knew how to spin one up when following tutorials, but it was always just one of those "do this because they said so" moments. I never really understood the power they wielded. But recently? Oh boy, things changed! I finally hacked how powerful they can be when properly integrated into a project, and now I cannot imagine coding without them.&lt;/p&gt;

&lt;p&gt;So, here is how I have been rolling with virtual environments lately.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Even Is a Virtual Environment?
&lt;/h3&gt;

&lt;p&gt;If you are like how I used to be, you might have nodded along when people talked about virtual environments without actually knowing what they were. A virtual environment is basically a self-contained workspace where you can install project-specific dependencies without messing up your system-wide Python setup.&lt;/p&gt;

&lt;p&gt;Think of it like a bubble for your project, everything it needs stays inside, away from global Python, keeping things clean and conflict-free. No more worrying about breaking other projects because some library decided to update itself to an incompatible version.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkwyxpwothebfr2rh0vb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkwyxpwothebfr2rh0vb.png" alt="A meme using the " width="651" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How To Setup Virtual Environments
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Create a virtual environment
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; venv my_env 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a new directory &lt;code&gt;my_env&lt;/code&gt;, which holds all the virtual environment goodies.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Activate it
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;On Windows:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  my_env&lt;span class="se"&gt;\S&lt;/span&gt;cripts&lt;span class="se"&gt;\a&lt;/span&gt;ctivate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;On macOS/Linux:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;source &lt;/span&gt;my_env/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once activated, your terminal will show &lt;code&gt;(my_env)&lt;/code&gt;, meaning you are now inside the isolated environment.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Install Dependencies
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;requests flask
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boom! These packages are now installed only inside &lt;code&gt;my_env&lt;/code&gt;, not system-wide.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Deactivate When Done
&lt;/h4&gt;



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

&lt;/div&gt;



&lt;p&gt;This takes you back to normal, global Python.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffpibx2k4i1thysz15kw4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffpibx2k4i1thysz15kw4.png" alt="A meme with the caption " start="" width="800" height="706"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why You Should Use Virtual Environments
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No More "It Works on My Machine" Nightmares&lt;/strong&gt; - With a virtual environment, dependencies are locked to specific versions, so no more "why does it work for you but not for me?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy Project Switching&lt;/strong&gt; - One can now hop between projects without dependency conflicts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better Collaboration&lt;/strong&gt; - When sharing code, others can recreate exact environment using a &lt;code&gt;requirements.txt&lt;/code&gt; file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that I have finally embraced virtual environments, I cannot believe I was coding without them for so long. If you are like I was, seeing people talk about them but never really using them, trust me, it is worth the 5 minutes to set up. Your projects (and future self) will thank you!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How Dictionary Lookup Operations Are O(1)</title>
      <dc:creator>Ajisafe Victor Oluwapelumi</dc:creator>
      <pubDate>Thu, 05 Sep 2024 18:16:38 +0000</pubDate>
      <link>https://dev.to/ajipelumi/how-dictionary-lookup-operations-are-o1-49pk</link>
      <guid>https://dev.to/ajipelumi/how-dictionary-lookup-operations-are-o1-49pk</guid>
      <description>&lt;p&gt;Imagine you have a magical book that lets you look up any word instantly. You don’t need to flip through pages or search for the right letter section. You just say the word, and &lt;em&gt;poof&lt;/em&gt;, the meaning appears immediately.&lt;/p&gt;

&lt;p&gt;In programming, we have something very similar to this magical book: &lt;strong&gt;dictionaries&lt;/strong&gt; (also called &lt;strong&gt;hashmaps&lt;/strong&gt;). They are special data structures where you can store things in a way that makes finding them super fast, no matter how much you’ve stored.&lt;/p&gt;

&lt;p&gt;But how does this work?&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s a Dictionary in Programming?
&lt;/h2&gt;

&lt;p&gt;A dictionary in programming is like a real-life dictionary, but instead of words and meanings, it stores keys and values. You give it a key (something unique like a number, a name, or a word), and it will give you back its value (like a description, number, or some other information related to the key).&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&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;fruit_colors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Apple&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Red&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Banana&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Yellow&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grapes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Purple&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;ul&gt;
&lt;li&gt;Key: "Apple"&lt;/li&gt;
&lt;li&gt;Value: "Red"&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Magic Behind O(1) Lookup
&lt;/h2&gt;

&lt;p&gt;So, how does the dictionary give you answers so quickly? The secret is something called &lt;strong&gt;hashing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let’s think about it this way: if you had a huge pile of toys and someone said, "Find me the red car" you would have to look through the whole pile one by one, that would take time, especially if there are lots of toys.&lt;/p&gt;

&lt;p&gt;Now, imagine if every toy had a magical sticker with an exact spot where it should go on a shelf. Every time you put a toy away, it goes straight to its specific spot. So, if you wanted the red car, you would know exactly where it is without looking through everything.&lt;/p&gt;

&lt;p&gt;This is exactly how a &lt;strong&gt;hashmap&lt;/strong&gt; works. When you add something to a dictionary, a special function (called a hash function) creates a magical "sticker" (called a &lt;strong&gt;hash&lt;/strong&gt;), which tells the dictionary where to store the value.&lt;/p&gt;

&lt;p&gt;When you ask for that value later using its key, the dictionary uses the same "sticker" to go straight to the spot and grab the value in one step. This quick access, no matter how much stuff you have, is called &lt;strong&gt;constant time&lt;/strong&gt; or &lt;strong&gt;O(1)&lt;/strong&gt; in Big O notation. It means the lookup time doesn’t grow even if you have millions of items stored.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking If a Key Exists in a Dictionary
&lt;/h2&gt;

&lt;p&gt;When working with dictionaries, one common task is checking if a specific key exists. For example, in our magical toy shelf, one might want to know if a red car is already on the shelf before adding another one.&lt;/p&gt;

&lt;p&gt;There are two ways you might write this check in Python:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if key in dictionary&lt;/li&gt;
&lt;li&gt;if key in dictionary.keys()&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At first glance, both seem to do the same thing however, there is a big difference in efficiency, and here is why.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;if key in dictionary&lt;/code&gt; – The Fast, Direct Way&lt;br&gt;
When you write &lt;code&gt;if key in dictionary&lt;/code&gt;, Python automatically looks for the key in the dictionary’s "shelf" of keys. It knows exactly where to check, thanks to the hashing system we talked about earlier. This lookup is done in O(1) time, meaning it is super fast.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;if key in dictionary.keys()&lt;/code&gt; – The Slower, Extra Work Way&lt;br&gt;
On the other hand, if you write &lt;code&gt;if key in dictionary.keys()&lt;/code&gt;, you are explicitly asking Python to first pull out all the keys from the dictionary and store them in a special "view" object. Then, Python checks if the key is in that view. While this still works, it is slower because you are adding an extra step: creating the view of all the keys.&lt;/p&gt;

&lt;p&gt;Always use &lt;code&gt;if key in dictionary&lt;/code&gt;. It is the faster, more efficient way to check if a key exists in a dictionary.&lt;/p&gt;

&lt;p&gt;Dictionaries in programming are powerful tools, allowing you to store and retrieve data quickly, thanks to the magic of hashing. With constant-time lookups (O(1)), they enable you to efficiently manage large amounts of data without worrying about performance issues. Whether you are checking if a key exists or retrieving a value, dictionaries are your go-to structure for fast and effective operations.&lt;/p&gt;

&lt;p&gt;Have any experiences with using dictionaries? Share your thoughts and tips in the comments below!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Goroutines and sync.WaitGroup in Golang</title>
      <dc:creator>Ajisafe Victor Oluwapelumi</dc:creator>
      <pubDate>Thu, 11 Jan 2024 16:13:37 +0000</pubDate>
      <link>https://dev.to/ajipelumi/goroutines-and-syncwaitgroup-in-golang-11dk</link>
      <guid>https://dev.to/ajipelumi/goroutines-and-syncwaitgroup-in-golang-11dk</guid>
      <description>&lt;p&gt;Creating a booking app with Golang has been a thrilling experience, filled with challenges and chances to learn. I came across something interesting while working on managing Goroutines using &lt;code&gt;sync.WaitGroup&lt;/code&gt;. It reminded me of the asynchronous and await functionality in Node.js, providing a strong way to handle multiple tasks at the same time in Golang. However, when I initially tried to add &lt;code&gt;sync.WaitGroup&lt;/code&gt; to my code, I encountered an unexpected error, I found out that it was crucial to create an instance of &lt;code&gt;sync.WaitGroup&lt;/code&gt; for it to work smoothly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Importance of Goroutines
&lt;/h2&gt;

&lt;p&gt;Goroutines are a key feature in Golang that allow functions to run concurrently. They are lightweight, making them great for handling many tasks simultaneously without affecting performance. To make Goroutines even more efficient, I explored using &lt;code&gt;sync.WaitGroup&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Sync.WaitGroup
&lt;/h2&gt;

&lt;p&gt;In Golang, &lt;code&gt;sync.WaitGroup&lt;/code&gt; is designed to coordinate Goroutines. It keeps track of the number of active Goroutines, making it useful in situations where you want to make sure all concurrent tasks are completed before moving on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Learning Experience
&lt;/h2&gt;

&lt;p&gt;While trying to add &lt;code&gt;sync.WaitGroup&lt;/code&gt; to my booking app, I faced an error that made me realize that creating an instance of &lt;code&gt;sync.WaitGroup&lt;/code&gt; is necessary before using its methods. The three main methods - &lt;code&gt;Add()&lt;/code&gt;, &lt;code&gt;Wait()&lt;/code&gt;, and &lt;code&gt;Done()&lt;/code&gt; - are crucial for synchronization. If we try to call &lt;code&gt;sync.WaitGroup.Add(1)&lt;/code&gt;, the Go compiler will give an error because &lt;strong&gt;Add&lt;/strong&gt; is not a function of the &lt;code&gt;sync.WaitGroup&lt;/code&gt; type that can be called directly. It's a method that needs an instance of &lt;code&gt;sync.WaitGroup&lt;/code&gt; to be called upon.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"sync"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Create an instance of sync.WaitGroup&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;wg&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WaitGroup&lt;/span&gt;

    &lt;span class="c"&gt;// Example Goroutine&lt;/span&gt;
    &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// Your concurrent task logic here&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;

    &lt;span class="c"&gt;// Wait for all Goroutines to finish&lt;/span&gt;
    &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wait&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;By creating an instance of &lt;code&gt;sync.WaitGroup&lt;/code&gt; and using its methods in the right context, I seamlessly integrated it into my booking app. This ensured smooth coordination between Goroutines.&lt;/p&gt;

&lt;p&gt;If you have any stories about using &lt;code&gt;sync.WaitGroup&lt;/code&gt;, feel free to share them in the comments below. I would love to hear about your experiences!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Journey to Becoming a Software Engineer: My Year at ALX</title>
      <dc:creator>Ajisafe Victor Oluwapelumi</dc:creator>
      <pubDate>Fri, 20 Oct 2023 22:58:55 +0000</pubDate>
      <link>https://dev.to/ajipelumi/the-journey-to-becoming-a-software-engineer-my-year-at-alx-p0a</link>
      <guid>https://dev.to/ajipelumi/the-journey-to-becoming-a-software-engineer-my-year-at-alx-p0a</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flq3iior1qqrd02920gd3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flq3iior1qqrd02920gd3.png" alt="A mail screenshot of my congratulatory message into ALX Software Engineering Program" width="626" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On August 15, 2022, I began a journey that changed my life's course. The &lt;a href="https://www.alxafrica.com/software-engineering-plus/" rel="noopener noreferrer"&gt;ALX Software Engineering&lt;/a&gt; program was my choice. At first, I was both excited and uncertain about what lay ahead. I'd been self-taught, but I longed for structured learning and a community of like-minded individuals. ALX was my answer.&lt;/p&gt;

&lt;p&gt;Today, on October 20, 2023, as I graduate from this transformative program, I'm brimming with excitement and a profound sense of achievement. The past year has been a remarkable journey of self-discovery and growth, one I'm eager to share with you in this post. It's been a time of refining my skills and broadening my horizons, and I can't wait to see where this newfound knowledge will lead me.&lt;/p&gt;

&lt;p&gt;My year at ALX was like an exciting journey where I not only became a better coder but also honed my problem-solving skills. The challenging curriculum and unwavering support from my fellow learners and mentors transformed everyday problems into chances for personal growth. My ability to think critically, debug, and solve complex problems all improved significantly, giving me the confidence to handle challenges with ease.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnp27radpxw0cnunezobv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnp27radpxw0cnunezobv.png" alt="A software engineering meme" width="659" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yet, one big realization during this year was the strength of community. The program created an atmosphere where working together was key. It wasn't only about standing out individually but also about supporting each other. The feeling of togetherness and sharing knowledge with my peers meant a lot. It taught me that the journey becomes more special when you're alongside others who have the same passion.&lt;/p&gt;

&lt;p&gt;While at ALX, I discovered a knack for explaining complex technical stuff in simple terms. This newfound passion for making the complicated seem easy has become a vital part of my journey. Feel free to check out my articles &lt;a href="https://dev.to/ajipelumi"&gt;here&lt;/a&gt; for a deeper dive into topics that pique my interest.&lt;/p&gt;

&lt;p&gt;As I gaze ahead, I see a world filled with opportunities. In the next 5-10 years, I imagine using my Software Engineering skills to make a positive impact on communities in Africa and beyond. My time at ALX has armed me with not just technical skills, but also the mindset and determination to effect change. I'm thrilled to apply my knowledge to tackle real-world issues and devise solutions that can benefit society.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxx0szfnmb7i881igykv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxx0szfnmb7i881igykv.png" alt="ALX 2023 Graduation graphic" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In summary, my year at ALX Africa has been an exceptional chapter in my software engineering journey. It transformed me, broadening my horizons, honing my skills, and instilling a deep sense of purpose. I found my community, uncovered a passion for technical writing, and gained the confidence to tackle complex challenges. The future holds abundant promise, and I can't wait to seize its opportunities.&lt;/p&gt;

&lt;p&gt;I invite you to dive into my articles here and reach out to &lt;a href="https://www.linkedin.com/in/ajisafeoluwapelumi" rel="noopener noreferrer"&gt;me&lt;/a&gt;. If you're on a similar path or have a story to share, I'd be thrilled to connect with you. Together, let's keep learning, growing, and inspiring one another.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Composition and Inheritance: From Cars to Cars</title>
      <dc:creator>Ajisafe Victor Oluwapelumi</dc:creator>
      <pubDate>Mon, 28 Aug 2023 23:35:44 +0000</pubDate>
      <link>https://dev.to/ajipelumi/composition-and-inheritance-from-cars-to-cars-gld</link>
      <guid>https://dev.to/ajipelumi/composition-and-inheritance-from-cars-to-cars-gld</guid>
      <description>&lt;p&gt;Hello and welcome! A while back, I tackled a real-world problem through Forage, and the company at the center was &lt;a href="https://www.lyft.com/" rel="noopener noreferrer"&gt;Lyft&lt;/a&gt;. While much of the material covered wasn't entirely new, what intrigued me were the concepts of &lt;em&gt;composition&lt;/em&gt; and &lt;em&gt;inheritance&lt;/em&gt;. These concepts played a central role in shaping Lyft's backend infrastructure and I thought to share my newfound knowledge with you. Stay tuned.&lt;/p&gt;

&lt;h3&gt;
  
  
  Composition: Assembling a Car
&lt;/h3&gt;

&lt;p&gt;Let's say we are putting together a car. A car is made up of lots of different parts, and instead of making the whole car all at once, we start by making smaller pieces. Then, we fit these pieces together to build the complete car. This way of building things is called &lt;em&gt;composition&lt;/em&gt;. It's a helpful approach because it gives our car flexibility. We can easily add or remove pieces as needed. This makes our finished car more versatile.&lt;/p&gt;

&lt;p&gt;Let's see an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Wheels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;brand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;brand&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;wheels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Wheels&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 are defining three classes: &lt;code&gt;Engine&lt;/code&gt;, &lt;code&gt;Wheels&lt;/code&gt;, and &lt;code&gt;Car&lt;/code&gt;. Engine and Wheels represent parts of a car while the Car class brings together an engine and wheels to construct a complete car.&lt;/p&gt;

&lt;p&gt;We see that each part has its own functionality with specific responsibilities. The engine starts, the wheels rotate and the car cars (I thought that would come out right).&lt;/p&gt;

&lt;h3&gt;
  
  
  Inheritance: Family Traits Passed On
&lt;/h3&gt;

&lt;p&gt;Inheritance is in the name, we inherit traits from our parents. Same applies here as our classes inherit characteristics from their base class. We can create new things based on existing things and pass down their characteristics. This approach makes us more efficient as we do not need to create things from the start.&lt;/p&gt;

&lt;p&gt;Let's see an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;brand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;brand&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Vehicle&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# Creating an instance of Car
&lt;/span&gt;&lt;span class="n"&gt;my_car&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Toyota&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My car&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s brand is &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;my_car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;brand&lt;/span&gt;&lt;span class="si"&gt;}&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;The &lt;code&gt;Car&lt;/code&gt; class inherits the &lt;code&gt;brand&lt;/code&gt; attribute from the &lt;code&gt;Vehicle&lt;/code&gt; class without needing to redefine the &lt;code&gt;__init__&lt;/code&gt; method. The Car class inherits all attributes and methods from the Vehicle class while also retaining the ability to redefine and implement its own variations.&lt;/p&gt;

&lt;p&gt;You could use both composition and inheritance together to get the best out of your application. If you'd like to explore how I employed both to address the Lyft challenge, you can find the code &lt;a href="https://github.com/ajipelumi/forage-lyft-starter-repo/tree/main" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you've got stories about using composition and inheritance, I would love to hear them. Drop a comment below and share your experiences!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Exploring the Magic of async/await in JavaScript!</title>
      <dc:creator>Ajisafe Victor Oluwapelumi</dc:creator>
      <pubDate>Thu, 10 Aug 2023 20:20:14 +0000</pubDate>
      <link>https://dev.to/ajipelumi/exploring-the-magic-of-asyncawait-in-javascript-1k3o</link>
      <guid>https://dev.to/ajipelumi/exploring-the-magic-of-asyncawait-in-javascript-1k3o</guid>
      <description>&lt;p&gt;Today, we're going to uncover &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt;. In JavaScript, there are some tasks that can take some time, like asking for information from the internet or reading special files. Instead of making the whole computer wait for these tasks to finish, JavaScript allows other tasks to be handled at the same time while it waits for the response from time-taking tasks. Sometimes, we want to wait for the response before starting other tasks, and that's where &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; comes in.&lt;/p&gt;

&lt;h3&gt;
  
  
  async
&lt;/h3&gt;

&lt;p&gt;In simple words, &lt;code&gt;async&lt;/code&gt; is a special word we put in front of a function to tell our computer, "Hey, inside this function, there might be things that take a bit of time to finish."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Asynchronous operation&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  await
&lt;/h3&gt;

&lt;p&gt;We use the &lt;code&gt;await&lt;/code&gt; keyword inside an &lt;code&gt;async&lt;/code&gt; function and it's a way to tell our computer, "Hey, take a break and pause execution here until this thing is done."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Pauses until getData() is resolved&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&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;Let's explore the use of &lt;em&gt;async&lt;/em&gt; and &lt;em&gt;await&lt;/em&gt; with some examples.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example 1: Without async/await
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Imagine fetching a cat fact from an API using Promises&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://catfact.ninja/fact&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Oops! This won't work as expected&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cat Fact Ninja!&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;function&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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="c1"&gt;// Fetch the cat fact from the API&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we have two functions: &lt;em&gt;main()&lt;/em&gt; and &lt;em&gt;fetch(url)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;fetch(url)&lt;/code&gt; function takes a URL as input and returns a Promise (a Promise ensures that our request is completed). Inside this Promise, we request a cat fact from the internet.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;main()&lt;/code&gt; function starts by setting a URL for a cat fact API. Then it calls the &lt;code&gt;fetch(url)&lt;/code&gt; function to get the cat fact data. Since &lt;code&gt;fetch(url)&lt;/code&gt; returns data from the internet, it doesn't immediately provide the result, the function takes time. Therefore, when we try to log &lt;code&gt;response.fact&lt;/code&gt;, it won't work correctly. The next console.log() statement and 'Cat Fact Ninja!' will be printed before the &lt;code&gt;fetch(url)&lt;/code&gt; is resolved and this is not what we want. We can fix this in the next example.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example 2: With async/await
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Now let's fetch a cat fact using async/await&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://catfact.ninja/fact&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// We await the promise to finish&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// This works perfectly now!&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cat Fact Ninja!&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;function&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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="c1"&gt;// Fetch the cat fact from the API&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we've made a slight change by using the &lt;code&gt;async&lt;/code&gt; keyword in the &lt;code&gt;main()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;main()&lt;/code&gt; function is now marked as &lt;code&gt;async&lt;/code&gt;, which means we can use the &lt;code&gt;await&lt;/code&gt; keyword inside it. When &lt;code&gt;await&lt;/code&gt; is used before calling &lt;code&gt;fetch(url)&lt;/code&gt;, it pauses the execution of the &lt;code&gt;main()&lt;/code&gt; function until we get the result we want. This way, the cat fact data is fetched and assigned to the &lt;code&gt;response&lt;/code&gt; variable before moving on. Now, when we log &lt;code&gt;response.fact&lt;/code&gt;, it will correctly show the cat fact fetched from the API because we were waiting for the function to return using &lt;code&gt;await&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; help us do cool things with our code, even if those things take time. If you've got thoughts or stories about using them, I'd love to hear them. Drop a comment below and share your experiences, your feedback means a lot!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Navigating One-To-Many Relationship in MySQL</title>
      <dc:creator>Ajisafe Victor Oluwapelumi</dc:creator>
      <pubDate>Thu, 03 Aug 2023 18:20:44 +0000</pubDate>
      <link>https://dev.to/ajipelumi/navigating-one-many-relationship-in-mysql-187o</link>
      <guid>https://dev.to/ajipelumi/navigating-one-many-relationship-in-mysql-187o</guid>
      <description>&lt;p&gt;While developing the backend for &lt;a href="//quiz.pelumi.tech"&gt;Vim Quizzer&lt;/a&gt;,  I encountered a challenge in handling a list of incorrect questions for our question class due to MySQL's lack of direct support for list structures. To address this, I created an Incorrect Question class and established a One-to-Many relationship between the Question class and the Incorrect Question class, successfully implementing a list structure. In this post, I will explain how I achieved that and also shed light on how the One-to-Many relationship works.&lt;/p&gt;

&lt;p&gt;Before we dive into the technicalities, let me give a brief overview of the project that kick started this adventure. &lt;strong&gt;Vim Quizzer&lt;/strong&gt; is an engaging platform designed to help users learn Vim commands through a series of multiple-choice questions that test their knowledge of this command-line text editor, commonly used on Linux machines. If you're eager to put your Vim skills to the test, you can try the quiz &lt;a href="//quiz.pelumi.tech"&gt;here&lt;/a&gt;, the source code is also available &lt;a href="https://github.com/ajipelumi/vim-quizzer" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Challenge
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdgnvyhcy8jcv8xt52vwt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdgnvyhcy8jcv8xt52vwt.png" alt="A snapshot of our database structure" width="800" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MySQL serves as the relational database management system, where we store the questions for our web application. As depicted above, our database structure includes a table named &lt;em&gt;questions&lt;/em&gt; with 4 columns: &lt;em&gt;question_id&lt;/em&gt;, &lt;em&gt;question&lt;/em&gt;, &lt;em&gt;correct_answer&lt;/em&gt;, and &lt;em&gt;incorrect_answers&lt;/em&gt;. The &lt;em&gt;question_id&lt;/em&gt; column holds the question id while the &lt;em&gt;question&lt;/em&gt; column accepts a string to store the question itself, the &lt;em&gt;correct_answer&lt;/em&gt; column also takes a string to store the accurate response for the question. On the other hand, the &lt;em&gt;incorrect_answers&lt;/em&gt; column requires a list of strings to store the various incorrect responses for the question.&lt;/p&gt;

&lt;p&gt;However, MySQL lacks built-in support for list structures so we can't have an &lt;em&gt;incorrect_answers&lt;/em&gt; column. To address this, we had to devise an alternative approach, and that's where One-to-Many relationship came into play.&lt;/p&gt;

&lt;h3&gt;
  
  
  One-To-Many Relationship
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpagey5dls4eu83hakb5n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpagey5dls4eu83hakb5n.png" alt="One-To-Many Relationship" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As illustrated above, we have established an &lt;em&gt;incorrect answers&lt;/em&gt; table, which comprises the &lt;em&gt;incorrect_answer_id&lt;/em&gt; column, the &lt;em&gt;question_id&lt;/em&gt; column, and the &lt;em&gt;incorrect_answer&lt;/em&gt; itself. It is evident that the &lt;em&gt;question_id&lt;/em&gt; serves as a shared column between the &lt;em&gt;question&lt;/em&gt; table and the &lt;em&gt;incorrect_answer&lt;/em&gt; table. The incorrect answers to the question in our first illustration are now stored accordingly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pyte8skt2vkufomdxrd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pyte8skt2vkufomdxrd.png" alt="Incorrect Answers Table" width="800" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, all 3 incorrect answers possess the same &lt;em&gt;question_id&lt;/em&gt;, signifying that they correspond to one particular question in our database. This linkage ensures that each incorrect answer is appropriately associated with its corresponding question.&lt;/p&gt;

&lt;p&gt;To enable the &lt;em&gt;incorrect_answers&lt;/em&gt; attribute to return the list of all incorrect answers associated with a question, we implemented the following code in our Question class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt; &lt;span class="c1"&gt;# Create list of incorrect answers
&lt;/span&gt; &lt;span class="n"&gt;incorrect_answers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;IncorrectAnswer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cascade&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;all, delete-orphan&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;In our implementation, we take advantage of SQLAlchemy's &lt;strong&gt;relationship&lt;/strong&gt; method to establish a seamless link between &lt;em&gt;incorrect_answers&lt;/em&gt; and the Incorrect Answer class. Thanks to the &lt;strong&gt;backref&lt;/strong&gt; parameter, accessing incorrect answers from a given question becomes a breeze, eliminating the need for complex queries or tangled joins. See snippet below.&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="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;question1&lt;span class="o"&gt;)&lt;/span&gt;
&amp;lt;class &lt;span class="s1"&gt;'__main__.Question'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; question1.question
&lt;span class="s1"&gt;'What is the Vim command to save and exit a file?'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; question1.correct_answer
&lt;span class="s1"&gt;':wq'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; question1.incorrect_answers
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;":w"&lt;/span&gt;, &lt;span class="s2"&gt;":q!"&lt;/span&gt;, &lt;span class="s2"&gt;":s"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Furthermore, the &lt;strong&gt;cascade&lt;/strong&gt; parameter works wonders in ensuring data integrity. When we remove a question, all its associated incorrect answers are gracefully deleted as well. This intelligent handling of cascading deletes prevents any orphaned records from cluttering up the database, maintaining a tidy and organized data structure. This solution brings simplicity and efficiency to the management of question and incorrect answer relationship, streamlining the entire process for optimal performance.&lt;/p&gt;

&lt;p&gt;As mentioned earlier, this implementation is at the core of our backend, making it the backbone of our entire application. Witnessing this implementation work in real-time was truly refreshing. The One-To-Many relationship unlocks the true power and practicality in our application, allowing us to seamlessly manage questions and their corresponding incorrect answers with utmost efficiency.&lt;/p&gt;

&lt;p&gt;I hope this explanation provided a clear understanding of the One-To-Many relationship. Feel free to share your thoughts and experiences in the comments. Whether you have explored this concept before or are eager to delve into it, your insights and feedback are appreciated.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>mysql</category>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>Setting up SSL Certificate with Nginx</title>
      <dc:creator>Ajisafe Victor Oluwapelumi</dc:creator>
      <pubDate>Tue, 25 Jul 2023 21:45:05 +0000</pubDate>
      <link>https://dev.to/ajipelumi/setting-up-ssl-certificate-with-nginx-48gn</link>
      <guid>https://dev.to/ajipelumi/setting-up-ssl-certificate-with-nginx-48gn</guid>
      <description>&lt;p&gt;One of the essential steps to ensure secure connections on any website or web application is to set up SSL (Secure Socket Layer) certificates.&lt;/p&gt;

&lt;p&gt;SSL certificates encrypt data transmitted between a user's browser and the web server, safeguarding sensitive information from prying eyes. In this post, we will walk through the process of setting up an SSL certificate with Nginx, a powerful and widely-used web server.&lt;/p&gt;

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

&lt;p&gt;Before we get started, make sure you have the following prerequisites in place:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A domain name (e.g. &lt;a href="http://www.example.com" rel="noopener noreferrer"&gt;www.example.com&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;A server with Nginx installed and running.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxy5waugmc7mauz41giz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxy5waugmc7mauz41giz.png" alt="Let's Begin Meme" width="432" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Obtaining an SSL Certificate:
&lt;/h3&gt;

&lt;p&gt;The first step is to obtain an SSL certificate, and we will use &lt;strong&gt;Let's Encrypt&lt;/strong&gt;, a free and widely recognized certificate authority, to do this. Let's Encrypt offers an automated certificate issuance process using the &lt;strong&gt;Certbot&lt;/strong&gt; tool.&lt;br&gt;
To get started, follow these steps:&lt;/p&gt;
&lt;h4&gt;
  
  
  Step 1: Install Certbot
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;certbot python3-certbot-nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Step 2: Obtaining the SSL Certificate
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;certbot certonly &lt;span class="nt"&gt;--standalone&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &amp;lt;your-domain-name&amp;gt; &lt;span class="nt"&gt;--non-interactive&lt;/span&gt; &lt;span class="nt"&gt;--agree-tos&lt;/span&gt; &lt;span class="nt"&gt;--email&lt;/span&gt; &amp;lt;your-email&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Certbot will handle the entire certificate issuance process for you. After a successful run, the SSL certificate and private key will be stored on your server.&lt;/p&gt;
&lt;h3&gt;
  
  
  Nginx Configuration for SSL:
&lt;/h3&gt;

&lt;p&gt;Now that we have the SSL certificate, let's configure Nginx to enable SSL on our domain.&lt;br&gt;
Locate your Nginx configuration file for the domain (usually found in &lt;code&gt;/etc/nginx/sites-available/default&lt;/code&gt;), and add the following lines within the server block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&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;443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="s"&gt;[::]:443&lt;/span&gt; &lt;span class="s"&gt;ssl&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;/var/www/html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt; &lt;span class="s"&gt;index.htm&lt;/span&gt; &lt;span class="s"&gt;index.nginx-debian.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;your-domain-name&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;ssl_certificate&lt;/span&gt; &lt;span class="n"&gt;/etc/letsencrypt/live/&amp;lt;your-domain-name&amp;gt;/fullchain.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_certificate_key&lt;/span&gt; &lt;span class="n"&gt;/etc/letsencrypt/live/&amp;lt;your-domain-name&amp;gt;/privkey.pem&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;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;listen 443 ssl&lt;/code&gt;; and &lt;code&gt;listen [::]:443 ssl&lt;/code&gt;; lines enable SSL on port 443, the default HTTPS port.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;ssl_certificate&lt;/code&gt; and &lt;code&gt;ssl_certificate_key&lt;/code&gt; directives point to the SSL certificate and private key files obtained from Certbot.&lt;/li&gt;
&lt;li&gt;The location &lt;code&gt;/&lt;/code&gt; block handles the regular web page requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuring HTTP to HTTPS Redirection:
&lt;/h3&gt;

&lt;p&gt;To redirect HTTP traffic to HTTPS, add the following server block for port 80 in the same Nginx configuration file as the above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&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;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="s"&gt;[::]:80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;your-domain-name&amp;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;/&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;301&lt;/span&gt; &lt;span class="s"&gt;https://&lt;/span&gt;&lt;span class="nv"&gt;$host$request_uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The location &lt;code&gt;/&lt;/code&gt; block performs an HTTP 301 (permanent) redirect to the HTTPS version of the same URL (https://$host$request_uri), effectively enforcing secure connections over HTTPS for the entire website.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing and Reloading Nginx:
&lt;/h3&gt;

&lt;p&gt;Before applying the changes, test your Nginx configuration for syntax errors:&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;sudo &lt;/span&gt;nginx &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the test is successful, reload Nginx to apply the new configuration:&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;sudo &lt;/span&gt;systemctl reload nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remember to replace &lt;strong&gt;&lt;/strong&gt; with your actual domain name in the configuration. Additionally, you should customize the location blocks and server settings according to your specific requirements.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>nginx</category>
      <category>security</category>
    </item>
    <item>
      <title>Unleashing the Copy-Paste Chuckles</title>
      <dc:creator>Ajisafe Victor Oluwapelumi</dc:creator>
      <pubDate>Sat, 15 Jul 2023 19:49:21 +0000</pubDate>
      <link>https://dev.to/ajipelumi/unleashing-the-copy-paste-chuckles-42nd</link>
      <guid>https://dev.to/ajipelumi/unleashing-the-copy-paste-chuckles-42nd</guid>
      <description>&lt;p&gt;Today, we delve into the intriguing world of copy-paste operations. We explore a fascinating challenge of achieving &lt;em&gt;'n' 'H'&lt;/em&gt; characters in the most efficient way possible.&lt;/p&gt;

&lt;p&gt;Here is what is expected:&lt;br&gt;
Given a number &lt;code&gt;n&lt;/code&gt;, write a method that calculates the fewest number of operations needed to result in exactly &lt;em&gt;'n' 'H'&lt;/em&gt; characters in the file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwrysryf6kqbegt9k5k4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwrysryf6kqbegt9k5k4.png" alt="An example of what is expected" width="800" height="189"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Through careful calculation and strategic maneuvers, we were able to unlock the secret to reaching the desired &lt;em&gt;'n' 'H'&lt;/em&gt; characters with the fewest number of operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Snippet
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;minOperations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt; Minimum Operations Function. &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="c1"&gt;# Set the minimum operation variable to 0
&lt;/span&gt;    &lt;span class="n"&gt;min_operations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="c1"&gt;# Set the current length variable to 1 as we start with 1 character 'H'
&lt;/span&gt;    &lt;span class="n"&gt;current_length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="c1"&gt;# Set the clipboard variable to 0 as we are not copying anything yet
&lt;/span&gt;    &lt;span class="n"&gt;clipboard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="c1"&gt;# Loop until current length is equal to n
&lt;/span&gt;    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;current_length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# If n is divisible by current length, we can copy all
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;current_length&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# This is the only time we can copy
&lt;/span&gt;            &lt;span class="n"&gt;clipboard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_length&lt;/span&gt;
            &lt;span class="c1"&gt;# Minimum operation is incremented by 1 because we copied
&lt;/span&gt;            &lt;span class="n"&gt;min_operations&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

        &lt;span class="c1"&gt;# Paste the clipboard
&lt;/span&gt;        &lt;span class="n"&gt;current_length&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;clipboard&lt;/span&gt;
        &lt;span class="c1"&gt;# Minimum operation is incremented by 1 because we pasted
&lt;/span&gt;        &lt;span class="n"&gt;min_operations&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="c1"&gt;# Return minimum operation
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;min_operations&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;minOperations&lt;/code&gt; function takes an integer &lt;code&gt;n&lt;/code&gt; as input, representing the desired number of 'H' characters in the file. It returns the fewest number of operations needed to reach the target.&lt;/p&gt;

&lt;p&gt;To start, the function checks if n is less than or equal to 1. If so, it means that the desired number of 'H' characters is already present in the file, and no operations are needed. In this case, the function returns &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, the function initializes some variables. &lt;code&gt;min_operations&lt;/code&gt; is set to &lt;code&gt;0&lt;/code&gt; to keep track of the total number of operations performed. &lt;code&gt;current_length&lt;/code&gt; is set to &lt;code&gt;1&lt;/code&gt; as we start with a single 'H' character in the file. The &lt;code&gt;clipboard&lt;/code&gt; variable is set to &lt;code&gt;0&lt;/code&gt; since there is nothing in the clipboard initially.&lt;/p&gt;

&lt;p&gt;The function then enters a while loop that continues until the &lt;code&gt;current_length&lt;/code&gt; is equal to &lt;code&gt;n&lt;/code&gt;. Inside the loop, it checks if &lt;code&gt;n&lt;/code&gt; is divisible by the &lt;code&gt;current_length&lt;/code&gt;. If it is, it means that the current length is a divisor of &lt;code&gt;n&lt;/code&gt;, and it would be optimal to perform a Copy All operation. The function updates the &lt;code&gt;clipboard&lt;/code&gt; variable to hold the value of &lt;code&gt;current_length&lt;/code&gt; since all characters can be copied at once. Additionally, &lt;code&gt;min_operations&lt;/code&gt; is incremented by &lt;code&gt;1&lt;/code&gt; to account for the copy operation.&lt;/p&gt;

&lt;p&gt;After that, the function performs a Paste operation by incrementing &lt;code&gt;current_length&lt;/code&gt; by the value of &lt;code&gt;clipboard&lt;/code&gt;. This increases the number of characters in the file. &lt;code&gt;min_operations&lt;/code&gt; is incremented by &lt;code&gt;1&lt;/code&gt; to track the paste operation.&lt;/p&gt;

&lt;p&gt;If n is not divisible by &lt;code&gt;current_length&lt;/code&gt;, the function simply performs a Paste operation by incrementing &lt;code&gt;current_length&lt;/code&gt; by &lt;code&gt;clipboard&lt;/code&gt; and increments &lt;code&gt;min_operations&lt;/code&gt; by &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once the loop completes and the &lt;code&gt;current_length&lt;/code&gt; reaches &lt;code&gt;n&lt;/code&gt;, the function returns the value of &lt;code&gt;min_operations&lt;/code&gt;, which represents the fewest number of operations needed to achieve exactly &lt;em&gt;'n' 'H'&lt;/em&gt; characters in the file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;minOperations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;minOperations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;minOperations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;minOperations&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="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;minOperations&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>interview</category>
    </item>
    <item>
      <title>PartnerUp: Revolutionizing Project Collaboration</title>
      <dc:creator>Ajisafe Victor Oluwapelumi</dc:creator>
      <pubDate>Wed, 21 Jun 2023 21:04:30 +0000</pubDate>
      <link>https://dev.to/ajipelumi/partnerup-revolutionizing-project-collaboration-4bkj</link>
      <guid>https://dev.to/ajipelumi/partnerup-revolutionizing-project-collaboration-4bkj</guid>
      <description>&lt;p&gt;In this blog post, I am excited to present &lt;a href="https://partnerup.pelumi.tech/" rel="noopener noreferrer"&gt;PartnerUp&lt;/a&gt;, a web application I developed as part of my portfolio project for the ALX/Holberton Software Engineering Program.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv78jekzu7amuth6k3i84.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv78jekzu7amuth6k3i84.png" alt="Let's Dive In Meme" width="800" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Purpose
&lt;/h3&gt;

&lt;p&gt;PartnerUp was created for the purpose of connecting ALX Software Engineering students, enabling them to find suitable project partners effortlessly. By providing a dedicated platform for students to connect and work together, PartnerUp aimed to enhance the overall learning experience and foster a supportive environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Timeline
&lt;/h3&gt;

&lt;p&gt;The development process spanned 6 weeks, allowing me to immerse myself in the intricacies of building both the frontend and backend. The timeline provided me with the opportunity to thoroughly plan, design, and implement PartnerUp, ensuring a robust and polished final product.&lt;/p&gt;

&lt;h3&gt;
  
  
  Target Audience
&lt;/h3&gt;

&lt;p&gt;PartnerUp was specifically designed for ALX Software Engineering students.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdw2jufjcwn7l5lx3dax.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffdw2jufjcwn7l5lx3dax.png" alt="PartnerUp Hold The Pain Harold Meme" width="800" height="1052"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Personal Focus
&lt;/h3&gt;

&lt;p&gt;As the sole developer of PartnerUp, I assumed the responsibility of both frontend and backend development. My personal focus revolved around creating a seamless user experience and a robust infrastructure to support the application's functionalities. I dedicated my efforts to ensure that PartnerUp was user-friendly, visually appealing, and responsive across different devices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Inspiration
&lt;/h3&gt;

&lt;p&gt;The inspiration for PartnerUp stems from my own experience as an ALX Software Engineering student. Throughout my journey in the program, I encountered the challenges of finding compatible project partners and witnessed firsthand the impact it had on the success of projects. Motivated by my own experiences and the desire to improve the collaborative experience for ALX students, I set out to create PartnerUp. I wanted to provide a dedicated platform that would empower students to connect with like-minded individuals, form strong project partnerships, and unlock their full potential.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;I have designed and implemented a robust architecture for PartnerUp that ensures seamless data flow and efficient functionality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F36rlzfhd8g39vevpe6vd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F36rlzfhd8g39vevpe6vd.png" alt="PartnerUp Architecture" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The architecture incorporates the frontend, backend, and database components, enabling smooth communication and interaction between the different layers of the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technology Choices and Justifications
&lt;/h3&gt;

&lt;p&gt;For the frontend development, I harnessed the capabilities of Bootstrap, Jinja, and jQuery to elevate the user experience in PartnerUp. While leveraging these powerful technologies, I ensured that the core web technologies such as HTML5, CSS3, and JavaScript remained at the heart of the project.&lt;/p&gt;

&lt;p&gt;With Bootstrap, I effortlessly created responsive and visually appealing user interfaces, allowing PartnerUp to seamlessly adapt to different screen sizes and devices. By integrating Jinja, a templating engine for Python, I streamlined the process of dynamically generating HTML content. Jinja's robust features and syntax provided a flexible and efficient approach to rendering dynamic data, enhancing the overall performance and maintainability of PartnerUp. To enrich the user experience, I harnessed the power of jQuery, a fast and concise JavaScript library.&lt;/p&gt;

&lt;p&gt;On the backend, I employed Python as the programming language and utilized the Flask web framework. Flask provided a lightweight and flexible foundation for handling HTTP requests, managing routes, and interacting with the database. Its simplicity allowed for efficient development, and I could focus on building the necessary functionality specific to PartnerUp.&lt;/p&gt;

&lt;p&gt;In terms of data storage, I utilized MySQL as the backend database, leveraging its reliability and efficiency for storing and retrieving user information. SQLAlchemy, a Python SQL toolkit, facilitated seamless integration between Python and MySQL, ensuring effective data management and storage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features Implemented
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User Registration and Authentication:&lt;/strong&gt; PartnerUp enables users to create accounts and authenticate themselves securely. The registration process collects essential user information, which is then stored in the database for future reference. User authentication ensures that only registered users can access and interact with the application's features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Partner Matching Algorithm:&lt;/strong&gt; A crucial feature of PartnerUp is its partner matching algorithm. Leveraging the power of PyGithub, the application analyzes user repositories, commits, and coding styles to match ALX students with compatible project partners. This feature streamlines the process of finding suitable partners, enhancing collaboration and project success.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;API Routes and Seamless Communication:&lt;/strong&gt; PartnerUp provides a range of API routes that facilitate seamless communication between the frontend and backend. These routes handle user information submission, retrieval, and partner management, ensuring a smooth flow of data and functionality within the application.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Technical Challenges
&lt;/h3&gt;

&lt;p&gt;As I delved into the development of the partner matching algorithm, I realized that accurately assessing the compatibility of coding periods and identifying relevant repositories would be crucial. I needed to devise an approach that could efficiently analyze and compare large volumes of code while considering various factors. The task at hand was to develop an algorithm that could handle (day/night) coding periods, effectively analyze repositories, and provide accurate partner suggestions based on compatibility. Additionally, I wanted to optimize the algorithm for efficiency and scalability to ensure smooth performance even with a growing user base.&lt;/p&gt;

&lt;p&gt;I conducted extensive research on analysis techniques. I integrated Github API to fetch commit history from user repositories. This allowed me to gather information on the user's coding patterns, commit frequency, and commit period. This data served as the basis for evaluating compatibility with potential partners. To provide personalized partner recommendations, I utilized the random library to randomly select three potential partners from the database. This random selection ensured a diverse pool of candidates for consideration. For each selected partner, I compared their commit history with the user's commit data. By analyzing factors such as commit frequency, and coding period, I assessed the compatibility of their coding practices.&lt;/p&gt;

&lt;p&gt;Through the combined use of Github API and the random library, I successfully implemented a partner matching algorithm that randomly selected three potential partners, assessed their commit history, and recommended the partner with the closest commit number to the user commit number. This approach ensured a fair selection process while considering the user's commit data and coding style preferences.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Takeaways
&lt;/h3&gt;

&lt;p&gt;Working on both the frontend and backend of the application has significantly broadened my technical skills. I gained a deeper understanding of frontend technologies such as HTML, CSS, and JavaScript, along with backend technologies like Python and database management. This hands-on experience allowed me to strengthen my proficiency in full-stack development and reinforced the importance of having a well-rounded skill set.&lt;/p&gt;

&lt;h3&gt;
  
  
  About Me
&lt;/h3&gt;

&lt;p&gt;I have a diverse background that combines both design and development. Having previously worked as a designer, I bring a keen eye for aesthetics and a user-centric approach to my projects. I thrive on the intersection of creativity and problem-solving, leveraging my design background to craft meaningful and visually appealing software solutions. I am constantly motivated by the ever-evolving world of engineering and eagerly embrace the challenges and opportunities it presents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ajipelumi" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://partnerup.pelumi.tech/login" rel="noopener noreferrer"&gt;Deployed Project&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://partnerup.pelumi.tech/" rel="noopener noreferrer"&gt;Landing Page&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.linkedin.com/in/ajisafeoluwapelumi" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>softwareengineering</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Nginx likes port 80 (a post-mortem)</title>
      <dc:creator>Ajisafe Victor Oluwapelumi</dc:creator>
      <pubDate>Fri, 12 May 2023 18:45:36 +0000</pubDate>
      <link>https://dev.to/ajipelumi/nginx-likes-port-80-a-post-mortem-26l8</link>
      <guid>https://dev.to/ajipelumi/nginx-likes-port-80-a-post-mortem-26l8</guid>
      <description>&lt;p&gt;The following is the incident report for the Nginx connection failure that occurred on &lt;em&gt;April 3, 2023&lt;/em&gt;. We understand this service issue has impacted our valued developers and users, and we apologize to everyone who was affected.&lt;/p&gt;

&lt;h4&gt;
  
  
  Issue Summary
&lt;/h4&gt;

&lt;p&gt;From 6:30 PM to 7:00 PM WAT, curl requests to our local server on port 80 resulted in connection refused messages. At its peak, the issue affected 100% of traffic to this server. The incident caused a delay in processing critical business operations for some of our users.&lt;/p&gt;

&lt;h4&gt;
  
  
  Timeline (all West African Time)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;6:25 PM: Configuration change is made by Engineer Daniel without peer review&lt;/li&gt;
&lt;li&gt;6:29 PM: Nginx is reloaded&lt;/li&gt;
&lt;li&gt;6:30 PM: Curl request fails, and issue begins&lt;/li&gt;
&lt;li&gt;6:30 PM: Engineer Pelumi notices connection failure&lt;/li&gt;
&lt;li&gt;6:50 PM: Engineer Pelumi investigates the issue and identifies the root cause&lt;/li&gt;
&lt;li&gt;6:55 PM: Successful configuration change rollback by Engineer Pelumi&lt;/li&gt;
&lt;li&gt;6:59 PM: Nginx restarts begin&lt;/li&gt;
&lt;li&gt;7:00 PM: 100% of traffic back online&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Root Cause and Resolution
&lt;/h4&gt;

&lt;p&gt;At &lt;em&gt;6:25pm&lt;/em&gt;, Engineer Daniel made a configuration change to the nginx configuration file that specifies the ports that the server listens to. The change specified that the default server only listens to requests made on port 8080. This change meant that requests made by our developers and users on port 80 would return connection failure. The configuration change was made without peer review, and this contributed to the issue.&lt;/p&gt;

&lt;p&gt;At &lt;em&gt;6:29pm&lt;/em&gt;, nginx was reloaded to apply the configuration changes, and a minute later, curl requests on port 80 returned connection failure. Engineer Pelumi who made the curl request and noticed the connection failure investigated the issue and identified the problem at &lt;em&gt;6:50pm&lt;/em&gt;. Engineer Pelumi rolled back the configuration change and made changes to the configuration file to listen on port 80. The web server was reloaded to apply the changes, and upon another curl request, the connection was restored, and the expected output was returned by the server.&lt;/p&gt;

&lt;h4&gt;
  
  
  Corrective and Preventative Measures
&lt;/h4&gt;

&lt;p&gt;We have taken the following corrective and preventative measures to ensure that similar incidents do not occur in the future:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We have implemented a peer review process for all configuration changes made to production systems.&lt;/li&gt;
&lt;li&gt;We have added additional monitoring and alerting mechanisms to detect configuration issues and notify the appropriate team members in a timely manner.&lt;/li&gt;
&lt;li&gt;We have updated our incident response procedures to ensure that all team members are familiar with the steps to take in the event of a configuration issue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We apologize once again for the inconvenience caused, and we remain committed to providing our users with the best possible service.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
