<?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: Antony Oduor</title>
    <description>The latest articles on DEV Community by Antony Oduor (@anoduor).</description>
    <link>https://dev.to/anoduor</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%2F1461273%2F633ee9c9-6350-4283-a4d2-85aea7ef7a64.jpeg</url>
      <title>DEV Community: Antony Oduor</title>
      <link>https://dev.to/anoduor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anoduor"/>
    <language>en</language>
    <item>
      <title>The Partnership Paradox: Why AI Is Struggling to Replace Human Judgment in Software Development</title>
      <dc:creator>Antony Oduor</dc:creator>
      <pubDate>Tue, 08 Jul 2025 08:29:04 +0000</pubDate>
      <link>https://dev.to/anoduor/the-partnership-paradox-why-ai-is-struggling-to-replace-human-judgment-in-software-development-1cl2</link>
      <guid>https://dev.to/anoduor/the-partnership-paradox-why-ai-is-struggling-to-replace-human-judgment-in-software-development-1cl2</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw3ve91nsiy1ty7savpkf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw3ve91nsiy1ty7savpkf.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AI is taking over. I cannot remember how many times I have heard this sentiment over the past week alone. While it is true that AI might be taking over, there has been an interesting overlap dragging on for the last two years where work that was supposedly going to be replaced by AI has not only thrived but evolved to be more effective when AI is paired with human expertise.&lt;/p&gt;

&lt;p&gt;I would like to offer an alternative perspective on what I think is actually happening. Yes, AI is gaining traction, most notably in big tech, but here is where it gets interesting. While big tech companies are actually leading AI adoption in development practices, they are doing it much more carefully than the rest of us. They have stable systems that have been in place for the longest time, and while the rest of the world moves faster and adopts newer languages and technologies, big tech usually has to move slower due to legacy systems that might not be optimal but offer the best return on investment with minimal effort compared to heavy rewrites. This cautious approach, ironically, might be protecting them from some of the pitfalls I am about to describe.&lt;/p&gt;

&lt;p&gt;Within the startup world, using AI almost exclusively might be setting yourself up for significant challenges. First, you are just trying to get to your first hundred customers who need to find enough value to stick with your product. Given the way machines approach work, it is a double-edged sword. Sure, you will move faster within the first two months, but your code base will quickly begin to feel like a decade-old piece of sellotape connecting components with virtually zero separation of concerns. Recent data shows that AI-generated code has led to an 8-fold increase in code duplication and a 7.2% decrease in delivery stability. While we in the startup space need to quickly pivot and iterate, it becomes much harder to do so when you are replacing whole parts entirely. This is not just about immediate failure. It is about accumulating technical debt that becomes increasingly expensive to maintain.&lt;/p&gt;

&lt;p&gt;Who am I? I am a software developer who has used AI both by surrendering control and working as partners. As soon as I surrendered control in a few individual projects, I realized that the project worked, but bugs kept popping up. I spoke to a colleague and they provided the solution of using AI to write the tests first. On the next iteration. I wrote the tests first and let AI do its thing. The outcome was amazing, but only at first. I went into the code base only to find single-function files as big as five hundred lines. In the software world we usually say that code is written for other human beings, but since I was not counting on another human to debug the code I had entrusted to AI, I saw no problem having those huge functions.&lt;/p&gt;

&lt;p&gt;It was not until my intelligent counterpart was told to go and change the position and color of an overlay that I began to hate my life. A few prompts later, I found myself asking it to return the code base to a certain point in history. What I quickly realized is that instead of trying to fix the code I told it to, it went out and swapped majority of the components with newer, more "advanced" features. On closer inspection, I realized that the more lines it added to fix a single problem, the more bugs it introduced. It was like cutting open another wound in your arm to offset the one in your thigh.&lt;/p&gt;

&lt;p&gt;I also learned the hard way that sometimes AI just seems to have a mind of its own. Remember when I gave it the tests? Yeah, when the tests do not work, your counterpart will rewrite them so that they work. I found a test case that had been adapted to make a "feature" work. What is a feature you did not account for? A bug. This is actually a critical blind spot in current AI development practices. AI will modify tests to fit the code rather than maintaining the integrity of what you are actually trying to test. It is like having a student change the answer key to match their wrong answers.&lt;/p&gt;

&lt;p&gt;Do not get me wrong, there are bugs that should be nowhere near a software product, but sometimes a bug might just creep in that gives your product a certain refinement you might not have noticed on your own. That is a strength of AI I have fallen in love with. It can stumble upon unexpected solutions that work better than what you initially planned.&lt;/p&gt;

&lt;p&gt;What am I advocating for? While I am a fan of AI, I feel that as it stands, it serves you better when you know what you are aiming for. AI will use the path of least resistance to introduce a feature, and this will end up costing you in the end. If you have no idea of the emergent effects it introduces by writing code in a certain way, then you will end up with a program that ideally works but will ultimately be too costly for a startup to recover from. You are not Google or Facebook who have been in the game long enough to pay off any cyber threats from zero-day discoveries, so use your power wisely.&lt;/p&gt;

&lt;p&gt;Here is what I have learned works: using AI to quickly iterate not just on business outcomes, but also on alternative implementations. Organizations that implement collaborative AI solutions are seeing productivity increases of up to 40%, but the key word here is "collaborative." The sweet spot seems to be where human judgment guides AI capabilities rather than the other way around. AI is excellent at generating options and handling repetitive tasks, but it still needs human context to understand what actually matters for your business.&lt;/p&gt;

