<?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: JohnKagunda</title>
    <description>The latest articles on DEV Community by JohnKagunda (@rafaeljohn9).</description>
    <link>https://dev.to/rafaeljohn9</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%2F1488078%2F8be905c1-d237-408e-9d64-7d36177a68e2.jpeg</url>
      <title>DEV Community: JohnKagunda</title>
      <link>https://dev.to/rafaeljohn9</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rafaeljohn9"/>
    <language>en</language>
    <item>
      <title>The Beauty of Git: Writing Code Stories</title>
      <dc:creator>JohnKagunda</dc:creator>
      <pubDate>Sun, 03 Aug 2025 18:17:07 +0000</pubDate>
      <link>https://dev.to/rafaeljohn9/the-beauty-of-git-writing-code-stories-3i99</link>
      <guid>https://dev.to/rafaeljohn9/the-beauty-of-git-writing-code-stories-3i99</guid>
      <description>&lt;p&gt;Most people understand the basics of what git is. &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;commit -m "please work"&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;. Well, having this for a git workflow makes it feel like a burden more than a tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lemme expand your mind a little bit.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine your code like a story one you're telling to your future self or another developer joining you. Every commit is a chapter, every branch is a plot thread, and every merge is where storylines converge. When viewed this way, Git transforms from a mundane version control system into a powerful narrative tool that makes your development journey coherent, traceable, and beautiful.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Art of Storytelling Through Commits
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Writing Commits That Matter
&lt;/h3&gt;

&lt;p&gt;A well-crafted commit message is like a good book title it tells you exactly what to expect inside. Instead of cryptic messages like "fix stuff" or "updates," consider commits as documentation of your thought process:&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="c"&gt;# Instead of this:&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"fix bug"&lt;/span&gt;

&lt;span class="c"&gt;# Write this:&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Fix user authentication timeout in mobile Safari

- Increase session timeout from 15 to 30 minutes
- Add heartbeat mechanism to maintain active sessions
- Update error handling for expired tokens

Resolves issue where users were logged out mid-transaction
on slower mobile connections."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This commit tells a complete story: what was broken, how it was fixed, why it matters, and what the impact is. Your future self will thank you when debugging at 2 AM.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Power of Atomic Commits
&lt;/h3&gt;

&lt;p&gt;Think of atomic commits as perfectly focused short stories each one should do exactly one thing, and do it completely. This approach transforms your development workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits of atomic commits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Easier debugging&lt;/strong&gt;: When something breaks, you can pinpoint exactly which change caused it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cleaner history&lt;/strong&gt;: Your project timeline becomes a clear narrative of evolution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safer reverts&lt;/strong&gt;: You can undo specific changes without collateral damage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better code reviews&lt;/strong&gt;: Reviewers can understand and evaluate each change independently
&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="c"&gt;# Instead of one massive commit:&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add user dashboard with profile, settings, and notifications"&lt;/span&gt;

&lt;span class="c"&gt;# Break it down:&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add user profile component with avatar and basic info"&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Implement user settings page with privacy controls"&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Create notification system with real-time updates"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each commit now tells a focused story that's easy to understand, review, and maintain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rebase: The Editor's Revision Process
&lt;/h3&gt;

&lt;p&gt;Interactive rebase is like having a time machine for your story. It lets you go back and polish your narrative before sharing it with the world:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; HEAD~3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This opens your last three commits in an editor where you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reword&lt;/strong&gt; commit messages for clarity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Squash&lt;/strong&gt; related commits together&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reorder&lt;/strong&gt; commits to create logical flow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edit&lt;/strong&gt; commits to fix small issues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drop&lt;/strong&gt; commits that shouldn't exist&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as the difference between showing someone your rough draft versus your polished manuscript. The story is the same, but the presentation makes all the difference.&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="c"&gt;# Before rebase - messy story:&lt;/span&gt;
feat: add login form
fix: typo &lt;span class="k"&gt;in &lt;/span&gt;login form
feat: add validation to login
fix: validation bug
feat: add password reset

&lt;span class="c"&gt;# After rebase - clean narrative:&lt;/span&gt;
feat: implement user authentication system
feat: add password reset functionality
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When Stories Take Unexpected Turns: Cherry-Pick to the Rescue
&lt;/h2&gt;

&lt;p&gt;We've all been there you're deep in the flow, making brilliant commits, only to realize you're on the wrong branch. It's like writing a perfect chapter for the wrong book. But Git has a solution: cherry-picking.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Cherry-Pick Rescue Mission
&lt;/h3&gt;

&lt;p&gt;Cherry-pick lets you take specific commits from one branch and apply them to another, like moving a scene from one story to another:&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="c"&gt;# You made commits on 'main' but meant to be on 'feature-branch'&lt;/span&gt;
git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
a1b2c3d Fix authentication bug
e4f5g6h Add user validation
i7j8k9l Update API endpoints

&lt;span class="c"&gt;# Switch to the correct branch&lt;/span&gt;
git checkout feature-branch

&lt;span class="c"&gt;# Cherry-pick the commits you need&lt;/span&gt;
git cherry-pick e4f5g6h  &lt;span class="c"&gt;# Just the validation commit&lt;/span&gt;
git cherry-pick a1b2c3d  &lt;span class="c"&gt;# And the auth fix&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common Cherry-Pick Scenarios
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Hotfix Emergency&lt;/strong&gt;: You've pushed a critical fix to the wrong branch, but production needs it now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout production
git cherry-pick hotfix-commit-hash
git push origin production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Feature Extraction&lt;/strong&gt;: You realize part of your feature should be its own separate story:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; new-feature-branch
git cherry-pick specific-commit-hash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Cross-Branch Pollination&lt;/strong&gt;: You developed something on one feature that another feature needs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout other-feature-branch
git cherry-pick useful-commit-hash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Beautiful Git Workflow
&lt;/h2&gt;

&lt;p&gt;When you combine all these concepts, your Git workflow becomes elegant and purposeful:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start with intention&lt;/strong&gt;: Create descriptive branch names that tell the story's purpose
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature/user-notification-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Commit atomically&lt;/strong&gt;: Each commit is a complete thought, a finished paragraph
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git add notification-model.js
   git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add notification data model with user preferences"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Polish before sharing&lt;/strong&gt;: Use interactive rebase to craft your narrative
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; origin/main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Handle mistakes gracefully&lt;/strong&gt;: Cherry-pick when life happens
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git cherry-pick commit-hash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Merge with purpose&lt;/strong&gt;: Your pull request tells a complete, coherent story
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git checkout main
   git merge &lt;span class="nt"&gt;--no-ff&lt;/span&gt; feature/user-notification-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Transformation
&lt;/h2&gt;

&lt;p&gt;Once you start thinking of Git as a storytelling tool, everything changes. Your commits become documentation. Your branches become organized thoughts. Your merges become chapter conclusions. Your repository becomes a living history of your project's evolution.&lt;/p&gt;