&lt;p&gt;I should mention that AI coding tools are evolving rapidly. My experiences from even a few months ago may not reflect the current state of the technology. But the fundamental principle remains: while AI can amplify your capabilities dramatically, it is important to realize that in the end, all logic and no intuition is not good for your business.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The 600-Line Controller That Changed How I Think About Code</title>
      <dc:creator>Antony Oduor</dc:creator>
      <pubDate>Thu, 29 May 2025 09:37:47 +0000</pubDate>
      <link>https://dev.to/anoduor/the-600-line-controller-that-changed-how-i-think-about-code-39k5</link>
      <guid>https://dev.to/anoduor/the-600-line-controller-that-changed-how-i-think-about-code-39k5</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp295hpb2zs9s21ovjbjj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp295hpb2zs9s21ovjbjj.jpg" alt="refactoring for scalability" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Recently, I kicked off work on a new application. While I cannot share all the details just yet, I &lt;em&gt;can&lt;/em&gt; talk about how the project turned into a crash course in scalable software design—and how that journey ended up as a talk at the Kisumu Gophers Meetup.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack (and the Problem)
&lt;/h2&gt;

&lt;p&gt;The stack:&lt;br&gt;
&lt;strong&gt;Laravel + React + Inertia.js&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The challenge:&lt;br&gt;
&lt;strong&gt;A 600-line controller packed with tangled business logic, database calls, and view rendering code—all in one place.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;&lt;br&gt;
Since I do not know yet what I am allowed to share from the project, I will use a very simplistic example (the boring posts from a blog. I could have gone the Todo way but we could always aim higher) but do not let that fool you—the example will still be valid.&lt;/p&gt;

&lt;p&gt;Here is an example snippet from a controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Inside PostsController.php&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$validated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s1"&gt;'title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'content'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'image'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'nullable|image'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;

    &lt;span class="nv"&gt;$post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$validated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$validated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'content'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'image'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'image'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'images'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$path&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nc"&gt;ActivityLogger&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Post created by user "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'posts.index'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'success'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Post created!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works. But it is doing &lt;em&gt;way too much.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The controller handles validation, database interaction, file uploads, and logging—all responsibilities that should be separated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seeing the Problem Clearly
&lt;/h2&gt;

&lt;p&gt;That controller was only the beginning, but it was a warning sign. If we kept building like this, the app would become a nightmare to maintain.&lt;/p&gt;

&lt;p&gt;I had read about Domain-Driven Design (DDD) before, but honestly? I had not truly practiced it. Like many developers, I had leaned on the framework to handle most of the application structure. Laravel is powerful, but it does not stop you from writing tightly coupled spaghetti code.&lt;/p&gt;

&lt;p&gt;That is when we hit pause. As a team, we asked: &lt;strong&gt;What if we treated Laravel as just a delivery mechanism?&lt;/strong&gt; What if we moved the &lt;em&gt;actual&lt;/em&gt; business logic into its own clean layer?&lt;/p&gt;

&lt;p&gt;Spoiler: That decision changed everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our Refactoring Strategy
&lt;/h2&gt;

&lt;p&gt;We introduced a &lt;code&gt;/src&lt;/code&gt; directory to contain our domain logic. Each domain had its own folder with services, actions, policies, and contracts. Controllers became light, focused, and boring—in the best way.&lt;/p&gt;

&lt;h3&gt;
  
  
  The cleaner and clearer separation of concerns:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// PostsController.php&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;CreatePostRequest&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;postService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validated&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'image'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'posts.index'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'success'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Post created!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/Posts/Services/PostService.php&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;createPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;?UploadedFile&lt;/span&gt; &lt;span class="nv"&gt;$image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="s1"&gt;'title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'content'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'content'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'user_id'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;uploadService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;activityLogger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Post created by user "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each class does one thing. That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Predictable, isolated changes&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Easier debugging&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rapid, low-risk feature additions&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Need to add file uploads for another domain? Reuse the upload service—no cross-domain contamination.&lt;/p&gt;

&lt;h2&gt;
  
  
  Borrowing from DDD (Without Going Full DDD)
&lt;/h2&gt;

&lt;p&gt;We did not follow DDD by the book. There were no aggregates or value objects (yet). But we embraced the &lt;em&gt;principles&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear separation between infrastructure and domain&lt;/li&gt;
&lt;li&gt;Thin controllers&lt;/li&gt;
&lt;li&gt;Explicit service layers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It was not just an academic exercise. The app instantly became easier to work with. There was a point where we realized we needed three more developers, and onboarding the new team members became significantly smoother.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sharing the Journey
&lt;/h2&gt;

&lt;p&gt;This experience left such an impression that I decided to share it with my local community—the &lt;strong&gt;Kisumu Gophers Meetup&lt;/strong&gt;. Although it is a Go-focused group, my talk was not about PHP or Laravel. It was about architecture, mindset, and patterns that transcend languages.&lt;/p&gt;

&lt;p&gt;I focused on the &lt;strong&gt;Repository Pattern&lt;/strong&gt; as an entry point for scalable thinking. And to my surprise, many developers in the room had never encountered these ideas. What I assumed was common knowledge turned out to be eye-opening.&lt;/p&gt;

&lt;p&gt;Here is a simplified example I shared:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;PostRepositoryInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EloquentPostRepository&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;PostRepositoryInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;Post&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even abstracting the data layer like this helps you &lt;em&gt;think&lt;/em&gt; in terms of contracts, not implementations—making your app more adaptable in the long run. Depending on an interface allows you the freedom to have different implementations that can be switched depending on the context.&lt;/p&gt;

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

&lt;p&gt;This whole experience reminded me that &lt;strong&gt;real-world experience is often the best teacher.&lt;/strong&gt; You can read all the books and blog posts you want—but it is when you are knee-deep in messy code, trying to make sense of it all, that the lessons really stick.&lt;/p&gt;

&lt;p&gt;And the best part? Sharing those lessons helps the entire community grow.&lt;/p&gt;

&lt;p&gt;Whether you are writing Laravel or Go, it pays to slow down, clean up, and think about the long-term health of your code. In this age of AI, it is easy to say I will let AI do the whole work. But at some point, the AI loses the context of an awfully long feature, and then you are left with a huge jumbled mess that you have to walk through.&lt;/p&gt;




&lt;p&gt;💬 Have you had your own "refactor epiphany"? I would love to hear how you approach controller cleanup and scalable design in your stack.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Bring Your Favorite Linux Commands to Windows Command Prompt in Minutes!</title>
      <dc:creator>Antony Oduor</dc:creator>
      <pubDate>Thu, 31 Oct 2024 06:20:10 +0000</pubDate>
      <link>https://dev.to/anoduor/bring-your-favorite-linux-commands-to-windows-command-prompt-in-minutes-4hbh</link>
      <guid>https://dev.to/anoduor/bring-your-favorite-linux-commands-to-windows-command-prompt-in-minutes-4hbh</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjuprylqayknvfvqsc3u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjuprylqayknvfvqsc3u.png" alt="an image displaying the results of running a linux command on a windows command prompt" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you live a double life where part of your day is spent on Linux and the other part on Windows, I’m about to make things a lot easier. Ever come home, open your Windows machine, type &lt;code&gt;ls&lt;/code&gt; by reflex, only to see an error message? Don’t worry; you're not alone. With a small tool called &lt;strong&gt;BusyBox&lt;/strong&gt;, you can bring familiar Linux commands like &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;pwd&lt;/code&gt;, and &lt;code&gt;grep&lt;/code&gt; to Windows Command Prompt, no WSL or Cygwin needed. Here’s how to set it up quickly so you can switch between Windows and Linux environments with ease.&lt;/p&gt;

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

&lt;p&gt;BusyBox is a tiny, standalone executable that packages many Unix commands. Originally made for embedded systems, it combines dozens of commands into one lightweight program. You can think of it as a Swiss Army knife for Linux commands on Windows! With BusyBox, you get familiar commands without needing a complex setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started with BusyBox on Windows
&lt;/h3&gt;

&lt;p&gt;Here’s a quick guide to set up BusyBox, allowing you to use commands like &lt;code&gt;ls&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt; in Windows Command Prompt just as you would in Linux.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Download BusyBox
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://frippery.org/busybox/" rel="noopener noreferrer"&gt;BusyBox for Windows&lt;/a&gt; and download the standalone executable.&lt;/li&gt;
&lt;li&gt;Place &lt;code&gt;busybox.exe&lt;/code&gt; in a folder (for example, &lt;code&gt;C:\busybox\&lt;/code&gt;). I like to keep all my custom tools under "C:\Program Files\" so I’d put it in &lt;code&gt;C:\Program Files\busybox\&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Step 2: Add BusyBox to Your System Path
&lt;/h4&gt;

&lt;p&gt;To make BusyBox accessible from any Command Prompt location, add it to your system’s PATH.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Search for “Environment Variables” in the Windows Start menu and open &lt;strong&gt;Edit the system environment variables&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;System Properties&lt;/strong&gt; window, click on &lt;strong&gt;Environment Variables…&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;System variables&lt;/strong&gt;, locate the &lt;strong&gt;Path&lt;/strong&gt; variable, select it, and click &lt;strong&gt;Edit&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add the directory where you saved &lt;code&gt;busybox.exe&lt;/code&gt; (like &lt;code&gt;C:\Program Files\busybox\&lt;/code&gt;) and click &lt;strong&gt;OK&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To check if it worked, open a new Command Prompt and type &lt;code&gt;busybox ls&lt;/code&gt;. If you see a directory listing, BusyBox is set up correctly! If not, double-check the PATH setup.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Create Symlinks for Linux Commands
&lt;/h4&gt;