&lt;p&gt;The developer who inherits your code won't curse your name they'll appreciate the clear narrative you've left behind. Your future self won't struggle to understand past decisions the story will be right there in the commit history.&lt;/p&gt;

&lt;p&gt;Git stops being a burden and becomes what it was always meant to be: a powerful tool for collaborative storytelling in code. Every repository becomes a well-crafted novel, every commit a meaningful sentence, every branch a thoughtful subplot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So the next time you sit at your terminal, remember: you're not just managing code you're writing the story of your software. Make it a story worth reading.&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Leetcode: Two Ptrs: Easy</title>
      <dc:creator>JohnKagunda</dc:creator>
      <pubDate>Tue, 25 Feb 2025 03:11:10 +0000</pubDate>
      <link>https://dev.to/rafaeljohn9/leetcode-two-ptrs-easy-1n31</link>
      <guid>https://dev.to/rafaeljohn9/leetcode-two-ptrs-easy-1n31</guid>
      <description>&lt;p&gt;Technical interviews haven’t changed much, so it’s up to us to upskill and master data structures and algorithms (DSA). Although the &lt;a href="https://leetcode.com/studyplan/leetcode-75/" rel="noopener noreferrer"&gt;LeetCode 75 Study Plan&lt;/a&gt; is a great resource, covering just 75 questions to grasp all DSA concepts might not be enough—they tend to favor breadth over depth.&lt;/p&gt;

&lt;p&gt;Being a jack of all trades might save us for now, but as time goes by, we might struggle to solve various medium-level problems within a specific topic.&lt;/p&gt;




&lt;h3&gt;
  
  
  Problem Statement
&lt;/h3&gt;

&lt;p&gt;Given two strings, &lt;code&gt;needle&lt;/code&gt; and &lt;code&gt;haystack&lt;/code&gt;, return the &lt;strong&gt;index&lt;/strong&gt; of the first occurrence of &lt;code&gt;needle&lt;/code&gt; in &lt;code&gt;haystack&lt;/code&gt;, or &lt;code&gt;-1&lt;/code&gt; if &lt;code&gt;needle&lt;/code&gt; is not part of &lt;code&gt;haystack&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example 1
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt; &lt;code&gt;haystack = "sadbutsad", needle = "sad"&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Output:&lt;/strong&gt; &lt;code&gt;0&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Explanation:&lt;/strong&gt; The substring &lt;code&gt;"sad"&lt;/code&gt; occurs at indices 0 and 6, but the first occurrence is at index 0.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Example 2
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Input:&lt;/strong&gt; &lt;code&gt;haystack = "leetcode", needle = "leeto"&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Output:&lt;/strong&gt; &lt;code&gt;-1&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Explanation:&lt;/strong&gt; The substring &lt;code&gt;"leeto"&lt;/code&gt; does not occur in &lt;code&gt;"leetcode"&lt;/code&gt;, so the output is &lt;code&gt;-1&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Two-Pointer Technique Solution
&lt;/h3&gt;

&lt;p&gt;Although this problem can be solved with a few lines of code, our goal is to implement it using the two-pointer technique. Below is one such solution:&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;Solution&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;strStr&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;haystack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;needle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# If needle is an empty string, return 0 as per convention.
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;needle&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;haystack&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
            &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;needle&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
                &lt;span class="c1"&gt;# Check if we are within the bounds of haystack and characters match.
&lt;/span&gt;                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;haystack&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;haystack&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;needle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
                    &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;break&lt;/span&gt;

                &lt;span class="c1"&gt;# If we've successfully matched all characters in needle.
&lt;/span&gt;                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;needle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&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="n"&gt;i&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Outer Loop:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Iterates through each index in &lt;code&gt;haystack&lt;/code&gt;, considering it as a potential starting position for &lt;code&gt;needle&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Inner Loop:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
For each starting index, it iterates through the characters in &lt;code&gt;needle&lt;/code&gt; to verify if the substring in &lt;code&gt;haystack&lt;/code&gt; starting at that index matches &lt;code&gt;needle&lt;/code&gt;. The loop breaks early if a mismatch is found.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Early Termination:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If the inner loop completes (i.e., all characters in &lt;code&gt;needle&lt;/code&gt; have been successfully matched), the function immediately returns the starting index.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Performance Analysis
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Time Complexity:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
In the worst-case scenario, the outer loop runs &lt;code&gt;n&lt;/code&gt; times (where &lt;code&gt;n&lt;/code&gt; is the length of &lt;code&gt;haystack&lt;/code&gt;) and the inner loop runs up to &lt;code&gt;m&lt;/code&gt; times (where &lt;code&gt;m&lt;/code&gt; is the length of &lt;code&gt;needle&lt;/code&gt;) for each iteration. This results in a worst-case time complexity of &lt;strong&gt;O(n * m)&lt;/strong&gt;. However, in most cases, the inner loop terminates early due to mismatches, leading to better average performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Space Complexity:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The solution uses only a few extra pointer variables and does not require additional data structures, resulting in a constant space complexity of &lt;strong&gt;O(1)&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This two-pointer approach provides a clear and intuitive solution for the string matching problem. While it is efficient for many cases, more advanced algorithms—such as the Knuth-Morris-Pratt (KMP) algorithm—can offer better performance in worst-case scenarios when dealing with very large strings.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Docker Woes: When Containers Refuse to Listen and Databases Play Hard to Get</title>
      <dc:creator>JohnKagunda</dc:creator>
      <pubDate>Tue, 12 Nov 2024 04:58:59 +0000</pubDate>
      <link>https://dev.to/rafaeljohn9/docker-woes-when-containers-refuse-to-listen-and-databases-play-hard-to-get-3g7</link>
      <guid>https://dev.to/rafaeljohn9/docker-woes-when-containers-refuse-to-listen-and-databases-play-hard-to-get-3g7</guid>
      <description>&lt;p&gt;We can all agree at this point that Docker is a unique tool. The magic of having a consistent environment for both development and production is truly one of a kind.&lt;/p&gt;

&lt;p&gt;Despite its many benefits, setting it up can sometimes be a bit of a headache, whether it's for a single container or a network of containers.&lt;/p&gt;

&lt;p&gt;In this article, we will look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why you can't stop/kill your container and why it happens&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Access Denied&lt;/code&gt; issues on database containers, even when using the correct username and password&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why can't I stop/kill my Docker container, and why does this happen?
&lt;/h2&gt;