&lt;p&gt;Right now, you’d need to prefix every command with &lt;code&gt;busybox&lt;/code&gt;, as in &lt;code&gt;busybox ls&lt;/code&gt; or &lt;code&gt;busybox clear&lt;/code&gt;. But we can simplify things further by creating &lt;strong&gt;symbolic links&lt;/strong&gt; (symlinks) so that typing &lt;code&gt;ls&lt;/code&gt; or &lt;code&gt;clear&lt;/code&gt; works as you’d expect. Here’s how:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Command Prompt as Administrator. Search for "cmd," right-click, and select &lt;strong&gt;Run as administrator&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Run these commands to create symlinks for frequently used commands:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   mklink "C:\Windows\System32\ls.exe" "C:\path\to\busybox.exe"
   mklink "C:\Windows\System32\pwd.exe" "C:\path\to\busybox.exe"
   mklink "C:\Windows\System32\grep.exe" "C:\path\to\busybox.exe"
   mklink "C:\Windows\System32\cat.exe" "C:\path\to\busybox.exe"
   mklink "C:\Windows\System32\clear.exe" "C:\path\to\busybox.exe"
   mklink "C:\Windows\System32\rm.exe" "C:\path\to\busybox.exe"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;C:\path\to\busybox.exe&lt;/code&gt; with the actual path where you saved &lt;code&gt;busybox.exe&lt;/code&gt;. For example, on my machine, I’d use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   mklink "C:\Windows\System32\ls.exe" "C:\Program Files\busybox\busybox.exe"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each command above creates a symlink, meaning &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;pwd&lt;/code&gt;, &lt;code&gt;grep&lt;/code&gt;, etc., will point to BusyBox automatically, no prefix needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip&lt;/strong&gt;: BusyBox has many commands available! To see a full list, type:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;You can repeat the &lt;code&gt;mklink&lt;/code&gt; command for any other commands you want to use directly.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 4: Test Your New Linux Commands
&lt;/h4&gt;

&lt;p&gt;After setting up the symlinks, open a new Command Prompt window and try a few commands. Run &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;pwd&lt;/code&gt;, or &lt;code&gt;grep&lt;/code&gt; just as you would on Linux. Here are a few examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ls
pwd
grep "text" file.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see normal output without errors, congrats! You’ve just added Linux functionality to your Windows Command Prompt.&lt;/p&gt;

&lt;h4&gt;
  
  
  Optional: Automate with a Batch File
&lt;/h4&gt;

&lt;p&gt;If you have many symlinks to create, save time by placing all &lt;code&gt;mklink&lt;/code&gt; commands in a &lt;code&gt;.cmd&lt;/code&gt; batch file. For example, create &lt;code&gt;setup_busybox.cmd&lt;/code&gt;, add your commands, then run the file once to set up all symlinks at once. You can run &lt;code&gt;.cmd&lt;/code&gt; files by simply writing their name(e.g: setup_busybox.cmd) on the command prompt then pressing the &lt;code&gt;ENTER&lt;/code&gt; key.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;By using BusyBox and symlinks, you can now run common Linux commands on Windows easily. No complex environments, just a lightweight tool and a few shortcuts. BusyBox covers most basic Linux commands, but if you need more specialized tools, consider options like Git Bash or WSL. &lt;/p&gt;

&lt;p&gt;Give it a try and enjoy a unified command-line experience on Windows!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Great Framework Debate. Balancing Flexibility and Efficiency in Software Development.</title>
      <dc:creator>Antony Oduor</dc:creator>
      <pubDate>Tue, 24 Sep 2024 08:41:26 +0000</pubDate>
      <link>https://dev.to/anoduor/the-great-framework-debate-balancing-flexibility-and-efficiency-in-software-development-5bbn</link>
      <guid>https://dev.to/anoduor/the-great-framework-debate-balancing-flexibility-and-efficiency-in-software-development-5bbn</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz55ryyecsauc4bafi3aj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz55ryyecsauc4bafi3aj.png" alt="An image depicting the struggle one faces when they begin a software project. Should they use a framework or not?" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the ever-evolving world of software development, programmers often find themselves at a crossroads: should they build their applications from the ground up, or should they leverage existing frameworks? This decision is not unlike the choice faced by manufacturers when deciding between artisanal craftsmanship and industrial production lines. Both approaches have their merits, and the best choice often depends on the specific needs of the project at hand.&lt;/p&gt;

&lt;p&gt;Whether you're a beginner just starting your coding journey or an experienced developer contemplating your next project, understanding the nuances of this debate is crucial. In this article, we'll explore the pros and cons of using frameworks, dive into the evolution of programming needs, and provide insights to help you make informed decisions about your development approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Evolution of Programming Needs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  From Solitary to Connected
&lt;/h3&gt;

&lt;p&gt;To understand the framework debate, we need to look at how programming needs have evolved over time. Let's take a trip down memory lane:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Era of Standalone Applications&lt;/strong&gt;: Once upon a time, in the not-so-distant past, computer applications were largely solitary affairs. Remember those simple mobile games where you were the sole participant, battling against a computer-controlled opponent? The thrill came from the occasional goal scored, sending dopamine rushing through your brain. It didn't matter if you were the worst player on the planet; the game served its purpose.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Rise of the Connected Generation&lt;/strong&gt;: As technology advanced and a new generation of users emerged, these simple games quickly lost their appeal. By the tender age of ten, many young users had conquered all levels of existing games. Unlike human opponents who naturally adapt and improve, computer-controlled adversaries remained static, limited by either computational power or the imagination of their creators.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Demand for Inter-connectivity&lt;/strong&gt;: Users began craving more dynamic, interconnected experiences. The focus shifted from playing against a computer to competing against other human beings across the globe. This shift mirrors what we've seen in other industries – just as consumers grew tired of one-size-fits-all products and began demanding customization and interactivity, software users began expecting more sophisticated, connected applications.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;As applications transitioned from standalone programs to interconnected systems, developers faced a new set of challenges that grew exponentially in complexity:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User Authentication&lt;/strong&gt;: How do we verify the identity of users accessing our system? This is akin to a manufacturing plant needing to implement security measures to ensure only authorized personnel can access different areas of the facility.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data Security&lt;/strong&gt;: Once users are connected, how do we ensure their data remains private and secure? This challenge is similar to a car manufacturer needing to protect proprietary designs as they collaborate with global partners.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability&lt;/strong&gt;: As user bases grow, how do we ensure our systems can handle increased load? This is comparable to a factory needing to ramp up production without compromising quality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cross-platform Compatibility&lt;/strong&gt;: With a myriad of devices and operating systems, how do we ensure a consistent experience across all platforms? This is like an automobile manufacturer ensuring their vehicles can operate efficiently in various climates and road conditions.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These challenges transformed what might have started as a simple game between friends into months of sleepless nights for developers. The burden on programmers continually increased as they grappled with these complex issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Case for Frameworks
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Efficiency and Standardization
&lt;/h3&gt;

&lt;p&gt;Frameworks in the programming world are analogous to assembly lines in manufacturing. They provide a structured, pre-built foundation upon which developers can build their applications. Here's how frameworks promote efficiency and standardization:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pre-built Components&lt;/strong&gt;: Frameworks come with a treasure trove of pre-built components that handle common tasks. For instance, instead of writing authentication systems from scratch for every project, a framework like Django provides a robust, tested system out of the box. This is similar to how car manufacturers use standardized parts across different models to increase efficiency and reduce costs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Standardized Practices&lt;/strong&gt;: Frameworks often enforce best practices and design patterns. This not only improves code quality but also makes it easier for developers to collaborate and understand each other's work. It's like how standardized manufacturing processes ensure consistent quality across different production lines or even different factories.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tested and Optimized Code&lt;/strong&gt;: The components provided by popular frameworks have been battle-tested by thousands of developers and optimized for performance. This is akin to how manufacturing equipment is refined and optimized over time to improve efficiency and reduce errors.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Adaptability and Maintenance
&lt;/h3&gt;

&lt;p&gt;Modern frameworks are designed with evolution in mind, much like how modern manufacturing plants are built to be flexible and adaptable:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Regular Updates&lt;/strong&gt;: Framework maintainers constantly work to support new technologies and programming paradigms. This allows developers to stay current without having to rewrite their entire code base. It's similar to how car manufacturers can update their assembly lines to incorporate new technologies or safety features without rebuilding the entire factory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Community-driven Improvements&lt;/strong&gt;: Popular frameworks benefit from a large community of developers who contribute improvements, fix bugs, and create helpful extensions. This collaborative effort is reminiscent of how industry consortia in manufacturing work together to develop new standards and technologies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Built-in Security Patches&lt;/strong&gt;: Frameworks often include security features and are regularly updated to address new vulnerabilities. This proactive approach to security is similar to how modern cars receive over-the-air updates to improve their safety and performance.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Case Against Frameworks
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Over-reliance and Skill Atrophy
&lt;/h3&gt;

&lt;p&gt;While frameworks offer numerous benefits, there's a potential downside to relying on them too heavily:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lack of Understanding Fundamental Concepts&lt;/strong&gt;: Developers who always work within the confines of a framework may struggle to understand the underlying principles of programming. This is like a modern car mechanic who can replace entire modules but doesn't understand the basic principles of internal combustion engines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Difficulty in Custom Implementations&lt;/strong&gt;: When faced with unique requirements that fall outside the framework's capabilities, over-reliant developers may struggle to implement custom solutions. This is akin to a manufacturing plant that can't produce custom orders because workers are only trained to operate specific machinery.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Challenges in Debugging Deep Issues&lt;/strong&gt;: When problems occur deep within the framework's code, developers who don't understand the underlying systems may find themselves at a loss. This is similar to how over-specialization in manufacturing can lead to difficulties when troubleshooting complex, systemic issues.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  One-Size-Fits-All Limitations
&lt;/h3&gt;

&lt;p&gt;Not all projects fit neatly into existing frameworks, and trying to force a square peg into a round hole can lead to problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unique Requirements&lt;/strong&gt;: Some projects have specific needs that are difficult to implement within the constraints of a framework. This is like trying to use a car assembly line to produce a spaceship – sometimes, custom solutions are necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance Overhead&lt;/strong&gt;: For simple applications, the additional features and abstractions provided by a framework can introduce unnecessary complexity and performance overhead. It's like using a massive industrial oven to bake a single cookie – overkill for the task at hand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Learning Curve&lt;/strong&gt;: Specialized frameworks often come with steep learning curves. The time spent learning a framework's intricacies could potentially be better spent developing a custom solution. This is comparable to the training time required for workers to operate complex, specialized machinery in a factory.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Balanced Approach
&lt;/h2&gt;

&lt;p&gt;The ideal approach combines the best of both worlds, much like how modern manufacturing often blends automated processes with handcrafted precision:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Understand the Basics&lt;/strong&gt;: Start with fundamentals, learning how to build from scratch with "void main(){}". This foundational knowledge is crucial, just as understanding basic engineering principles is essential for innovative car design.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Learn Common Patterns and Practices&lt;/strong&gt;: Familiarize yourself with standard design patterns and best practices. This knowledge transcends specific frameworks and provides a solid foundation for problem-solving.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Utilize Frameworks for Efficiency&lt;/strong&gt;: Leverage frameworks to handle common tasks and speed up development. This allows you to focus on solving unique problems specific to your application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Know When to Customize&lt;/strong&gt;: Be prepared to step outside the framework when necessary. Understanding when to build custom solutions is a valuable skill, similar to knowing when a manufacturing process needs to be custom-designed for a specific product.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Visual Representation: Time vs. Project Progress
&lt;/h2&gt;