&lt;p&gt;Docker containers can become extremely frustrating when you try &lt;code&gt;Ctrl + C&lt;/code&gt; or &lt;code&gt;Cmd + C&lt;/code&gt;, and the container does not stop. You might start questioning your life choices, and eventually, you open another terminal to kill it using &lt;code&gt;docker kill&lt;/code&gt;, only to receive a &lt;code&gt;Permission denied&lt;/code&gt; error, even when running with &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Instead of rebooting your system each time or trying to reset your Docker service, using &lt;code&gt;kill -9&lt;/code&gt; can help. First, find all running services using &lt;code&gt;pgrep docker&lt;/code&gt;, then pick the process numbers and use &lt;code&gt;kill -9 &amp;lt;process number&amp;gt;&lt;/code&gt; to terminate the process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does this happen?
&lt;/h3&gt;

&lt;p&gt;This issue often occurs because the process running inside the Docker container has a &lt;code&gt;restart&lt;/code&gt; policy or operand.&lt;/p&gt;

&lt;p&gt;For example, consider the following process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uvicorn main:app &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run this app inside a Docker container and let it start by default when the container is launched, you won't be able to kill it because the &lt;code&gt;--reload&lt;/code&gt; option continuously restarts the app, even when the &lt;code&gt;SIGINT&lt;/code&gt; signal is sent.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;Access Denied&lt;/code&gt; on database containers, even with the correct username and password
&lt;/h2&gt;

&lt;p&gt;This problem can be puzzling. You might think, "Did I miss a comma, or perhaps there's an extra space?" Maybe you suspect there's an "Egyptian semicolon" in the password. But no, I’m sure of it — I copy-pasted the credentials, so even the Egyptian semicolon should have worked.&lt;/p&gt;

&lt;p&gt;The issue occurred while using a &lt;code&gt;docker-compose.yml&lt;/code&gt; file. The strange part was that the image ran fine on a single Docker container but failed when used with a &lt;code&gt;docker-compose&lt;/code&gt; file. I began removing extra parameters I wasn’t using when running the container individually, and it all came down to one culprit: &lt;code&gt;MYSQL_HOST&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Specifying this parameter caused a myriad of problems, as outlined in the issue &lt;a href="https://github.com/docker-library/mysql/issues/184" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Avoiding it is a better way to resolve the problem.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Dockerfile Best Practices: Building Efficient and Secure Containers</title>
      <dc:creator>JohnKagunda</dc:creator>
      <pubDate>Fri, 16 Aug 2024 16:32:19 +0000</pubDate>
      <link>https://dev.to/rafaeljohn9/dockerfile-best-practices-building-efficient-and-secure-containers-fa</link>
      <guid>https://dev.to/rafaeljohn9/dockerfile-best-practices-building-efficient-and-secure-containers-fa</guid>
      <description>&lt;p&gt;Docker has revolutionized the way we develop, ship, and run applications. However, writing an efficient and secure Dockerfile is crucial to ensure your containers perform well and are safe from vulnerabilities. In this article, we’ll explore some best practices that can help you create robust Docker images.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;strong&gt;Use Official Base Images&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Always start your Dockerfile with an official base image from Docker Hub, such as &lt;code&gt;alpine&lt;/code&gt;, &lt;code&gt;ubuntu&lt;/code&gt;, or &lt;code&gt;node&lt;/code&gt;. Official images are maintained by Docker and are regularly updated for security patches.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.9-slim&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Official images are vetted for security vulnerabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stability&lt;/strong&gt;: They are tested and maintained by the community or the official project maintainers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. &lt;strong&gt;Leverage Multi-Stage Builds&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Multi-stage builds allow you to separate the build environment from the final runtime environment, reducing the size of your Docker image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Stage 1: Build&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;golang:1.19&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;go build &lt;span class="nt"&gt;-o&lt;/span&gt; myapp