&lt;p&gt;To better understand the trade-offs between different development approaches, let's look at a visual representation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnkq82wkdnw4835i28adt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnkq82wkdnw4835i28adt.png" alt="A graph indicating the time it takes to develop a project. It compares the curves for all three approaches" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This graph compares two main variables:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Time (X-axis)&lt;/strong&gt;: This represents the duration of the project, from its inception to completion and beyond. It includes the initial learning period, development time, and long-term maintenance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Project Progress / Functionality (Y-axis)&lt;/strong&gt;: This represents the amount of functionality implemented or the overall progress of the project. As we move up the Y-axis, more features are completed, and the project becomes more fully realized.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The three lines on the graph represent different approaches to development:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Custom Code (Red line)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Starts with a gentler slope, indicating slower initial progress as developers build everything from scratch.&lt;/li&gt;
&lt;li&gt;Gradually accelerates as the foundation is laid, showing faster progress in later stages.&lt;/li&gt;
&lt;li&gt;Ends at a high point, suggesting great flexibility and customization in the long term.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Framework (Green line)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Begins with a steep learning curve (shown by the initial sharp rise), representing the time needed to learn the framework.&lt;/li&gt;
&lt;li&gt;After the learning phase, progress is rapid (shown by the subsequent sharp incline), as pre-built components speed up development.&lt;/li&gt;
&lt;li&gt;The line flattens out towards the end, suggesting potential limitations in highly specialized or unique requirements.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Balanced Approach (Blue dashed line)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Starts between the custom and framework approaches, indicating a mix of learning framework basics and custom coding.&lt;/li&gt;
&lt;li&gt;Progresses steadily, benefiting from both framework efficiencies and custom solutions where needed.&lt;/li&gt;
&lt;li&gt;Ends at a high point, suggesting good long-term flexibility and functionality.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Key points illustrated by the graph:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Initial Learning Curve&lt;/strong&gt;: The annotation highlights the steeper initial curve for the framework approach, representing the time invested in learning the framework's structure and conventions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Long-term Flexibility&lt;/strong&gt;: Near the end of the graph shows how custom code and the balanced approach may offer more flexibility for specialized requirements in the long run.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Development Speed&lt;/strong&gt;: The steepness of each line represents the speed of development. The framework approach shows faster development after the initial learning period, while custom code has a more gradual but steady pace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Project Completion&lt;/strong&gt;: All approaches eventually reach the top of the graph, indicating project completion, but they take different paths to get there.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Making the Right Choice for Your Project
&lt;/h2&gt;

&lt;p&gt;When deciding between custom coding, using a framework, or adopting a balanced approach, consider the following factors:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Project Scope and Complexity&lt;/strong&gt;: For small, simple projects, custom coding might be quicker. For large, complex applications with standard features, a framework could save significant time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Team Expertise&lt;/strong&gt;: If your team is already proficient in a particular framework, leveraging that expertise could lead to faster development. However, if the team is skilled in low-level programming, custom solutions might be more efficient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Long-term Maintenance&lt;/strong&gt;: Consider who will maintain the project in the long run. Frameworks often have better documentation and a larger community for support, which can be crucial for long-term maintenance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance Requirements&lt;/strong&gt;: If your application has strict performance requirements, custom code might be necessary to optimize every aspect of the system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Time Constraints&lt;/strong&gt;: Tight deadlines might favor using a framework to get a working product quickly, while more flexible timelines allow for custom solutions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability Needs&lt;/strong&gt;: If you anticipate rapid growth, frameworks often provide built-in scalability features that could be time-consuming to implement from scratch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Budget&lt;/strong&gt;: Framework development can often be more cost-effective initially, but custom solutions might save money in the long run for very specific or long-lived projects.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;The debate between custom coding and using frameworks is not about finding a one-size-fits-all solution. Instead, it's about understanding the trade-offs and making informed decisions based on your specific project needs, team capabilities, and long-term goals.&lt;/p&gt;

&lt;p&gt;Remember, whether you're building a simple website or the next SpaceX launch system, the right tool for the job might be a framework, a custom solution, or a bit of both. The most successful developers, like the most innovative manufacturers, know how to blend the efficiency of standardized processes with the flexibility of custom solutions.&lt;/p&gt;

&lt;p&gt;As you embark on your next project, take the time to evaluate your needs, consider the long-term implications of your choices, and don't be afraid to adopt a balanced approach that leverages the strengths of both custom coding and frameworks. By doing so, you'll be well-equipped to navigate the complexities of modern software development and create solutions that are both efficient and flexible.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Drawing shapes on a computer terminal</title>
      <dc:creator>Antony Oduor</dc:creator>
      <pubDate>Tue, 09 Jul 2024 08:05:04 +0000</pubDate>
      <link>https://dev.to/anoduor/drawing-shapes-on-a-computer-terminal-1opk</link>
      <guid>https://dev.to/anoduor/drawing-shapes-on-a-computer-terminal-1opk</guid>
      <description>&lt;p&gt;Have you ever seen cool shapes on a computer screen and wondered how they were made? It's simpler than you might think! We're going to explore how to create these shapes step by step, even if you're new to programming.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites and Getting Started
&lt;/h3&gt;

&lt;p&gt;Before we begin, you'll need a basic understanding of how to write a computer program. We'll be using a programming language called Go (or Golang), but don't worry if you've never used it before. The concepts we cover here can be applied to other similar languages like C or Java.&lt;/p&gt;

&lt;p&gt;To follow along with the examples, you'll need to have Go installed on your computer. Here’s how you can set things up:&lt;/p&gt;

&lt;h4&gt;
  
  
  Setting Up Your Project
&lt;/h4&gt;

&lt;p&gt;Open your terminal (that's the black screen where you type commands) and follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new folder for your project. Let's call it example-art.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;example-art
&lt;span class="nb"&gt;cd &lt;/span&gt;example-art
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initialize a new Go module in this folder.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go mod init example-art
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a new file named main.go inside this folder.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, your example-art folder should contain two files: go.mod and main.go.&lt;/p&gt;

&lt;h4&gt;
  
  
  Writing Your First Program
&lt;/h4&gt;

&lt;p&gt;Open main.go with a text editor (like Notepad or TextEdit) and paste the following code:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Your code will go here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Running Your Program
&lt;/h5&gt;

&lt;p&gt;Back in your terminal, type the following command to run your program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go run &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything is set up correctly, your terminal should show no errors.&lt;/p&gt;

&lt;p&gt;Note: When you run the program, make sure to include the dot (.) after 'go run'&lt;/p&gt;

&lt;p&gt;Now you're ready to start creating shapes on your computer terminal!&lt;/p&gt;

&lt;h3&gt;
  
  
  Simple Filled Rectangle
&lt;/h3&gt;

&lt;p&gt;Imagine you want to create a filled rectangle like the one shown, with a specific width and height&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Instead of looking at it as a bunch of stars that span multiple lines, it will be easier if you looked at it as a grid which contains empty characters to begin with&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhys45v7dpf4nd46xr2ax.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhys45v7dpf4nd46xr2ax.png" alt="a grid consisting of rows and columns" width="640" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The grid is made up of rows which run from top to bottom.&lt;/p&gt;

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

&lt;p&gt;Did you notice  the i == 2? In this article, all of our counting will begin at 0. We will therefore count like this: 0, 1, 2, 3, et cetera. In the figure above, i == 2 indicates the position of that row from the starting point. Hence the third row is at position 2. It is best to get used to this form of counting since it is quite commonly used within the computing world. &lt;/p&gt;

&lt;p&gt;Each row is made up of a certain number of cells. While we are at this row, we can access its individual cells, each time updating the value with the desired character&lt;/p&gt;

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

&lt;p&gt;In essence, what we need to do is iterate through each row, and within each row, populate its cells with a specific character. In programming, we achieve this using a construct called repetition. Repetition allows us to repeat a statement multiple times without having to rewrite it each time. For instance, if we wanted to emphasise the line "I am learning to draw shapes on the terminal" by printing it one million times, instead of,&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I am learning to draw shapes on the terminal"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I am learning to draw shapes on the terminal"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I am learning to draw shapes on the terminal"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I am learning to draw shapes on the terminal"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I am learning to draw shapes on the terminal"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I am learning to draw shapes on the terminal"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;/* 999994 more times of this */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could use repetition to accomplish this in a more compact way, as in,&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nb"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I am learning to draw shapes on the terminal"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, for i := 0; i &amp;lt; 1000000; i++ sets up a loop that repeats the println statement a million times, incrementing i from 0 to 999999.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;nested for loops&lt;/strong&gt;&lt;br&gt;
Take for instance you wanted to print five stars in a single line. The for-loop below would accomplish this, without having to repeat the print(“*”) statement five times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output of that program would be&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="k"&gt;*****&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you remember how we used loops to print a line multiple times? What if we treated the for loop above as a unit in the sense that we can also repeat it a certain number of times? In programming, there is a concept known as abstraction. Abstraction enables us to treat something as if it is a single unit. This will be akin to the concept of a dozen. If someone told you they have a dozen pencils, you would immediately know that they have twelve pencils. The same way to refer to a collection of things can be used in programming. Abstraction allows us to treat a whole block of code that does many things as if it was a single entity. We could essentially refer to the code above as the “inner loop”. If it is a unit, can we also repeat our “inner loop” multiple times?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// first 5 stars&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;// go to the next line&lt;/span&gt;
&lt;span class="nb"&gt;println&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c"&gt;// second 5 stars&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;// go to the next line&lt;/span&gt;
&lt;span class="nb"&gt;println&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c"&gt;// third 5 stars&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above will print 3 rows, each with five stars. The println() is used to move the cursor to the next line so that the next five lines are printed just below the first and not right next to them. We have met such inefficient code before when we needed to print a line a million times. In out case, if we also needed to print a million lines each with five stars, we will have to repeat our “inner loop” a million times. Can we make this more compact? This is where the notion of a unit comes in. We can treat that whole block of code as something that knows how to print five stars in a single line. We can then repeat it many times and each time, it will print the required five stars. But if we can use a for loop to repeat this statement,  print(“I am learning to draw shapes”), can we also do the same to repeat the preceding block of code?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would notice that we are using a for loop to repeat the block of code we had before (in bold). Abstraction therefore enables us view a collection of things, like our “inner loop” as a single entity which we can easily repeat to produce whatever outcomes we need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does this relate to our grid system?&lt;/strong&gt;&lt;br&gt;
For grids or shapes, we use nested loops. The outer loop controls rows, and the inner loop controls cells or characters within each row. For example:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawnuadlpq5wz4opylt1u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawnuadlpq5wz4opylt1u.png" alt="printing many rows image depiction" width="800" height="592"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The complete code example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;                          &lt;span class="c"&gt;// Number of rows&lt;/span&gt;
    &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;                          &lt;span class="c"&gt;// Number of columns&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;        &lt;span class="c"&gt;// outer loop for rows&lt;/span&gt;
     &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&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;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;width&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="p"&gt;{&lt;/span&gt;     &lt;span class="c"&gt;// inner loop for columns&lt;/span&gt;
         &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c"&gt;// print a character: *&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="nb"&gt;println&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;           &lt;span class="c"&gt;// Move to the next line after each row&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this combined loop structure:&lt;br&gt;
The outer loop for i := 0; i &amp;lt; height; i++ iterates over each row.&lt;br&gt;
The inner loop for j := 0; j &amp;lt; width; j++ prints a character (e.g., "*") for each column.&lt;br&gt;
After printing all characters in a row, println() moves to the next line for the next row.&lt;br&gt;
These loops allow us to efficiently create and manipulate grids or shapes in programming, scaling from simple patterns to complex structures, all while minimising repetitive code.&lt;/p&gt;
&lt;h3&gt;
  
  
  Introducing Constraints
&lt;/h3&gt;

&lt;p&gt;Imagine you're creating a drawing using an empty rectangle, like this:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;When drawing each line in our grid, we follow specific rules, or "constraints," about where characters can appear. These rules ensure that characters only show up in certain places, particularly along the edges or borders of the drawing.&lt;/p&gt;

&lt;p&gt;In our previous example, the constraint was effectively "no constraint." This meant we printed "*" in every position of the line. In contrast, our current example introduces a stricter constraint: characters can only be printed if they are within the vertical or horizontal borders.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Vertical Edges (constraints for &lt;code&gt;i&lt;/code&gt;):&lt;/strong&gt; Our outer loop index &lt;code&gt;i&lt;/code&gt; correlates to the height (rows). Only draw characters at the very top and bottom lines. So, if we're at the first line (index 0) or the last line (index 5 in this case), we draw characters all the way across.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;i == 0 || i == 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Horizontal Edges (constraints for &lt;code&gt;j&lt;/code&gt;):&lt;/strong&gt; Our inner index &lt;code&gt;j&lt;/code&gt; correlates to the width (columns). Along each line, characters only go at the very left and right edges. For example, at position 0 and position 19 (since we have 20 columns in total).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;j == 0 || j == 19
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Putting It All Together:&lt;/strong&gt; To decide if we should draw a character at any position, we check these rules. If the position meets any of these conditions — being at the top or bottom line, or at the far left or right of any line — then we draw a "*" character. Otherwise, we leave that spot blank with a space (" ").&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;19&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Complete code Example&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The same principles from before still apply, however, when it comes to drawing the characters on each line, we need to introduce constraints as stated so that we can only print a character if a certain constraint is met. There are four constraints that we need the indexes &lt;code&gt;i&lt;/code&gt; and &lt;code&gt;j&lt;/code&gt; to adhere to before we print a character. We, therefore, need to print a non-empty character if and only if these constraints are met.&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;6&lt;/span&gt;
    &lt;span class="n"&gt;columns&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;


    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&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;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;columns&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="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// our constraints&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c"&gt;// constraint met. &lt;/span&gt;
            &lt;span class="c"&gt;// print a non-empty character&lt;/span&gt;
                &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c"&gt;// index not along the border&lt;/span&gt;
                &lt;span class="c"&gt;// print an empty character&lt;/span&gt;
                &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c"&gt;// move to the next row&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Overarching Idea
&lt;/h3&gt;

&lt;p&gt;The following procedure can be replicated across different examples to produce any shape imaginable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Outer: Loop the number of times as the lines you have.
    Inner: For each line,
    - If there is a constraint that makes that particular line appear different, take it into account.
    - Otherwise, draw the character in every position of the line
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;finally&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The next time you see a graphical shape on someone’s screen and wonder how it’s done, remember it often starts with simple loops. By understanding how loops and constraints work, you can unlock the potential to create visually interesting designs in your terminal. With practice and creativity, you can build more complex shapes, patterns, and even complete ASCII art masterpieces.&lt;/p&gt;

&lt;p&gt;You can find an enhanced version of this code in a repository. While the repository will continue to evolve, the fundamental shapes mentioned here will always stay the same. Access the code at &lt;a href="https://github.com/oduortoni/console-art.git" rel="noopener noreferrer"&gt;this link&lt;/a&gt; or visit &lt;a href="https://github.com/oduortoni/console-art.git" rel="noopener noreferrer"&gt;https://github.com/oduortoni/console-art.git&lt;/a&gt; in your web browser.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