&lt;span class="c"&gt;# Stage 2: Runtime&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; alpine:latest&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /app/myapp .&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["./myapp"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduced Image Size&lt;/strong&gt;: Only the necessary files are included in the final image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Keeps build tools and other unnecessary components out of your runtime environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. &lt;strong&gt;Minimize Layers&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Each &lt;code&gt;RUN&lt;/code&gt;, &lt;code&gt;COPY&lt;/code&gt;, or &lt;code&gt;ADD&lt;/code&gt; instruction creates a new layer in your image. Combining commands in a single &lt;code&gt;RUN&lt;/code&gt; instruction can help minimize the number of layers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    curl &lt;span class="se"&gt;\
&lt;/span&gt;    vim &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get clean &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency&lt;/strong&gt;: Reduces the size of the Docker image and improves build performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainability&lt;/strong&gt;: Fewer layers make the image easier to understand and manage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. &lt;strong&gt;Use &lt;code&gt;.dockerignore&lt;/code&gt; File&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Include a &lt;code&gt;.dockerignore&lt;/code&gt; file to prevent unnecessary files from being copied into the Docker image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node_modules
*.log
Dockerfile
README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Smaller Images&lt;/strong&gt;: Excluding unnecessary files reduces the final image size.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Faster Builds&lt;/strong&gt;: Fewer files to copy means faster build times.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. &lt;strong&gt;Avoid Installing Unnecessary Packages&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Only install the packages and dependencies that are absolutely necessary for your application to run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    curl &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get clean &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Fewer packages mean fewer potential vulnerabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: Reducing the number of packages improves image build times and runtime performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. &lt;strong&gt;Use Non-Root User&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Running your application as a non-root user inside the container enhances security.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a non-root user&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;useradd &lt;span class="nt"&gt;-m&lt;/span&gt; appuser
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; appuser&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["./myapp"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Limits the impact of a security breach by reducing the permissions available to the running process.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. &lt;strong&gt;Optimize Caching&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Take advantage of Docker’s layer caching to speed up your builds. Place commands that change less frequently towards the top of your Dockerfile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Dependencies&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="c"&gt;# Application code&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency&lt;/strong&gt;: Docker reuses layers from the cache, leading to faster builds, especially during development.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8. &lt;strong&gt;Clean Up After Yourself&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Remove temporary files, package managers’ cache, and other unnecessary files after installation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    curl &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get clean &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Smaller Images&lt;/strong&gt;: Removing unnecessary files helps keep your Docker image lean.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better Performance&lt;/strong&gt;: Smaller images download faster and use less disk space.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  9. &lt;strong&gt;Set Metadata Labels&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Use labels to add metadata to your images, such as version information or maintainer contact details.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;LABEL&lt;/span&gt;&lt;span class="s"&gt; maintainer="rafaeljohn@example.com"&lt;/span&gt;
&lt;span class="k"&gt;LABEL&lt;/span&gt;&lt;span class="s"&gt; version="1.0"&lt;/span&gt;
&lt;span class="k"&gt;LABEL&lt;/span&gt;&lt;span class="s"&gt; description="My application Docker image"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Organizational&lt;/strong&gt;: Helps track image versions, authorship, and purpose.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation&lt;/strong&gt;: Labels can be used in automation tools to filter or organize images.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  10. &lt;strong&gt;Scan Images for Vulnerabilities&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Regularly scan your Docker images for vulnerabilities using tools like &lt;a href="https://github.com/aquasecurity/trivy" rel="noopener noreferrer"&gt;Trivy&lt;/a&gt; or &lt;a href="https://github.com/quay/clair" rel="noopener noreferrer"&gt;Clair&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Regular scans help identify and fix vulnerabilities before they can be exploited.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;By following these best practices, you’ll be well on your way to building efficient, secure, and maintainable Docker images. Remember, a well-crafted Dockerfile not only ensures the smooth operation of your applications but also contributes to the overall security and performance of your environment.&lt;/p&gt;

&lt;p&gt;Happy Dockerizing!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Docker Advanced Techniques: Beyond the Basics</title>
      <dc:creator>JohnKagunda</dc:creator>
      <pubDate>Wed, 14 Aug 2024 18:16:55 +0000</pubDate>
      <link>https://dev.to/rafaeljohn9/docker-advanced-techniques-beyond-the-basics-633</link>
      <guid>https://dev.to/rafaeljohn9/docker-advanced-techniques-beyond-the-basics-633</guid>
      <description>&lt;p&gt;Docker is an incredible tool that makes managing applications easier. Most people are familiar with the basics: creating containers, managing images, and using Docker Compose. But there's so much more you can do with Docker! In this article, I'll walk you through some advanced techniques that will level up your Docker game.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Multi-Stage Builds
&lt;/h2&gt;

&lt;p&gt;Ever wondered how to keep your Docker images small and efficient? Multi-stage builds are the answer! They allow you to use multiple &lt;code&gt;FROM&lt;/code&gt; statements in your Dockerfile, each with a different purpose. &lt;/p&gt;

&lt;p&gt;Here's a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Stage 1: Build the application&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:14&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build

&lt;span class="c"&gt;# Stage 2: Run the application&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; nginx:alpine&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build /app/build /usr/share/nginx/html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this Dockerfile, we first build our Node.js app in a full Node.js environment, and then in the second stage, we copy only the necessary files into a lightweight Nginx container. This keeps the final image small and fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Using Docker Volumes for Persistence
&lt;/h2&gt;

&lt;p&gt;Docker containers are ephemeral by nature, meaning they don't keep data once stopped or removed. But what if you need to store data that persists even after the container stops? This is where Docker volumes come in.&lt;/p&gt;

&lt;p&gt;Volumes allow you to persist data outside the container's filesystem. Here’s how you can use them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; my_app &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; my_data:/data &lt;span class="se"&gt;\&lt;/span&gt;
  my_image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this command, &lt;code&gt;-v my_data:/data&lt;/code&gt; creates a volume named &lt;code&gt;my_data&lt;/code&gt; and mounts it to the &lt;code&gt;/data&lt;/code&gt; directory inside the container. Your data will be safe even if the container is removed!&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Docker Networking for Communication
&lt;/h2&gt;

&lt;p&gt;When working with multiple containers, you'll often need them to communicate. Docker provides networking options to make this seamless. The most common approach is to use a bridge network.&lt;/p&gt;

&lt;p&gt;First, create a network:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker network create my_network
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, run your containers on this network:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; app1 &lt;span class="nt"&gt;--network&lt;/span&gt; my_network my_image1
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; app2 &lt;span class="nt"&gt;--network&lt;/span&gt; my_network my_image2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, &lt;code&gt;app1&lt;/code&gt; and &lt;code&gt;app2&lt;/code&gt; can communicate with each other using their container names as hostnames. Simple, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Docker Compose for Multi-Container Applications
&lt;/h2&gt;

&lt;p&gt;Docker Compose is a powerful tool for managing multi-container applications. With a single YAML file, you can define and run all your services together.&lt;/p&gt;

&lt;p&gt;Here’s a basic example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;80:80"&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;example&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running &lt;code&gt;docker-compose up&lt;/code&gt; in the directory containing this file will start both the Nginx and Postgres containers, ready to work together.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Automating Docker with CI/CD Pipelines
&lt;/h2&gt;

&lt;p&gt;For those who want to take their Docker usage to the next level, integrating Docker with CI/CD (Continuous Integration/Continuous Deployment) pipelines is the way to go. Tools like Jenkins, GitLab CI, or GitHub Actions can automate your Docker workflows.&lt;/p&gt;

&lt;p&gt;Here’s an example of a GitHub Actions workflow for building and pushing a Docker image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Docker CI&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Docker image&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker build -t my_app:latest .&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Log in to Docker Hub&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Push Docker image&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker push my_app:latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This workflow builds your Docker image every time you push to the &lt;code&gt;main&lt;/code&gt; branch and then pushes it to Docker Hub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Docker is more than just a tool for containerizing applications; it's a whole ecosystem that can transform how you develop, deploy, and manage your apps. By mastering these advanced techniques, you'll be well on your way to becoming a Docker pro. Happy tinkering!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>It's Working on My Machine; "Deploy Your Machine Then"</title>
      <dc:creator>JohnKagunda</dc:creator>
      <pubDate>Mon, 12 Aug 2024 08:28:54 +0000</pubDate>
      <link>https://dev.to/rafaeljohn9/its-working-on-my-machine-deploy-your-machine-then-4794</link>
      <guid>https://dev.to/rafaeljohn9/its-working-on-my-machine-deploy-your-machine-then-4794</guid>
      <description>&lt;p&gt;We’ve all heard the joke: “It’s working on my machine; deploy your machine then.” This joke highlights a common problem in software development: software that runs perfectly on a developer’s local machine might not work the same way when deployed to a different environment.&lt;/p&gt;

&lt;p&gt;To tackle this issue, developers needed a way to ensure that software runs consistently across different machines. That’s where Docker containers come in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Docker Containers?
&lt;/h2&gt;

&lt;p&gt;Docker containers are a technology that allows you to package your application and all its dependencies into a single, portable unit. Think of a Docker container as a lightweight, self-contained box that holds everything your application needs to run.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Use Docker Containers?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consistency&lt;/strong&gt;: Since the container includes the application and all its dependencies, you can be sure that it will work the same way on any machine. Whether it’s your local development machine or a production server, the container will behave the same.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Isolation&lt;/strong&gt;: Containers run in isolation from each other and from the host system. This means that one container’s processes won’t interfere with another’s, and your application won’t affect the underlying system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Portability&lt;/strong&gt;: Containers can be moved easily from one environment to another. You can build a container on your local machine and deploy it to a cloud server without worrying about compatibility issues.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example: Running a Simple Web App in Docker
&lt;/h3&gt;

&lt;p&gt;Let’s go through a basic example of using Docker containers. Suppose you have a simple web application that requires Python and some libraries to run.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create a Dockerfile&lt;/strong&gt;: This file describes how to build your Docker image. It includes instructions for setting up the environment and installing dependencies.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Use the official Python image from Docker Hub&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.8&lt;/span&gt;

&lt;span class="c"&gt;# Set the working directory in the container&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="c"&gt;# Copy the application code into the container&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /app&lt;/span&gt;

&lt;span class="c"&gt;# Install the dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="c"&gt;# Define the command to run the application&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python", "app.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Build the Docker Image&lt;/strong&gt;: Run the following command in your terminal to create an image from the Dockerfile.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; my-web-app &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This command builds an image named &lt;code&gt;my-web-app&lt;/code&gt; using the current directory (denoted by &lt;code&gt;.&lt;/code&gt;) as the build context.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Run the Docker Container&lt;/strong&gt;: Start a container from the image you just built.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 5000:5000 my-web-app
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This command runs the &lt;code&gt;my-web-app&lt;/code&gt; container and maps port 5000 of the container to port 5000 on your local machine.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Access the Application&lt;/strong&gt;: Open your web browser and go to &lt;code&gt;http://localhost:5000&lt;/code&gt;. You should see your web application running.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By using Docker containers, you’ve packaged your application in a way that makes it easy to deploy and run consistently, no matter where you are. This eliminates the “it works on my machine” problem and simplifies the deployment process.&lt;/p&gt;

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

&lt;p&gt;Docker containers are a powerful tool for ensuring your applications run smoothly across different environments. They provide consistency, isolation, and portability, making them a popular choice for modern software development. By using containers, you can avoid common deployment issues and focus on building great software.&lt;/p&gt;




&lt;p&gt;Check out this video about &lt;a href="https://youtu.be/Gjnup-PuquQ?si=eL6-l1K5qStY5BPE" rel="noopener noreferrer"&gt;Docker in 100 seconds&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building a Monty Bytecode Interpreter: A Hands-On Approach to Learning Stacks and Queues</title>
      <dc:creator>JohnKagunda</dc:creator>
      <pubDate>Wed, 07 Aug 2024 11:19:47 +0000</pubDate>
      <link>https://dev.to/rafaeljohn9/building-a-monty-bytecode-interpreter-a-hands-on-approach-to-learning-stacks-and-queues-52m1</link>
      <guid>https://dev.to/rafaeljohn9/building-a-monty-bytecode-interpreter-a-hands-on-approach-to-learning-stacks-and-queues-52m1</guid>
      <description>&lt;h2&gt;
  
  
  Understanding the Monty Bytecode Interpreter: A Comprehensive Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;In the realm of programming languages and interpreters, the Monty Bytecode Interpreter stands out as a valuable tool for learning and mastering core computer science concepts such as &lt;code&gt;stacks&lt;/code&gt;, &lt;code&gt;queues&lt;/code&gt;, and &lt;code&gt;data manipulation&lt;/code&gt;. This article delves into what the Monty Bytecode Interpreter is, why it is significant, and how recreating it can significantly enhance your technical skills.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the Monty Bytecode Interpreter?
&lt;/h3&gt;

&lt;p&gt;The Monty Bytecode Interpreter is a simple interpreter designed to execute a custom bytecode language. It is a part of a learning exercise, often associated with educational programming courses or challenges. The Monty Bytecode Interpreter operates on a stack-based virtual machine, which interprets a series of bytecode instructions to perform various operations.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Features
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stack-Based Architecture&lt;/strong&gt;: The interpreter relies on a stack for executing bytecode instructions. This stack-based model is fundamental in understanding how low-level operations are performed in various computing environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bytecode Language&lt;/strong&gt;: Monty Bytecode is a minimalistic language consisting of a set of predefined instructions. These instructions are designed to demonstrate basic control flow and data manipulation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Virtual Machine&lt;/strong&gt;: The interpreter simulates a virtual machine environment where bytecode instructions are executed sequentially.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Components of the Monty Bytecode Interpreter
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bytecode Instructions&lt;/strong&gt;: The interpreter processes a set of bytecode instructions such as &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;pop&lt;/code&gt;, &lt;code&gt;pall&lt;/code&gt;, &lt;code&gt;pint&lt;/code&gt;, etc. Each instruction performs a specific operation on the stack or prints output.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stack Operations&lt;/strong&gt;: The Monty Bytecode Interpreter primarily uses a stack to manage data. Common stack operations include &lt;code&gt;push&lt;/code&gt; (to add an item to the stack) and &lt;code&gt;pop&lt;/code&gt; (to remove the top item from the stack).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Execution Loop&lt;/strong&gt;: The interpreter reads bytecode instructions and executes them in a loop. It maintains a program counter to keep track of the current instruction being executed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Error Handling&lt;/strong&gt;: Proper error handling mechanisms are essential for interpreting invalid instructions or handling stack underflow/overflow situations.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Why Recreate the Monty Bytecode Interpreter?
&lt;/h3&gt;

&lt;p&gt;Recreating the Monty Bytecode Interpreter is a valuable exercise for several reasons:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Deepens Understanding of Stacks&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The stack is a fundamental data structure used extensively in computer science. By implementing a stack-based interpreter, you gain hands-on experience with stack operations such as push, pop, and peek. Understanding how the stack manages data in real-time helps solidify your knowledge of this crucial data structure.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Enhances Knowledge of Queues&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;While the Monty Bytecode Interpreter is primarily stack-based, you might integrate queues to handle certain operations or manage instructions. Learning how to implement and use queues in conjunction with stacks provides a broader perspective on data management and manipulation.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Improves Bytecode Interpretation Skills&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Writing an interpreter requires you to understand how to parse and execute low-level instructions. This exercise enhances your skills in interpreting and executing bytecode, which is relevant for understanding how modern programming languages work at a fundamental level.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. &lt;strong&gt;Boosts Debugging and Error-Handling Abilities&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Implementing a bytecode interpreter involves addressing various edge cases, such as invalid instructions or stack underflows. Developing robust error-handling mechanisms sharpens your debugging skills and prepares you for real-world programming challenges.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. &lt;strong&gt;Strengthens Algorithmic and System Design Skills&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Designing and implementing an interpreter involves algorithmic thinking and system design. You need to create efficient algorithms for instruction execution and design a system that manages data effectively. This exercise improves your overall problem-solving and system design abilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The Monty Bytecode Interpreter is more than just a simple interpreter; it is a powerful tool for learning and mastering fundamental computer science concepts. By recreating it, you not only enhance your understanding of stacks and queues but also improve your debugging, algorithmic, and system design skills. Whether you're a beginner or an experienced developer, this exercise offers valuable insights into the inner workings of interpreters and virtual machines.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>datastructures</category>
      <category>softwareengineering</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Exploring Lesser-Known but Essential Git Commands</title>
      <dc:creator>JohnKagunda</dc:creator>
      <pubDate>Mon, 05 Aug 2024 12:30:28 +0000</pubDate>
      <link>https://dev.to/rafaeljohn9/exploring-lesser-known-but-essential-git-commands-4ipf</link>
      <guid>https://dev.to/rafaeljohn9/exploring-lesser-known-but-essential-git-commands-4ipf</guid>
      <description>&lt;p&gt;While many are familiar with basic commands like &lt;code&gt;git add&lt;/code&gt;, &lt;code&gt;git commit&lt;/code&gt;, and &lt;code&gt;git push&lt;/code&gt;, there are several lesser-known commands that can be equally important. Understanding these commands can help you become more efficient and effective in your version control practices.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;git stash&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Imagine you're working on a feature, and suddenly you need to switch branches to fix a critical bug. You don't want to commit incomplete work, but you also don't want to lose your changes. This is where &lt;code&gt;git stash&lt;/code&gt; comes in handy. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command:&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;git stash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command temporarily shelves (or stashes) your changes, allowing you to switch branches without committing. Later, you can reapply your stashed changes with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;code&gt;git cherry-pick&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Have you ever committed a bug fix on one branch and then realized that the same fix is needed on another branch? Instead of copying and pasting the changes, you can use &lt;code&gt;git cherry-pick&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command:&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;git cherry-pick &amp;lt;commit-hash&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command applies the changes from a specific commit to your current branch. It’s like plucking a cherry from one tree and placing it on another!&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;code&gt;git bisect&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;When trying to find the commit that introduced a bug, &lt;code&gt;git bisect&lt;/code&gt; can be a lifesaver. It uses a binary search algorithm to efficiently pinpoint the problematic commit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command:&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;git bisect start
git bisect bad
git bisect good &amp;lt;commit-hash&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Git will then check out different commits, asking you to mark them as good or bad, until it identifies the offending commit.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;code&gt;git reflog&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Ever made a mistake and wished you could turn back time? &lt;code&gt;git reflog&lt;/code&gt; is your time machine. It logs every change made to the tip of branches and allows you to recover lost commits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command:&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;git reflog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then use &lt;code&gt;git checkout &amp;lt;commit-hash&amp;gt;&lt;/code&gt; or &lt;code&gt;git reset --hard &amp;lt;commit-hash&amp;gt;&lt;/code&gt; to revert to a previous state.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. &lt;code&gt;git blame&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Want to know who made a specific change in a file? &lt;code&gt;git blame&lt;/code&gt; can tell you. It shows the commit hash, author, and timestamp for each line in a file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command:&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;git blame &amp;lt;file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be useful for tracking down when a change was introduced and who made it.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. &lt;code&gt;git clean&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;When your working directory gets cluttered with untracked files, &lt;code&gt;git clean&lt;/code&gt; can help you tidy up. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command:&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;git clean &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-f&lt;/code&gt; flag stands for force, as Git wants to ensure you really want to remove those files. For added caution, use the &lt;code&gt;-n&lt;/code&gt; flag to perform a dry run and see what would be removed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clean &lt;span class="nt"&gt;-n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7. &lt;code&gt;git log --graph --oneline&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;If you want a visual representation of your commit history, &lt;code&gt;git log --graph --oneline&lt;/code&gt; is perfect. It provides a concise, graphical view of your branch history.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command:&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;git log &lt;span class="nt"&gt;--graph&lt;/span&gt; &lt;span class="nt"&gt;--oneline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is particularly useful for understanding complex branching and merging histories.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. &lt;code&gt;git shortlog&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;For a summary of contributions by author, &lt;code&gt;git shortlog&lt;/code&gt; is very helpful. It groups commit messages by author and can give you an overview of who has contributed what.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command:&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;git shortlog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the &lt;code&gt;-s&lt;/code&gt; flag to see a summary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git shortlog &lt;span class="nt"&gt;-s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9. &lt;code&gt;git diff&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;While &lt;code&gt;git diff&lt;/code&gt; is commonly known, many don't use it to its full potential. It shows changes between commits, commit and working tree, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command:&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;git diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To compare changes between two branches:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git diff branch1..branch2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10. &lt;code&gt;git show&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;git show&lt;/code&gt; is a versatile command that shows various types of objects, including commits, trees, and tags.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command:&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;git show &amp;lt;object&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For instance, to see the details of a specific commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git show &amp;lt;commit-hash&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;By incorporating these lesser-known but powerful Git commands into your workflow, you can enhance your productivity and make your version control more effective.&lt;/p&gt;




&lt;p&gt;Feel free to explore these commands in your projects, and don't hesitate to refer back to this guide whenever you need a quick refresher. Git is an indispensable tool, and mastering it can significantly improve your development experience.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Avoid Common Pitfalls: Octocat's Tips for Better Git Commits🐙 🐱🐈</title>
      <dc:creator>JohnKagunda</dc:creator>
      <pubDate>Sat, 03 Aug 2024 11:52:38 +0000</pubDate>
      <link>https://dev.to/rafaeljohn9/avoid-common-pitfalls-octocats-tips-for-better-git-commits-5d1i</link>
      <guid>https://dev.to/rafaeljohn9/avoid-common-pitfalls-octocats-tips-for-better-git-commits-5d1i</guid>
      <description>&lt;p&gt;Well, if you are reading this article we can agree that our git commits are not what we are most proud of. Mostly, it's because of the idea that we are just putting up our code in GitHub or a remote repo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Quick Fact&lt;/em&gt;&lt;/strong&gt;: &lt;em&gt;Do you know you can make git commits without the use of GitHub, GitLab, or any remote repository?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Try it:&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;mkdir &lt;/span&gt;my_project
&lt;span class="nb"&gt;cd &lt;/span&gt;my_project
git init
&lt;span class="nb"&gt;touch &lt;/span&gt;README.md
git add README.md
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Added a README file"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have a git repository on your local machine, you can write code and commit some more with no worries. If you want to keep track just use &lt;code&gt;git log&lt;/code&gt; to see the commit history.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Then why do we need git commits?&lt;/em&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Well, commits just help you keep track of different versions of your code. It is like a time machine for your code. You can always go back to a previous version of your code if you want to.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Well, now with this ideology we can now all agree commits are important.
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Commit messages are like the ID of different versions of you. You wouldn't want to go to the past and when you try to check the different versions you, all you have as the ID is &lt;code&gt;Small changes&lt;/code&gt; or &lt;code&gt;WIP&lt;/code&gt;. That would be a nightmare.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;So what makes a good commit message?&lt;/em&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Short and sweet&lt;/strong&gt;: A commit message should be short and sweet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meaningful&lt;/strong&gt;: A commit message should be meaningful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent&lt;/strong&gt;: A commit message should be consistent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use the imperative mood&lt;/strong&gt;: A commit message should use the imperative mood.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Let's see comparisons between good commit messages and bad commit messages:
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Aspect&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Bad Commit Message&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Good Commit Message&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Clarity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"Fix"&lt;/td&gt;
&lt;td&gt;"Fix null pointer exception in user login"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Specificity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"Bug fix"&lt;/td&gt;
&lt;td&gt;"Fix bug causing crash when username is empty"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Context&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"Updated"&lt;/td&gt;
&lt;td&gt;"Update dependencies to latest versions"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Feature Addition&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"Added new feature"&lt;/td&gt;
&lt;td&gt;"Add search functionality to the product catalog"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Initial Commit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"Initial commit"&lt;/td&gt;
&lt;td&gt;"Initial commit: setup project structure and dependencies"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Well, now when it comes to maintaining your codebase with good commit history, you can always go back to a previous version of your code and see what you did in that commit.&lt;/li&gt;
&lt;li&gt;You can also see the commit message and understand what you did in that commit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;So, in conclusion, commit messages are important.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They help you keep track of different versions of your code.&lt;/li&gt;
&lt;li&gt;They help you understand what you did in that commit.&lt;/li&gt;
&lt;li&gt;They help you maintain your codebase.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, next time you make a commit, make sure you commit to its message first.&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>softwareengineering</category>
      <category>powerfuldevs</category>
    </item>
    <item>
      <title>If it quacks like a duck 🦆🐥</title>
      <dc:creator>JohnKagunda</dc:creator>
      <pubDate>Thu, 01 Aug 2024 08:37:54 +0000</pubDate>
      <link>https://dev.to/rafaeljohn9/if-it-quacks-like-a-duck-1fl8</link>
      <guid>https://dev.to/rafaeljohn9/if-it-quacks-like-a-duck-1fl8</guid>
      <description>&lt;p&gt;&lt;strong&gt;Duck typing is an interesting concept to learn and also very valuable when you understand it.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So what is duck typing?
&lt;/h2&gt;

&lt;p&gt;A famous concept was made to make understanding this simpler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if it quacks like a duck, then it is a duck
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, let's look at this using a simple 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;Duck&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;quack&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Quack!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Goose&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;quack&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Quack!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&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;bark&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Woof!&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 the example above, a duck &lt;code&gt;quacks&lt;/code&gt; as well as a goose, while a dog only &lt;code&gt;barks&lt;/code&gt;. According to duck typing, we can agree that a duck and a goose may as well both be ducks.&lt;/p&gt;

&lt;p&gt;So the next question is:&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is this important?
&lt;/h2&gt;

&lt;p&gt;Let's use already existing components &lt;code&gt;min&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt; inbuilt functions in Python.&lt;br&gt;
Duck typing is one of the reasons why they are so efficient in getting the minimum and the maximum values.&lt;/p&gt;
&lt;h3&gt;
  
  
  Comparability
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;min&lt;/code&gt; checks for the method &lt;code&gt;__lt__&lt;/code&gt; inside the object called, regardless of the class, while &lt;code&gt;max&lt;/code&gt; checks for the method &lt;code&gt;__gt__&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Iterability
&lt;/h3&gt;

&lt;p&gt;The collection passed to &lt;code&gt;min&lt;/code&gt; or &lt;code&gt;max&lt;/code&gt; must be iterable. This means it should implement the &lt;code&gt;__iter__&lt;/code&gt; method, which allows the function to traverse through the elements of the collection.&lt;/p&gt;

&lt;p&gt;Here is a simple 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;ComparableObject&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;value&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__lt__&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;other&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__gt__&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;other&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__repr__&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;return&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;ComparableObject(&lt;/span&gt;&lt;span class="si"&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;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ComparableObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ComparableObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ComparableObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;objects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&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="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# Outputs: ComparableObject(5)
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# Outputs: ComparableObject(20)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;ComparableObject&lt;/code&gt; implements the &lt;code&gt;__lt__&lt;/code&gt; and &lt;code&gt;__gt__&lt;/code&gt; methods, allowing instances of this class to be compared using the &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&lt;/code&gt; operators. This makes them suitable for use with &lt;code&gt;min&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Duck Typing in Action:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;When &lt;code&gt;min(objects)&lt;/code&gt; is called, Python checks if each element in &lt;code&gt;objects&lt;/code&gt; can be compared using the &lt;code&gt;&amp;lt;&lt;/code&gt; operator. It doesn't care about the type of the elements as long as they can be compared.&lt;/li&gt;
&lt;li&gt;Similarly, when &lt;code&gt;max(objects)&lt;/code&gt; is called, Python checks if each element can be compared using the &lt;code&gt;&amp;gt;&lt;/code&gt; operator.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because &lt;code&gt;ComparableObject&lt;/code&gt; implements the necessary comparison methods, &lt;code&gt;min&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt; work with instances of this class, demonstrating duck typing. The focus is on the presence of the required methods (&lt;code&gt;__lt__&lt;/code&gt; and &lt;code&gt;__gt__&lt;/code&gt;), not on the specific type of the objects.&lt;/p&gt;

&lt;p&gt;In conclusion, duck typing is a powerful and flexible programming paradigm that emphasizes an object's behavior over its explicit type. &lt;/p&gt;

&lt;p&gt;This approach allows for more reusable and adaptable code, as seen in the seamless operation of Python's min and max functions. &lt;/p&gt;

&lt;p&gt;By focusing on the presence of necessary methods and attributes, duck typing promotes a more intuitive and efficient coding style, ultimately leading to cleaner and more maintainable codebases. &lt;/p&gt;

&lt;p&gt;Embracing duck typing can enhance your programming skills, making you a more versatile and effective developer in dynamically typed languages like Python.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>python</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Tackling Complex Backend Challenges: My Journey with HNG Internship</title>
      <dc:creator>JohnKagunda</dc:creator>
      <pubDate>Mon, 01 Jul 2024 05:03:34 +0000</pubDate>
      <link>https://dev.to/rafaeljohn9/tackling-complex-backend-challenges-my-journey-with-hng-internship-3fg</link>
      <guid>https://dev.to/rafaeljohn9/tackling-complex-backend-challenges-my-journey-with-hng-internship-3fg</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hello, tech enthusiasts! My name is Rafael John, and I am a full-stack developer with a passion for backend development. Recently, I faced a particularly challenging backend problem that tested my skills and determination. In this blog post, I’ll walk you through the problem, how I approached it, and the solution I implemented. Additionally, I'll share my excitement about starting my journey with the HNG Internship and why this opportunity is so important to me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;p&gt;The problem I encountered involved optimizing a complex data processing pipeline for a client project. The system was built using Python and Flask, with a MySQL database for storing processed data. The challenge was to reduce the processing time and improve the overall efficiency of the system. The existing solution was slow, and the client needed a faster, more reliable system.&lt;br&gt;
Breaking Down the Solution&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Analyzing the Bottlenecks&lt;br&gt;
The first step was to identify the main bottlenecks in the existing system. I used profiling tools to monitor the performance of each component in the pipeline. This helped me pinpoint areas where the system was slowing down.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Database Optimization&lt;br&gt;
I noticed that the database queries were a major bottleneck. To address this, I optimized the queries by adding appropriate indexes and restructuring the database schema. This significantly improved the query performance.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Efficient Data Processing
The data processing logic was another area that needed improvement. I refactored the code to use more efficient algorithms and data structures. Additionally, I implemented batch processing to handle large datasets more effectively.&lt;/li&gt;
&lt;li&gt;Asynchronous Processing
To further enhance performance, I integrated asynchronous processing using Celery and Redis. This allowed the system to handle multiple tasks concurrently, reducing the overall processing time.&lt;/li&gt;
&lt;li&gt;Caching Frequently Accessed Data
I implemented caching using Redis to store frequently accessed data. This reduced the load on the database and improved the system's response time.&lt;/li&gt;
&lt;li&gt;Testing and Deployment
After implementing the optimizations, I thoroughly tested the system to ensure it met the client's requirements. Finally, I deployed the updated system using Docker and Nginx, ensuring it was scalable and easy to maintain.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;The optimizations resulted in a significant reduction in processing time, from several hours to just under 30 minutes. The client was thrilled with the improved performance and reliability of the system.&lt;br&gt;
My Journey with HNG Internship&lt;/p&gt;

&lt;p&gt;I am incredibly excited to start my journey with the HNG Internship. This program is a fantastic opportunity to learn from industry experts and collaborate with other talented developers. The hands-on experience and mentorship provided by the HNG Internship will help me grow as a backend developer and tackle even more complex challenges in the future.&lt;/p&gt;

&lt;p&gt;The HNG Internship is not just about coding; it's about building a network, gaining real-world experience, and becoming a part of a vibrant community. If you're interested in learning more about the program, check out the HNG Internship website and HNG Premium.&lt;/p&gt;

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

&lt;p&gt;Solving complex backend challenges requires a combination of analytical thinking, technical skills, and perseverance. I am proud of the solution I developed for my client and excited about the journey ahead with the HNG Internship. This experience has reinforced my passion for backend development and my commitment to continuous learning and improvement.&lt;/p&gt;

&lt;p&gt;Thank you for reading, and I hope my story inspires you to tackle your own challenges with determination and creativity. Let's continue to learn and grow together!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Make your own music downloader website</title>
      <dc:creator>JohnKagunda</dc:creator>
      <pubDate>Tue, 11 Jun 2024 01:49:13 +0000</pubDate>
      <link>https://dev.to/rafaeljohn9/make-your-own-music-downloader-website-4o1p</link>
      <guid>https://dev.to/rafaeljohn9/make-your-own-music-downloader-website-4o1p</guid>
      <description>&lt;h2&gt;
  
  
  How I Built My Music Downloader Site
&lt;/h2&gt;

&lt;p&gt;Disclaimer: Services described in this post are in courtesies of &lt;br&gt;
the Service providers, codes described in this post may be used only for educational purposes&lt;/p&gt;

&lt;p&gt;Creating my music downloader site was an exciting and educational journey. I leveraged the Spotify API and Pytube to build a seamless experience for users who want to discover and download music. Here’s a detailed walkthrough of how I achieved this.&lt;br&gt;
Backend Development&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Integrating Spotify API&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first step was to integrate the Spotify API to fetch tracks and preview music. Setting up the Spotify component was straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Register your application: Sign up on the Spotify Developer Dashboard and create a new application to get your API credentials.&lt;/li&gt;
&lt;li&gt;Get an access token: Use the credentials to request an access token. This token will authenticate your API requests.&lt;/li&gt;
&lt;li&gt;Fetch tracks: Use the access token to query the Spotify API and fetch tracks based on user search inputs. Spotify's rich API provides detailed information including track previews, album art, and links to Spotify.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a quick code snippet on how you can achieve this:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;python&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

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

# Define the API endpoint and access token
SPOTIFY_API_URL = 'https://api.spotify.com/v1/search'
access_token = 'YOUR_ACCESS_TOKEN'

def search_spotify(query):
    headers = {
        'Authorization': f'Bearer {access_token}'
    }
    params = {
        'q': query,
        'type': 'track'
    }
    response = requests.get(SPOTIFY_API_URL, headers=headers, params=params)
    return response.json()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Creating the API Endpoint&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once I had the data from Spotify, I created an endpoint using Flask to serve this data to my frontend:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;python&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/search', methods=['GET'])
def search():
    query = request.args.get('query')
    results = search_spotify(query)
    return jsonify(results)

if __name__ == '__main__':
    app.run(debug=True)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Implementing the Download Option with Pytube&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The next challenge was to enable downloading the music. I used Pytube to fetch music from YouTube based on the track title and artist:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;python&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from pytube import YouTube
from io import BytesIO

def download_youtube_audio(query):
    # Find the YouTube video using the query
    yt = YouTube(f'https://www.youtube.com/results?search_query={query}')
    video = yt.streams.filter(only_audio=True).first()

    # Download the audio to a BytesIO buffer
    buffer = BytesIO()
    video.stream_to_buffer(buffer)
    buffer.seek(0)

    return buffer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By saving the audio in a buffer (using BytesIO), I was able to transport this buffer through the API endpoint, thus overcoming the challenge of file directory dependency.&lt;/p&gt;

&lt;p&gt;Here’s how the Flask endpoint looked for handling the download:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;python&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@app.route('/download', methods=['GET'])
def download():
    track_title = request.args.get('track_title')
    artist = request.args.get('artist')
    query = f"{track_title} {artist}"
    audio_buffer = download_youtube_audio(query)

    return send_file(audio_buffer, as_attachment=True, download_name=f"{track_title}.mp3", mimetype='audio/mpeg')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Frontend Integration
&lt;/h3&gt;

&lt;p&gt;On the Frontend, when a user searches for a music track, an API request is sent to my backend API which queries the Spotify API. The results, including music images, previews, and direct Spotify links, are displayed to the user.&lt;/p&gt;

&lt;p&gt;When the user wants to download a track, they specify the track title and artist for accuracy. An API request is then sent to the backend, which uses Pytube to fetch and deliver the audio file.&lt;br&gt;
Conclusion&lt;/p&gt;

&lt;p&gt;Building this site was a rewarding experience, combining several technologies to provide a useful service. For a more detailed post-mortem, check out &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.linkedin.com%2Fposts%2Fjohn-kagunda-232961270_post-mortem-for-atubidypro-recently-i-activity-7206101779967565825-2phr%3Futm_source%3Dshare%26utm_medium%3Dmember_desktop" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.linkedin.com%2Fposts%2Fjohn-kagunda-232961270_post-mortem-for-atubidypro-recently-i-activity-7206101779967565825-2phr%3Futm_source%3Dshare%26utm_medium%3Dmember_desktop" alt="my LinkedIn post."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also explore the site &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/www.johnmkagunda.me%2Fmusic-search" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/www.johnmkagunda.me%2Fmusic-search" alt="here"&gt;&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>development</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
