<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ learning - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ learning - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 14:15:13 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/learning/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Why Many Beginner Self-Taught Developers Struggle (And What to Do About It) ]]>
                </title>
                <description>
                    <![CDATA[ Self‑taught developers often begin with the same “starter pack”: a laptop, internet access, and sheer determination. What they lack, however, is structured guidance, a defined curriculum, or any form  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/why-many-beginner-self-taught-developers-struggle-and-what-to-do-about-it/</link>
                <guid isPermaLink="false">69e66a12c9501dd0101793f9</guid>
                
                    <category>
                        <![CDATA[ Learning Journey ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Self-taught  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Beginner Developers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Great John ]]>
                </dc:creator>
                <pubDate>Mon, 20 Apr 2026 18:01:54 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/76b41ea4-5375-4393-ad06-a0e53b53d23a.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Self‑taught developers often begin with the same “starter pack”: a laptop, internet access, and sheer determination. What they lack, however, is structured guidance, a defined curriculum, or any form of pedagogical support.</p>
<p>This absence of direction makes the journey significantly harder. Faced with an overwhelming abundance of online resources, many beginners become confused about where to start and often attempt to learn everything at once.</p>
<p>This is where the struggle with knowledge retention begins.</p>
<p>Not because they lack intelligence or effort, but because they're learning in a way that contradicts how the human brain actually works.</p>
<p>They dive into tutorials and courses without understanding the mechanism of the brain – that is, how the brain processes, stores, and retrieves information. As a result, much of what they learn simply doesn’t stick.</p>
<h3 id="heading-how-the-brain-processes-information">How the Brain Processes Information</h3>
<p>So what's the connection between the brain and learning how to code, you might ponder?</p>
<p>The connection is direct and unavoidable.</p>
<p>Coding isn't learned through willpower or motivation — though both matter — or by spending countless hours watching tutorials.</p>
<p>It's learned through the brain’s ability to process, store, and retrieve information.</p>
<p>Every variable, function, data structure, or debugging pattern must pass through the brain’s cognitive systems before it becomes usable knowledge.</p>
<p>If your learning process doesn't align with how the brain naturally acquires and organises information, your retention will collapse, no matter how determined you are.</p>
<p>Now imagine you’re trying to fill a bucket with water. You keep pouring and pouring, but the bucket has tiny holes at the bottom. No matter how much effort you put in, the water keeps leaking out. You might blame yourself for not pouring fast enough, or you might try switching to a bigger jug, but the real problem isn’t your effort — it’s the bucket.</p>
<p>The water is the information you’re trying to learn.</p>
<p>The bucket is your brain’s memory system.</p>
<p>The holes in the bucket are the natural forgetting mechanisms of the brain: cognitive overload, limited working memory, and other constraints that make retention difficult.</p>
<p>If you don’t understand these mechanisms, you can pour in as much information as you want, but most of it will leak out.</p>
<p>Not because you’re incapable, but because you’re learning in a way that contradicts how the brain actually retains knowledge.</p>
<h3 id="heading-the-role-of-academic-learning-theories">The Role of Academic Learning Theories</h3>
<p>Since learning ultimately takes place in the brain, an important question is: How does the human brain acquire, organize, and apply knowledge and why does the typical self‑taught learning process clash with these principles?</p>
<p>This is where academic learning theories become indispensable. These frameworks explain how the brain actually acquires, retains, and applies complex information and they offer a scientific roadmap for learning more effectively. Without understanding these principles, self‑taught developers unintentionally work against the brain’s natural architecture.</p>
<p>The purpose of this article is to unpack these essential learning theories and apply them directly to the beginner self‑taught developer’s journey.</p>
<p>By understanding how the brain processes information, beginners can structure their learning more intentionally, retain knowledge more reliably, and move toward becoming competent developers with far greater confidence and clarity.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-cognitive-load-theory-clt">Cognitive Load Theory (CLT)</a></p>
<ul>
<li><p><a href="#heading-working-memory">Working Memory</a></p>
</li>
<li><p><a href="#heading-millers-law">Miller's Law</a></p>
</li>
<li><p><a href="#heading-chunking">Chunking</a></p>
</li>
<li><p><a href="#heading-long-term-memory">Long-term memory</a></p>
</li>
<li><p><a href="#heading-schema">Schema</a></p>
</li>
<li><p><a href="#heading-intrinsic-load-the-natural-difficulty-of-the-task">Intrinsic Load: The Natural Difficulty of the Task</a></p>
</li>
<li><p><a href="#heading-extraneous-load-the-mental-noise">Extraneous Load: The Mental Noise</a></p>
</li>
<li><p><a href="#heading-germane-load-the-construction-work">Germane Load: The Construction Work</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-ebbinghaus-forgetting-curve">Ebbinghaus Forgetting Curve.</a></p>
</li>
<li><p><a href="#heading-how-the-theory-of-spaced-repetition-works">How the Theory of Spaced Repetition Works</a></p>
</li>
<li><p><a href="#heading-theory-of-deliberate-practice">Theory of Deliberate Practice</a></p>
</li>
<li><p><a href="#heading-what-is-blooms-taxonomy">What is Bloom's Taxonomy?</a></p>
<ul>
<li><a href="#heading-focused-mode-vs-diffuse-mode">Focused Mode vs Diffuse Mode</a></li>
</ul>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
<li><p><a href="#heading-references">References</a></p>
</li>
</ul>
<h2 id="heading-cognitive-load-theory-clt">Cognitive Load Theory (CLT)</h2>
<p>Learning a new concept often requires mental effort by the brain to process newly acquired information. This effort exerted by the brain is known as cognitive load, a term coined by Australian educational psychologist John Sweller in 1988 during his study on how the brain acquires and retains information (Sweller, 1988).</p>
<p>Since then, his work has been expanded upon by other researchers. Notably, Dylan Wiliam famously tweeted in 2017 that Cognitive Load Theory (CLT) is "the single most important thing for teachers to know" (Dylan William, 2017).</p>
<p>You might wonder again: What does this have to do with me? As a beginner self‑taught developer, the answer is simple: you're both the teacher and the student.</p>
<p>So this is the most important theory you should know. In this self-tutoring journey, you're tasked with designing your own curriculum, choosing your own resources, pace your own learning, and evaluating your own progress.</p>
<p>Without understanding how cognitive load affects your ability to absorb and retain information, you may unintentionally overload your brain and sabotage your own learning.</p>
<p>Before we get into the nitty-gritty of CLT, there are important concepts masterminded by David Geary that you'll need to grasp to sufficiently understand this concept : “that which can be learnt” (biologically primary knowledge), “that which can be taught”(biologically secondary knowledge) (Geary, 2007, 2008).</p>
<p>According Geary (2007, 2008), "biologically primary knowledge" consists of "instinctual" skills that the brain is evolved to pick up naturally without formal schooling.</p>
<p>Examples include learning a first language, recognizing faces, or basic social navigation.</p>
<p>"Biologically secondary knowledge", on the other hand, consists of cultural and technical skills, like reading and writing, that are necessary for society but don't come naturally to the brain.</p>
<p>This is because we aren't "wired" to pick these up automatically. Instead, they require formal instruction and schools to pass them down.</p>
<p>Therefore, coding is a prime example of biologically secondary knowledge. The human brain is remarkably plastic, but it didn't evolve to interpret syntax, manage memory allocation, or debug logical loops.</p>
<p>These are cultural inventions, not natural instincts. Unlike learning to walk or speak your native language (which are biologically primary skills) you can't learn to code simply by “being around” computers.</p>
<p>Recognising that the human brain is not instinctively prepared for coding allows you to change your strategy. Once you accept that coding concepts are not “natural,” you can finally approach them with the structured, deliberate effort they require.</p>
<p>The second set of concepts beginner self-taught developers should know and understand are working memory, Miller's Laws, chunking, long-term memory, and schemas.</p>
<h3 id="heading-working-memory">Working Memory</h3>
<p>Working memory is where thinking happens. It's the active mental workspace where you hold information while you process it. When you encounter concepts like syntax, loops, functions, or an if/elseif statement for the first time, all of that information sits inside your working memory. The problem is that working memory is extremely limited and fragile.</p>
<p>When you first learn to code, your working memory functions like a small mental desk where only a few items can be placed at once.</p>
<p>Imagine trying to assemble a piece of IKEA furniture on a tiny coffee table. If you spread out the instruction manual, the screws, the wooden panels, and the tools all at the same time, the table becomes cluttered instantly. You start losing track of which part goes where, not because you’re incapable, but because the surface you’re working on is too small to hold everything at once.</p>
<p>Working memory behaves the same way. When you’re learning new concepts – like arrays, loops, functions, or error handling – each idea takes up space on that mental desk. If you then overload it, the desk becomes overcrowded.</p>
<p>Once it exceeds its capacity, things begin to fall off, and your ability to retain collapses.</p>
<p>It’s not a lack of intelligence. It’s simply the natural limit of working memory.</p>
<p>Now this collapse happens because you went against the threshold your working memory can hold. This is backed up by research that shows that working memory can typically process only 5–9 pieces of information at any given time (Miller, 1956). This is known as Miller’s Law.</p>
<h3 id="heading-millers-law">Miller's Law</h3>
<p>In 1956, George Miller found that the average human can hold about seven items (plus or minus two) in working memory at once, even some recent research has stated the number is even lower about four item (Nelson Cowan, 2001).</p>
<p>So imagine you encounter a tutorial that introduces the following concepts all at the same time: a Route, a Controller, a Model, a Migration, a View, a Request, Helper files, Jobs and Queues, Middleware, Roles and Permissions, and a Service Provider. If you attempt to hold all of these in your mind simultaneously, you'll inevitably hit Miller’s Wall, as your working memory becomes overloaded, and you'll likely forget the first concept long before you reach the last.</p>
<p>So how do you handle complex tasks if the brain can only juggle 4–9 items at once?</p>
<p>You use chunking — the process of grouping small pieces of information into a single, meaningful unit.</p>
<h3 id="heading-chunking">Chunking</h3>
<p>Chunking is the brain’s strategy for compressing complexity. Instead of forcing working memory to hold a dozen unrelated items, you reorganise them into a few coherent structures. This reduces cognitive load, prevents overload, and allows you to work with far more information than your raw working‑memory limits would normally allow.</p>
<p>Let's consider an example:</p>
<p>A beginner learning Laravel might see Route, Controller, Model, Migration, and View as five separate, overwhelming items. To a beginner, each one feels like a distinct cognitive burden. But an experienced developer doesn't treat them as isolated concepts. Instead, they're understood as a single meaningful unit: the MVC pattern. Instead of holding five items in working memory, the expert holds one.</p>
<p>This raises an important question: how does a beginner know that these five elements belong together when they have only just encountered them?</p>
<p>It's crucial to emphasise that chunking isn't automatic. It depends on recognising meaningful relationships between concepts, and beginners typically lack the prior knowledge needed to perceive those relationships early on.</p>
<p>But as learners repeatedly encounter the same sequence during the learning process, they begin to notice consistent patterns. Over time, the brain’s natural tendency to seek structure enables them to identify which components reliably operate together, allowing these elements to gradually fuse into a single, meaningful chunk.</p>
<p>For example, when I first followed a Laravel e-commerce tutorial, I noticed that for every new resource the tutor created –&nbsp;Payment, Cart, KYC, and Contact – the same pattern was repeated: a Controller, a Model, and a View were always created together.</p>
<p>After encountering this sequence several times, it became clear that these components consistently belonged together as a set. Over time, I began to perceive the Controller, Model, and View not as separate elements, but as a single, integrated unit.</p>
<p>So beginners may not be able to chunk effectively on day one because they lack the prior knowledge needed to recognise what belongs together. But with time, and repeated encounters across different contexts, these individual pieces fuse into stable mental units stored in long‑term memory.</p>
<p>What feels overwhelming at first eventually becomes effortless, not because the task became simpler, but because your internal representation became more organised.</p>
<p>This is the power of chunking: it transforms scattered pieces of information into organised units that fit comfortably within the limits of working memory.</p>
<p>Without chunking, beginners drown in details. With chunking, they gain the cognitive space needed to understand, retain, and apply what they learn.</p>
<h3 id="heading-long-term-memory">Long-term memory</h3>
<p>Unlike working memory, long‑term memory has virtually infinite capacity. The goal of all study is to move information from the cramped working memory into the vast long‑term memory.</p>
<p>Here is the real secret: you don’t learn in working memory – you only process there.</p>
<p>True learning is the permanent change that happens in long‑term memory.</p>
<h3 id="heading-schema">Schema</h3>
<p>Once stored in long-term memory, information becomes part of a schema — a mental map or filing system that organizes related ideas.</p>
<p>For example, when you finally learn that Laravel is an MVC framework, you aren’t just memorizing three letters. You're building a schema that tells your brain: Models handle data, Views handle presentation, and Controllers handle logic.</p>
<p>Once a schema is built, it can be pulled into working memory as a single chunk, effectively bypassing Miller’s Law.</p>
<p>This is how experts think effortlessly while beginners feel overwhelmed.</p>
<p>And this is why Garnett (2020) argues that "being competent or lacking competence in something depends entirely on how secure the retrieval of knowledge held in the schema is".</p>
<p>Now that the foundations of working memory, long‑term memory, schemas, and chunking are clear, we can turn to another set of concepts every self‑taught developer must understand: intrinsic load, extraneous load, and germane load. These three components make up the full structure of Cognitive Load Theory, and they determine whether learning feels manageable or overwhelming.</p>
<h3 id="heading-intrinsic-load-the-natural-difficulty-of-the-task">Intrinsic Load: The Natural Difficulty of the Task</h3>
<p>Intrinsic load refers to the inherent complexity of the material itself. Some concepts are simply harder than others because they contain more interacting elements that must be processed at the same time.</p>
<p>In Laravel, understanding a simple Route has low intrinsic load.</p>
<p>But concepts like Dependency Injection or Polymorphic Relationships have high intrinsic load because they involve multiple layers of abstraction and interdependent ideas.</p>
<p>You can't change the intrinsic load of a concept, but you can manage it by breaking the idea into smaller, more digestible sub‑tasks. This is why good teaching — and good self‑teaching — always begins with simplification and sequencing.</p>
<p>Simplification means stripping a concept down to its essential parts so the learner isn't overwhelmed by unnecessary detail.</p>
<p>Sequencing means introducing parts in a logical order, where each step builds on the previous one. This helps reduce unnecessary cognitive load and allows learners to devote more mental effort (germane load) to building schemas.</p>
<p>It’s like meeting someone new, and they tell you their name and it happens to be your mother’s name. Instantly, your brain forms a connection. You associate this new person’s name with the strong, deeply stored memory of your mother.</p>
<p>Because that schema already exists in your long-term memory, the new information “attaches” to it. Later, when you try to recall the name, you don’t struggle, you simply think of your mother, and the name comes back easily.</p>
<p>While many believe self‑taught developers struggle because they lack immediate, reliable, personal guidance, there's actually a hidden advantage in this predicament. When a teacher explains a concept, even if they try their best to “chunk” the information, they can't truly know the student’s internal limits — how much intrinsic load the learner can handle, how quickly they can process new ideas, or how much prior knowledge they can activate.</p>
<p>This is where self‑taught developer quietly shines. Because you are both the teacher and the student, you know your own cognitive limits better than anyone else. You can slow down when something feels heavy, pause when working memory is overloaded, and chunk information in a way that perfectly matches your personal capacity.</p>
<p>You can simplify a concept to its bare essentials and sequence it at a pace that aligns with your own understanding.</p>
<h3 id="heading-extraneous-load-the-mental-noise">Extraneous Load: The Mental Noise</h3>
<p>Extraneous load is the enemy of the self‑taught developer. It's the mental effort wasted on tasks that don't contribute to actual learning. This is where a self-taught developer's strength must truly shine.</p>
<p>A teacher in a classroom is responsible for removing any distractions that might derail a child or slow down their assimilation of knowledge. As a self-taught developer, that responsibility falls entirely on you. You must identify these distractions and eliminate them.</p>
<p>As a self-taught developer myself, I use specific strategies to ensure I stay focused. Before starting any course, I spend time reading the comment section to see what others have experienced. If I see complaints about low audio quality, unclear explanations, or tutorials that move too fast, I immediately abandon that course and look for one with better reviews.</p>
<p>Anything that might derail my progress must be removed. If you spend half of your mental energy trying to figure out all of these, you only have the remaining half available for understanding the logic of the code. And remember: when learning new concepts, we use working memory, which is fragile.</p>
<p>As your own “inner teacher,” you must eliminate this noise so your limited working memory can focus entirely on the material that matters.</p>
<h3 id="heading-germane-load-the-construction-work">Germane Load: The Construction Work</h3>
<p>Germane load is the productive mental effort used to build and refine schemas — the mental structures that make future learning easier.</p>
<p>This is the “Aha!” moment when new information connects meaningfully to what you already know.</p>
<p>For example, germane load appears when you realise that a Database Migration is essentially a version‑control system for your table structure.</p>
<p>That insight is schema construction in action.</p>
<p>Teachers are often advised to help manage a child's germane load. One way they do this is by connecting the new idea being taught to an existing concept.</p>
<p>By doing this, they help the student build schemas: mental frameworks that organise and interpret information.</p>
<p>For a self-taught developer, this means instead of memorizing a new syntax in isolation, you look for a 'hook' in something you already understand.</p>
<p>For example, if you already know how a physical filing cabinet works, understanding Arrays or Objects in code becomes much easier.</p>
<p>You aren't learning from scratch – you're simply "plugging" new data into an old socket. This reduces the mental strain and makes the new knowledge stick permanently.</p>
<p>But this can only happen when intrinsic load is properly managed and extraneous load is removed.</p>
<p>It's important to note that, unlike intrinsic and extraneous load, germane load isn't an independent type of cognitive load.</p>
<p>Instead, it represents the portion of your working memory that remains available to handle the element interactivity associated with intrinsic load.</p>
<p>In other words, germane load is the mental energy you have left for learning once the unnecessary noise is stripped away.</p>
<p>Understanding cognitive load explains why learning can feel overwhelming in the moment, but it doesn't explain why knowledge fades after the moment has passed. For that, we turn to another foundational principle in learning science: the Ebbinghaus Forgetting Curve.</p>
<h2 id="heading-ebbinghaus-forgetting-curve">Ebbinghaus Forgetting Curve</h2>
<p>If you remember the bucket analogy, this curve represents one of the holes at the bottom — the brain’s natural tendency to let information leak away unless it's reinforced.</p>
<p>In the late 19th century, Hermann Ebbinghaus discovered that human memory follows a predictable pattern of decline. After learning something new, we forget most of it astonishingly quickly — often within hours — unless the information is revisited. The forgetting curve shows that memory retention drops sharply at first and then continues to decline more slowly over time.</p>
<p>Studies based on Ebbinghaus’ forgetting curve found that without a conscious effort to retain newly acquired information, we lose approximately 50% of new information within 24 hours, and up to 90% within a week (Clearwater, 2024).</p>
<p>In other words, the brain is designed to discard information that isn't reinforced.</p>
<p>For self‑taught developers, this has profound implications.</p>
<p>You may understand a Laravel controller today, spatial roles and permission concepts, and so on – but if you don't revisit it, practice it, or apply it within the next few hours, your brain will naturally let it fade.</p>
<p>This is not a sign of weakness or lack of talent. It's simply how human brain works.</p>
<p>The forgetting curve also explains why tutorials feel deceptively easy the moment you're going through them.</p>
<p>While watching, everything seems clear — but a week later, the same concepts feel unfamiliar.</p>
<p>The knowledge never made it into long‑term memory because you didn't revisit, practice, or connect it to existing schemas.</p>
<p>Since the human brain is designed to forget anything that isn't repeated, repetition becomes the signal that tells the brain, “This matters — keep it.”</p>
<p>This is why, when you meet someone for the first time and they tell you their name, you'll almost certainly forget it unless you consciously repeat it to yourself several times. If you don’t reinforce it, you end up asking — often with embarrassment — “Sorry, what was your name again?”</p>
<p>The same principle applies to learning code: without deliberate repetition, the brain simply lets the information fade. However, with a technique called spaced repetition, retention is significantly improved .</p>
<h2 id="heading-how-the-theory-of-spaced-repetition-works">How the Theory of Spaced Repetition Works</h2>
<p>Spaced repetition is a learning technique grounded in cognitive psychology that involves reviewing information at increasingly spaced intervals to strengthen long‑term memory retention.</p>
<p>It's based on the principle that memory decays predictably over time — as demonstrated by the Ebbinghaus Forgetting Curve — and that strategically timed reviews or repetition interrupt this decay, making the memory more durable with each repetition.</p>
<p>This idea is what gave birth to Anki-Flash cards.</p>
<p>Imagine you're trying to memorise the time complexity of different algorithms.</p>
<p>This is a classic "dry" academic topic that's easy to forget.</p>
<p>To understand why spaced repetition is so powerful, consider a familiar scenario. You spend Sunday night staring at a chart of Big‑O complexities for four hours. By Monday’s review, you can recall most of them. By Friday, only a few remain. Two weeks later, the entire chart has vanished from memory.</p>
<p>Spaced repetition reverses this process by reviewing information at the precise moment it's about to be forgotten. Instead of cramming Big‑O notation in a single session, you revisit it across expanding intervals:</p>
<ol>
<li><p>Day 1 (Initial Learning): You study the Big‑O chart and understand each complexity class.</p>
</li>
<li><p>Day 2 (First Review): You test yourself. If you recall an item correctly, you schedule the next review three days later. If you miss it, you review it again the following day.</p>
</li>
<li><p>Day 5 (Second Review): You encounter the material again. Because you still remember it, the interval expands to ten days.</p>
</li>
<li><p>Day 15 (Third Review): Your memory has begun to fade, but the moment you see the prompt, the concept resurfaces. This slight struggle to retrieve the information is precisely what strengthens long‑term retention.</p>
</li>
<li><p>Day 45 (Fourth Review): By now, the memory is deeply consolidated. Concepts like O(log⁡n) feel as natural and accessible as your own phone number.</p>
</li>
</ol>
<p>Through this process, spaced repetition transforms fragile, short‑term awareness into durable, long‑term knowledge. Each review interrupts the forgetting curve, reinforces the schema, and reduces the cognitive load required to recall the concept in the future.</p>
<p>For self-taught developers, spaced repetition can take many forms. You might rewrite code from memory, re‑implement a feature days later, build small variations of the same concept, or return to the concept after working on different tasks.</p>
<p>Every review strengthens the schema and reduces the cognitive load required to recall it. Over time, what once felt complex becomes automatic — not because the concept changed, but because your brain reorganised it into a stable, efficient structure.</p>
<p>As you can see, learning isn't a single event but a cycle of exposure, forgetting, and reinforcement.</p>
<p>Mastery comes not from seeing something once, but from returning to it until it becomes part of your cognitive architecture.</p>
<p>But we must be careful with repetition. Doing the same thing over and over again doesn't guarantee improvement. In fact, mindless repetition can trap you at the same level indefinitely.</p>
<p>This is where the theory of deliberate practice becomes essential, as it emphasises increasing the level of challenge, focusing on specific weaknesses, and actively seeking feedback so that each repetition leads to measurable improvement rather than just familiarity.</p>
<h2 id="heading-theory-of-deliberate-practice">Theory of Deliberate Practice</h2>
<p>Developed by psychologist K. Anders Ericsson, it argues that expertise is not the result of talent but of high‑quality, intentional practice (Ericsson, 1993). This type of practice is fundamentally different from simply doing something repeatedly.</p>
<p>He coined the term "deliberate practice" while researching how people become experts. Studying experts from several different fields, he dismantled the myth that expert performers have unusual innate talents.</p>
<p>Instead, he discovered that experts attain their high performance through how they practice: it's a deliberate effort to become an expert. This effort is characterized by breaking down required skills into smaller parts and practicing these parts repeatedly.</p>
<p>According to Anders Ericsson, Deliberate Practice requires:</p>
<ol>
<li><p>Clear goals</p>
</li>
<li><p>Immediate feedback</p>
</li>
<li><p>Tasks that stretch your ability just beyond your comfort zone</p>
</li>
<li><p>Full concentration and effort</p>
</li>
</ol>
<p>The main tenet of Deliberate Practice is that tasks must stretch your ability just beyond your comfort zone. This is paramount to the advancement of learning.</p>
<p>Imagine a child being taught 1+1 every day. That child will never grow beyond basic arithmetic. Anders Ericsson calls this "Arrested Development" (Ericsson, Nandagopal and Roring, 2005). For that child to grow to become a mathematician, their knowledge must be stretched.</p>
<p>The takeaway for developers is a play on the DRY principle (Don’t Repeat Yourself): If you are only repeating what you already know without stretching yourself, you aren't growing. This "stretch" is the extra edge that Deliberate Practice adds to Spaced Repetition.</p>
<p>Building a simple to-do list, a calculator, or a weather app over and over again won't take you anywhere. You already know how to do those.</p>
<p>To truly grow, you must stretch yourself. Instead, try a project that integrates new ideas, like building a mini-app where the weather data affects your to-do list. For example, if the API shows it's raining, the app automatically hides outdoor tasks and calculates the time you'll save or the indoor tasks you should prioritize instead.</p>
<p>This forces you to handle complex logic and state management, moving you beyond simple repetition into true mastery.</p>
<p>This ability to create brings me to the last theory: Bloom's Taxonomy.</p>
<h2 id="heading-what-is-blooms-taxonomy">What is Bloom's Taxonomy?</h2>
<p>Bloom’s Taxonomy provides a hierarchy of cognitive skills that learners move through as they develop mastery. It begins with the simplest tasks and progresses toward the most complex:</p>
<ol>
<li><p>Remember – recalling facts or syntax</p>
</li>
<li><p>Understand – explaining concepts in your own words</p>
</li>
<li><p>Apply – using knowledge in real situations</p>
</li>
<li><p>Analyze – breaking problems into parts</p>
</li>
<li><p>Evaluate – judging solutions or comparing approaches</p>
</li>
<li><p>Create – building original systems or applications</p>
</li>
</ol>
<p>Most self‑taught developers get stuck in the first two levels. They memorize syntax and understand examples, but they struggle to apply, analyze, or create.</p>
<p>This isn't because they lack ability. Rather, it's because they haven't been taught that learning must progress through these stages.</p>
<p>Bloom’s Taxonomy gives structure to the learning journey.</p>
<p>It reminds self-taught developers that mastery isn't achieved by watching tutorials but by climbing the ladder from remembering → understanding → applying → analyzing → evaluating → creating (with an emphasis on Creation).</p>
<p>Creation is one of the most difficult yet most transformative experiences in your journey as a developer. It forces you to think abstractly, confront ambiguity, and notice dimensions of a problem that tutorials rarely reveal.</p>
<p>When you build something real, the neatness of the theory in your head collapses, and you begin to see its true complexity. You must then devise strategies to navigate these challenges, and through this process, you learn.</p>
<p>And as with anything worthwhile, the process isn't smooth. You'll encounter bugs — not just one or two, but hundreds. Yet this is precisely how real knowledge is built. Every bug you solve becomes a permanent entry in your long‑term memory.</p>
<p>The next time you see that error, you won’t panic. Instead, you’ll recognise it instantly and know exactly where it’s coming from and how to fix it.</p>
<p>Some self‑taught developers encounter a few bugs and never return to their projects again, concluding that “coding isn’t for me.”</p>
<p>After trying several fixes and seeing no progress, they abandon the work and look for something else. But this is the wrong conclusion. The problem is rarely a lack of talent — it's a misunderstanding of how the brain behaves under cognitive strain.</p>
<h3 id="heading-focused-mode-vs-diffuse-mode">Focused Mode vs Diffuse Mode</h3>
<p>When you spend a long time wrestling with a bug, you may be experiencing mental fixation or functional fixedness.</p>
<p>This is when your brain becomes locked into a single line of reasoning, repeating the same logic path over and over because it feels like the right direction. The longer you stare at the problem, the deeper the cognitive rut becomes. You develop tunnel vision, making it almost impossible to see alternative solutions.</p>
<p>This is where understanding how the brain operates becomes essential.</p>
<p>According to Oakley (2014), the brain works in two primary modes:</p>
<ol>
<li><p>Focused Mode: Ideal for executing a known formula or following a clear procedure, terrible for discovering a new approach or breaking out of a mental rut.</p>
</li>
<li><p>Diffuse Mode: This is activated when you step away — walking, showering, relaxing, or sleeping.</p>
</li>
</ol>
<p>In this second mode, the brain enters a “big‑picture” state where neural connections stretch across different regions.</p>
<p>The background processes continue working on the problem without the restrictive tunnel vision of conscious focus.</p>
<p>This phenomenon is known as incubation.</p>
<p>This is why solutions often appear when you’re not actively thinking about the problem. You step away, and suddenly the answer emerges, not because you stopped working, but because a different part of your brain started working for you.</p>
<p>The reality is that many developers never allow for incubation. While you step away from the problem, your brain performs subconscious synthesis: it clears out the noise (Extraneous Load) and lets the core logic (Germane Load) settle. When you return, the “wrong” paths you were obsessing over have faded, and the correct path which was there all along often finally becomes visible.</p>
<p>This is why developers must deliberately allow for incubation. We can take some lessons from great minds of the past:</p>
<p>Henri Poincaré famously struggled with Fuchsian functions for weeks. It was only during a geological excursion when he had completely forgotten about the mathematics that the solution appeared with “perfect certainty” the moment he stepped onto an omnibus. His breakthrough did not come from more effort, but from stepping away long enough for diffuse mode to take over.</p>
<p>Friedrich August Kekulé experienced something similar after years of wondering why benzene’s carbon atoms didn't fit a linear structure.</p>
<p>If some of the greatest minds in history stepped away from their problems and found solutions in diffuse mode, why should developers treat themselves any differently?</p>
<p>Now that you're familiar with some key learning strategies –&nbsp;Cognitive Load Theory, Spaced Repetition, and Bloom's Taxonomy –&nbsp;creating or building a project from the ground up should be your next task. It will help you curate, retrieve, organise, and seal in all that diverse knowledge you've gathered as a self-taught developer.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, we explored why the human brain isn't instinctively wired to understand programming. Coding is a biologically secondary skill, which means it doesn't develop naturally through immersion but requires explicit instruction, structure, and patience.</p>
<p>We also talked about the limits of working memory, the importance of chunking, and the need to manage cognitive load so that learning remains possible rather than overwhelming.</p>
<p>We then analyzed the three components of Cognitive Load Theory –&nbsp;intrinsic, extraneous, and germane load –&nbsp;and discussed how each influences the learning process. Reducing extraneous load is especially crucial for self‑taught developers, as it frees up mental resources for meaningful understanding.</p>
<p>From there, we turned to the Ebbinghaus Forgetting Curve, which demonstrates how quickly newly learned information fades without reinforcement.</p>
<p>To counter this natural forgetting, we introduced Spaced Repetition, a method that strengthens memory by reviewing material at expanding intervals. We also examined Deliberate Practice, which pushes learners just beyond their comfort zone to promote genuine skill development, and Bloom’s Taxonomy, which outlines the stages of cognitive growth from remembering to creating.</p>
<p>Finally, we emphasized the importance of knowing when to step back. The brain operates in both focused and diffuse modes, and effective learning requires movement between the two. Breaks are not signs of weakness but essential components of consolidation and insight.</p>
<p>Together, these theories form a comprehensive framework for learning to code with scientific precision. When self‑taught developers understand how their brain learns, forgets, and grows, they can design a learning process that isn't only more efficient but far more sustainable.</p>
<p>With all this new knowledge, one truth is certain: focus, determination, and consistency are the forces that transform theory into mastery.</p>
<p>Learning science can guide the process, but only sustained effort turns knowledge into skill.</p>
<h2 id="heading-references">References</h2>
<ol>
<li><p>Clearwater, L. (2024). <em>Understanding the Science Behind Learning Retention | Reports | What We Think | Indegene</em>. [online] <a href="http://www.indegene.com">www.indegene.com</a>. Available at: <a href="https://www.indegene.com/what-we-think/reports/understanding-science-behind-learning-retention">https://www.indegene.com/what-we-think/reports/understanding-science-behind-learning-retention</a>.</p>
</li>
<li><p>Dylan Wiliam [@dylanwiliam]. (2017, January 25). <em>I’ve come to the conclusion Sweller’s Cognitive Load Theory is the single most important thing for teachers to know</em> [Tweet]. X. <a href="https://x.com/dylanwiliam/status/824682504602943489">https://x.com/dylanwiliam/status/824682504602943489</a></p>
</li>
<li><p>Ericsson, K. A., Krampe, R. T., &amp; Tesch-Römer, C. (1993).<br><em>The role of deliberate practice in the acquisition of expert performance.</em><br><strong>Psychological Review, 100(3), 363–406.</strong></p>
</li>
<li><p>Garnett, S. (2020.). <em>Cognitive Load Theory A handbook for teachers</em>. [online] Available at: <a href="https://www.crownhouse.co.uk/assets/look-inside/9781785835018.pdf">https://www.crownhouse.co.uk/assets/look-inside/9781785835018.pdf</a>.</p>
</li>
<li><p>Geary, D. C. (2007). <em>An evolutionary perspective on learning disability in mathematics</em>. Developmental Neuropsychology, 32(1), 471–519. <a href="https://doi.org/10.1080/87565640701360924">https://doi.org/10.1080/87565640701360924</a></p>
</li>
<li><p>Geary, D. C. (2008). <em>An evolutionarily informed education science</em>. Educational Psychologist, 43(4), 179–195. <a href="https://doi.org/10.1080/00461520802392133">https://doi.org/10.1080/00461520802392133</a></p>
</li>
<li><p>George A. Miller (1956). <em>The magical number seven, plus or minus two: Some limits on our capacity for processing information</em>. Psychological Review, 63(2), 81–97. <a href="https://doi.org/10.1037/h0043158">https://doi.org/10.1037/h0043158</a></p>
</li>
<li><p>Nelson Cowan (2001). <em>The magical number 4 in short-term memory: A reconsideration of mental storage capacity</em>. Behavioral and Brain Sciences, 24(1), 87–114. <a href="https://doi.org/10.1017/S0140525X01003922">https://doi.org/10.1017/S0140525X01003922</a></p>
</li>
<li><p>Oakley, B. (2014). <em>A Mind for Numbers: How to Excel at Math and Science (Even If You Flunked Algebra).</em> New York: TarcherPerigee.</p>
</li>
<li><p>Sweller, J. (1988). Cognitive Load during Problem Solving: Effects on Learning. <em>Cognitive Science</em>, [online] 12(2), pp.257–285. doi:<a href="https://doi.org/10.1207/s15516709cog1202_4">https://doi.org/10.1207/s15516709cog1202_4</a>.</p>
</li>
</ol>
<p>‌</p>
<p>‌</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A Beginner Developer's Guide to Scrum ]]>
                </title>
                <description>
                    <![CDATA[ Let me guess: you’re learning to code…alone. You’ve been grinding through tutorials. You've built a portfolio site, maybe deployed a few projects on GitHub. And now you're trying to land a job or join a team. Then the interviews start. Suddenly, peop... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/a-beginner-developers-guide-to-scrum/</link>
                <guid isPermaLink="false">68813c7579e092b166d373b6</guid>
                
                    <category>
                        <![CDATA[ Scrum ]]>
                    </category>
                
                    <category>
                        <![CDATA[ agile development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ project management ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ interview ]]>
                    </category>
                
                    <category>
                        <![CDATA[ guide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ education ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Product Management ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Data Science ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Career ]]>
                    </category>
                
                    <category>
                        <![CDATA[ workflow ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Aditya Vikram Kashyap ]]>
                </dc:creator>
                <pubDate>Wed, 23 Jul 2025 19:48:05 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1753300058064/7046dd6c-1d9e-4f06-9ca1-65b3bb7eec83.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Let me guess: you’re learning to code…alone.</p>
<p>You’ve been grinding through tutorials. You've built a portfolio site, maybe deployed a few projects on GitHub. And now you're trying to land a job or join a team.</p>
<p>Then the interviews start.</p>
<p>Suddenly, people ask:</p>
<ul>
<li><p>"Are you familiar with Agile?"</p>
</li>
<li><p>"Have you worked in a Scrum environment?"</p>
</li>
<li><p>"What’s your experience with sprints?"</p>
</li>
</ul>
<p>Cue the imposter syndrome. Because no one teaches this stuff in JavaScript 101.</p>
<p>This guide is for you.</p>
<p>I’ll help make the Scrum process – a very common way developers work together – <em>make actual sense</em>. I’ll walk you through the basics, but also tell you what developers actually <em>do</em>, how standups feel when you're new, and what’s expected of you when you’re no longer coding in a vacuum.</p>
<p>Let’s break it down.</p>
<h3 id="heading-heres-what-well-cover">Here’s what we’ll cover:</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-even-is-scrum">What Even Is Scrum?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-three-roles-in-scrum-and-who-does-what">The Three Roles in Scrum (and Who Does What)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-scrum-rhythm-what-a-sprint-actually-looks-like">The Scrum Rhythm: What a Sprint Actually Looks Like</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-who-attends-the-ceremonies">Who attends the Ceremonies:</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-standups-where-you-talk-like-a-human-not-a-robot">Standups: Where You Talk Like a Human, Not a Robot</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-sprint-planning">Sprint Planning</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-whats-a-user-story-and-why-does-it-sound-like-a-childrens-book">What’s a User Story and Why Does It Sound Like a Children’s Book?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-counts-as-done-definition-of-done-and-why-its-important">What Counts as “Done”? Definition of Done and Why It’s Important</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-demos-retros-and-saying-the-hard-things">Demos, Retros, and Saying the Hard Things</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-tools-you-might-encounter">Tools You Might Encounter</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-if-youre-preparing-for-a-job-heres-what-you-can-do">If You’re Preparing for a Job, Here’s What You Can Do</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-final-thoughts">Final Thoughts</a></p>
</li>
</ul>
<h2 id="heading-what-even-is-scrum"><strong>What Even Is Scrum?</strong></h2>
<p>Scrum is not a tool. It’s not a software. It’s not some elite thing only PMs care about.</p>
<p>It’s a lightweight framework that helps software teams build things incrementally, together, in short focused cycles called sprints.</p>
<p>Scrum is used by everyone from FAANG teams to indie dev shops because it helps:</p>
<ul>
<li><p>Keep teams aligned</p>
</li>
<li><p>Deliver working software fast</p>
</li>
<li><p>Course-correct often</p>
</li>
<li><p>Spot problems early (before they go nuclear)</p>
</li>
</ul>
<p>It’s the opposite of the old-school “build for a year and pray it works” model.</p>
<h2 id="heading-the-three-roles-in-scrum-and-who-does-what"><strong>The Three Roles in Scrum (and Who Does What)</strong></h2>
<p>Scrum officially defines three roles. Here's what that means in practice:</p>
<h3 id="heading-1-product-owner-po"><strong>1. Product Owner (PO)</strong></h3>
<p>Think: Vision-holder. They decide <em>what</em> the team builds and <em>why</em>. A product owner:</p>
<ul>
<li><p>Writes user stories (think of these as feature requests written from a user’s point of view)</p>
</li>
<li><p>Prioritizes the work</p>
</li>
<li><p>Clarifies what success looks like</p>
</li>
<li><p>Says “yes” or “not yet” to features</p>
</li>
</ul>
<h3 id="heading-2-scrum-master-sm"><strong>2. Scrum Master (SM)</strong></h3>
<p>Think: Air-traffic controller meets therapist. They make sure the process works. The are master Facilitators, like between Dev and PO’s. A Scrum Master:</p>
<ul>
<li><p>Facilitates meetings</p>
</li>
<li><p>Removes blockers (“Your AWS access is stuck? I’ll escalate it.”)</p>
</li>
<li><p>Coaches the team on Scrum practices</p>
</li>
<li><p>Doesn’t manage people – manages <em>flow</em></p>
</li>
</ul>
<h3 id="heading-3-developers-you"><strong>3. Developers (YOU!)</strong></h3>
<p>Think: Builders. You write code, test it, ship it, fix it, and improve it. You also:</p>
<ul>
<li><p>Break down stories into tasks</p>
</li>
<li><p>Pick up work from the team board (like Jira or Trello)</p>
</li>
<li><p>Communicate progress</p>
</li>
<li><p>Demo what you’ve built at the end of the sprint</p>
</li>
</ul>
<p>You might also work with designers, testers, or DevOps folks – but within Scrum, you’re all “developers” building a product together.</p>
<h2 id="heading-the-scrum-rhythm-what-a-sprint-actually-looks-like"><strong>The Scrum Rhythm: What a Sprint Actually Looks Like</strong></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752809790048/253fd92b-1ebe-4f3e-bfbc-48719676dc82.png" alt="253fd92b-1ebe-4f3e-bfbc-48719676dc82" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Image Source: <a target="_blank" href="https://www.invensislearning.com/blog/what-are-scrum-ceremonies/">https://www.invensislearning.com/blog/what-are-scrum-ceremonies/</a></p>
<h3 id="heading-understanding-the-scrum-cycle"><strong>Understanding the Scrum Cycle</strong></h3>
<p>So, what does it <em>actually</em> look like when a team uses Scrum to build software?</p>
<p>Let’s walk through a full sprint – not just the buzzwords, but what really happens when a group of humans tries to plan, build, review, and improve together. Think of this as your backstage pass to the rhythm of modern teamwork.</p>
<h3 id="heading-step-1-build-and-refine-the-product-backlog">📦 Step 1: Build and Refine the Product Backlog</h3>
<p>Before any coding starts, the team needs to agree on <em>what</em> they might build – not just this week, but in the near future too.</p>
<p>That’s where the <strong>Product Backlog</strong> comes in. This is a big, running list of everything the product might need – features, bug fixes, improvements, ideas, and maybe a few wild dreams. It’s like the wishlist for the product, but more organized (ideally).</p>
<p>The Product Owner is responsible for maintaining and prioritizing this list. They decide what’s most important to work on based on customer needs, business goals, and feedback.</p>
<p>But the PO doesn’t do this in isolation. Enter the <strong>Backlog Refinement meeting</strong>.</p>
<p>In these sessions, the Scrum Team – that’s the PO, the Scrum Master (SM), and the Developers – come together to:</p>
<ul>
<li><p><strong>Review</strong> the most important upcoming items</p>
</li>
<li><p><strong>Clarify</strong> any vague or confusing parts of each task</p>
</li>
<li><p><strong>Break big items</strong> down into smaller, buildable pieces called <strong>user stories</strong></p>
</li>
<li><p><strong>Estimate effort</strong> (how much time or complexity is involved for each story)</p>
</li>
</ul>
<p>This meeting makes sure the team isn’t caught off guard in the sprint – that they understand the work ahead and can actually start sprinting when the time comes.</p>
<h3 id="heading-step-2-sprint-planning-what-are-we-building-this-time">🧭 Step 2: Sprint Planning – What Are We Building This Time?</h3>
<p>Now that we’ve got a solid backlog, it’s time to pick what to build <em>right now</em>.</p>
<p>At the start of each sprint (which typically lasts 1 to 4 weeks), the team holds a <strong>Sprint Planning meeting</strong>. This meeting sets the stage for the entire sprint – it’s like the huddle before the big game.</p>
<p>In Sprint Planning, the team:</p>
<ul>
<li><p>Reviews the top items from the backlog</p>
</li>
<li><p>Discusses what can realistically be completed based on their availability and capacity</p>
</li>
<li><p>Chooses a handful of these stories to commit to</p>
</li>
<li><p><strong>Defines a Sprint Goal</strong> – a simple statement that captures the purpose of this sprint</p>
</li>
</ul>
<p>For example, the Sprint Goal might be:<br>🎯 <em>“Allow users to reset their passwords.”</em></p>
<p>Every user story chosen should contribute to that goal. The collection of these stories becomes the <strong>Sprint Backlog</strong> – basically, the to-do list for the sprint.</p>
<p>So when we say:</p>
<p>“The team selects an ordered list of user stories to comprise the Sprint Backlog for the next sprint, which will be achievable to satisfy the Sprint Goal...”</p>
<p>We’re really just saying:<br>👉 <em>“Pick a realistic number of important tasks that, if completed, will help us hit our target for the sprint.”</em></p>
<p>Not too vague. Not too ambitious. Just achievable and focused.</p>
<h3 id="heading-step-3-daily-standups-stay-in-sync">☀️ Step 3: Daily Standups – Stay in Sync</h3>
<p>Now the sprint is underway! But how does everyone stay aligned and avoid working in silos?</p>
<p>That’s where the <strong>Daily Standup</strong> comes in. Every day – usually in the morning – the team has a quick check-in (about 15 minutes) where each person answers three questions:</p>
<ol>
<li><p><strong>What did I do yesterday?</strong></p>
</li>
<li><p><strong>What am I working on today?</strong></p>
</li>
<li><p><strong>Is anything blocking me?</strong> (that is, am I stuck?)</p>
</li>
</ol>
<p>Example:</p>
<p>“Yesterday I set up the login API integration. Today I’ll work on the UI validation. I’m blocked on getting access to the staging database — may need help.”</p>
<p>These standups keep the team in sync and surface blockers early so they can be addressed quickly. They’re not about micromanaging or showing off. They’re about visibility and support.</p>
<h3 id="heading-whats-a-sprint-burndown-chart">📉 What’s a Sprint Burndown Chart?</h3>
<p>You might hear your team mention a “burndown chart.” No, this isn’t about things going down in flames (hopefully).</p>
<p>A <strong>Sprint Burndown Chart</strong> is a graph that shows how much work is left in the sprint – day by day.</p>
<ul>
<li><p>The <strong>y-axis</strong> is the amount of work remaining (often measured in story points or tasks)</p>
</li>
<li><p>The <strong>x-axis</strong> is the number of days left in the sprint</p>
</li>
</ul>
<p>The line should ideally trend downward as work gets completed – hence “burning down.” If it flattens out or slopes up, that’s a red flag that the team might be stuck, behind schedule, or not updating the board.</p>
<p>Think of it as a visual heartbeat of the sprint. You can learn more via a practical example <a target="_blank" href="https://youtu.be/2K84aZn9AY8?si=tS8oMGxVD0CYtnlw">in this video</a>.</p>
<h3 id="heading-step-4-sprint-review-show-what-youve-built">🖥️ Step 4: Sprint Review – Show What You’ve Built</h3>
<p>At the end of the sprint, the team holds a <strong>Sprint Review</strong> (also called a “demo”). This is where you show what was actually built during the sprint.</p>
<ul>
<li><p>The <strong>Developers</strong> demo working features – live, not just screenshots</p>
</li>
<li><p>The <strong>Product Owner</strong> reviews whether the Sprint Goal was achieved</p>
</li>
<li><p>Stakeholders may ask questions, give feedback, or suggest tweaks</p>
</li>
</ul>
<p>This meeting isn’t just for show – it’s a feedback loop. It helps the team validate that what they built is useful, usable, and meets expectations. If changes are needed, those get added to the backlog for future sprints.</p>
<h3 id="heading-step-5-sprint-retrospective-look-back-to-move-forward">🔍 Step 5: Sprint Retrospective – Look Back to Move Forward</h3>
<p>Once the review is done, the team shifts focus from <em>what</em> they built to <em>how</em> they worked together.</p>
<p>Enter the <strong>Sprint Retrospective</strong> – a meeting to reflect on the process, not the product.</p>
<p>The team discusses:</p>
<ul>
<li><p>✅ What went well</p>
</li>
<li><p>❌ What didn’t go so well</p>
</li>
<li><p>🔁 What could be improved next time</p>
</li>
</ul>
<p>This isn’t about pointing fingers. It’s about learning, adapting, and continuously improving how the team collaborates.</p>
<p>The <strong>Scrum Master</strong> often facilitates this meeting and helps turn feedback into action items for the next sprint. For example:</p>
<p>“We underestimated testing time. Next sprint, let’s budget for QA earlier.”</p>
<p>The best teams take retros seriously. Why? Because even if your code is perfect, your <em>process</em> needs tuning too – and small process changes often lead to big gains.</p>
<h3 id="heading-scrum-is-a-loop">♻️ Scrum Is a Loop</h3>
<p>Here’s the rhythm:</p>
<ol>
<li><p>Plan the sprint</p>
</li>
<li><p>Check in daily</p>
</li>
<li><p>Build and demo the product</p>
</li>
<li><p>Reflect and improve</p>
</li>
</ol>
<p>Then do it all over again – with slightly better coordination and slightly more trust each time.</p>
<p>It’s not about being fast. It’s about being intentional, consistent, and collaborative.</p>
<h3 id="heading-example-sprint">Example Sprint</h3>
<p>Let’s say, for example, that your team does 4-week sprints. (Keep in mind that Sprints can differ by team, nature of product, release cycles, and so on.)</p>
<p>Here’s the rough beat:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Week</strong></td><td><strong>What Happens (Sprint Ceremonies)</strong></td><td><strong>Your Role</strong></td></tr>
</thead>
<tbody>
<tr>
<td>1</td><td><strong>Sprint Planning</strong></td><td>Help estimate effort, pick what to build</td></tr>
<tr>
<td>1-4</td><td><strong>Daily Stand ups</strong> (15 mins)</td><td>Share what you’re doing &amp; any blockers</td></tr>
<tr>
<td>1-3</td><td><strong>Development Time</strong></td><td>Code, test, commit, fix, push, repeat</td></tr>
<tr>
<td>3.5-4</td><td><strong>Sprint Review</strong></td><td>Demo what you built</td></tr>
<tr>
<td>4</td><td><strong>Sprint Retrospective</strong></td><td>Reflect on how the sprint went as a team</td></tr>
</tbody>
</table>
</div><p>Scrum works in <strong>loops</strong>. Every 2-4 weeks (depending on your cadence and sprint cycle), your team should have working, demo-able software to show for it – even if it’s small.</p>
<p>And no, it’s not about “speed.” It’s about consistency, communication, and collaboration.</p>
<h2 id="heading-who-attends-the-ceremonies"><strong>Who attends the Ceremonies:</strong></h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Ceremony</strong></td><td><strong>Who Attends</strong></td><td><strong>Why They’re There</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Sprint Planning</strong></td><td>Product Owner (PO), Scrum Master (SM), Development Team</td><td>To define what will be delivered and how the work will be accomplished</td></tr>
<tr>
<td><strong>Daily Standup</strong></td><td>Development Team, Scrum Master (optional), PO (optional)</td><td>To sync on progress, share blockers, and coordinate efforts</td></tr>
<tr>
<td><strong>Sprint Review</strong></td><td>Development Team, Scrum Master, Product Owner, Stakeholders</td><td>To demo the work, get feedback, and assess if goals were met</td></tr>
<tr>
<td><strong>Sprint Retrospective</strong></td><td>Development Team, Scrum Master, Product Owner (optional)</td><td>To reflect on the process, identify what worked/what didn’t, and improve the next sprint</td></tr>
<tr>
<td><strong>Backlog Refinement</strong></td><td>Product Owner, Development Team, Scrum Master (optional)</td><td>To clarify upcoming stories, estimate work, and prepare for future sprint planning</td></tr>
</tbody>
</table>
</div><p>Now lets dive deeper and understand practically how each of these ceremonies work:</p>
<h2 id="heading-standups-where-you-talk-like-a-human-not-a-robot"><strong>Standups: Where You Talk Like a Human, Not a Robot</strong></h2>
<p>So how does the team actually stay connected day to day? That’s where standups come in.</p>
<p>Every morning, your team meets briefly – usually on Zoom or in a circle – and you answer 3 questions:</p>
<ol>
<li><p>What did I work on yesterday?</p>
</li>
<li><p>What will I work on today?</p>
</li>
<li><p>What’s blocking me? Any impediments?</p>
</li>
</ol>
<p>Example:</p>
<p>"Yesterday I cleaned up the signup validation logic. Today I’m working on the email verification flow. I’m stuck on SendGrid config – might need help setting up credentials."</p>
<p>It’s not about impressing anyone. It’s about keeping everyone in sync. Some days you’ll say, “I spent the whole day debugging a CSS bug that turned out to be a semicolon.” That’s okay.</p>
<p>How does it work?</p>
<p>The Scrum Master gathers everyone in a huddle room, the PO and Dev Team included, and opens the the Standup. They are the facilitator of the ceremony. Everyone gets a chance to answer the 3 questions above (usually about 2-5 minutes each). It’s not a full report – it’s quick. When one person is done, they pass it on to someone else.</p>
<p>This ensures there is team cohesion and transparency.</p>
<p><a target="_blank" href="https://youtu.be/q_R9wQY4G5I?si=W1AcvcLXB-mnUM1f">Here is a video example of a standup</a>.</p>
<h2 id="heading-sprint-planning"><strong>Sprint Planning</strong></h2>
<p>The goal of the planning meeting is to answer the questions “What are we going to work on, and how are we going to do it?” It is critical for the team to have a shared goal and a shared commitment to this goal before beginning this ceremony.</p>
<p>Participants should:</p>
<ul>
<li><p>Measure growth</p>
</li>
<li><p>Sync with the Scrum Master</p>
</li>
<li><p>Sync with the Product Owner</p>
</li>
</ul>
<p>Sprint planning happens just before the sprint starts, and usually lasts for an hour or two. In this meeting, the team goes over a collection of <strong>user stories</strong> and discuss, plan, measure, and prioritize. This is where they decide what is going to be in scope for their upcoming sprint cycle.</p>
<p>The Product Owner will have a prioritized view of things in the backlog. They work with the team on each object or customer experience. Together, as a group they go through and make calculations, deciding to what they can commit.</p>
<h2 id="heading-whats-a-user-story-and-why-does-it-sound-like-a-childrens-book"><strong>What’s a User Story and Why Does It Sound Like a Children’s Book?</strong></h2>
<p>So you might be wondering: how do you know what to work on? What to build? So much work, so little time? Thats where <strong>user stories</strong> come in.</p>
<p>In Scrum, teams don’t just write vague tasks like “code the login.” Instead, they write user stories – short, human-centered feature descriptions that describe what the user needs, why they need it, and what success looks like.</p>
<p>Here’s an example:</p>
<p><em>As a user, I want to be able to reset my password, so I can access my account if I forget it.</em></p>
<p>User stories are the scaffolding of teamwork. They’re written with empathy, not just efficiency. And each one comes with <strong>acceptance criteria</strong> – a checklist that clarifies what “done” actually means:</p>
<ul>
<li><p>A “Forgot Password” link is visible</p>
</li>
<li><p>Clicking it shows a form</p>
</li>
<li><p>An email gets sent with a reset link</p>
</li>
</ul>
<p>Once a story is agreed upon, developers break it down into tasks, like “build form,” “hook into backend,” or “handle email validation.” It’s collaborative, not prescriptive. And user stories have priority so you know what’s the most important and what’s the least.</p>
<p>A helpful rule of thumb many teams use is the <a target="_blank" href="https://medium.com/@nic/writing-user-stories-with-gherkin-dda63461b1d2"><strong>Gherkin</strong>-style "Given–When–Then"</a> format:</p>
<ul>
<li><p><strong>Given</strong> some initial context</p>
</li>
<li><p><strong>When</strong> an event occurs</p>
</li>
<li><p><strong>Then</strong> a specific outcome should happen</p>
</li>
</ul>
<p>This ensures that everyone – devs, testers, and product owners – shares the same understanding of behavior and expectations.</p>
<p><a target="_blank" href="https://www.youtube.com/watch?v=7hoGqhb6qAs">Here is a great video example</a> thats outlines how to draft effective and powerful user stories.</p>
<h2 id="heading-what-counts-as-done-definition-of-done-and-why-its-important"><strong>What Counts as “Done”? Definition of Done and Why It’s Important</strong></h2>
<p>Now you might be wondering – how do I know when a task is done and can be closed out?</p>
<p>The <strong>Definition of Done</strong> is a type of documentation in the form of a <strong>team agreement</strong>. The Definition of Done identifies the conditions that need to be achieved in order for the product to be considered done (as in <strong>potentially shippable</strong>).</p>
<p>This is how we know that we "did the thing right". Meaning, we built the correct level of quality into the product. The Definition of Done is not the same as the acceptance criteria, which are written by the product owner to help us know we did the "right thing".</p>
<p>Every team has a Definition of Done – it’s not just “I pushed code.” It could mean:</p>
<ul>
<li><p>Code is written</p>
</li>
<li><p>Reviewed by a peer</p>
</li>
<li><p>Merged into main</p>
</li>
<li><p>Tested on staging</p>
</li>
<li><p>Possibly deployed</p>
</li>
</ul>
<p>This clarity keeps teams honest and accountable. No “it works on my machine” energy here. The DoD sets a quality bar. It prevents ambiguity, rework, and “it works on my machine” moments. When every card on the board passes the same finish line, teams move faster – and trust each other more.</p>
<p>Everyone should know what done is in a team. Either its Done as per DoD standards or its not.</p>
<p><a target="_blank" href="https://youtu.be/pYOJyQoBT3U?si=nVygkQQx79NaAOo4">Here is a beautiful video</a> highlighting the impotence of DoD.</p>
<h2 id="heading-demos-retros-and-saying-the-hard-things"><strong>Demos, Retros, and Saying the Hard Things</strong></h2>
<p>Once you’ve built the product, then comes demos (showcasing your work) and retros (analysis as a team on what when well and what areas to improve on).</p>
<p>In the retro, everyone’s encouraged to speak up:</p>
<ul>
<li><p>What went well?</p>
</li>
<li><p>What didn’t?</p>
</li>
<li><p>What should we try next time?</p>
</li>
</ul>
<p>Example:</p>
<p>“We missed a lot of stories because we didn’t account for testing time. Maybe we buffer next sprint with fewer tasks.”</p>
<p>The goal is not to blame – it’s to <em>improve</em>. Over time, this feedback loop becomes gold. The Scrum Master usually facilitates, collects feedback (via tools like Parabol, Miro, or sticky notes), and helps turn insights into actionable experiments for the next sprint.</p>
<p>Over time, retros become the heartbeat of team evolution.</p>
<p><a target="_blank" href="https://youtu.be/5eu1HotNmWs?si=1DZaSmztB6rHyawj">Here is a video</a> highlighting the importance of a Retro and Sprint Review.</p>
<h3 id="heading-why-retrospection-matters-more-than-you-think">🧠 Why Retrospection Matters More Than You Think</h3>
<p>The Sprint Retrospective is more than just another meeting. It’s a mirror for your team – a safe, structured space to pause, reflect, and improve together.</p>
<p>You discuss:</p>
<p>✅ what went well</p>
<p>❌ what did not go well</p>
<p>🔁 what could we do better next time</p>
<p>Great teams don't just deliver great software, they continually deliver better ways of working.</p>
<p>This is why many experienced Scrum practitioners consider the retro to be the most important event in Scrum. Code is deployed once, but process improvements grow exponentially, sprint after sprint.</p>
<h2 id="heading-tools-you-might-encounter"><strong>Tools You Might Encounter</strong></h2>
<p>Scrum doesn’t require software, but real-world teams use a variety of tools:</p>
<ul>
<li><p><strong>Jira</strong> – Tracks sprints, issues, velocity</p>
</li>
<li><p><strong>Trello</strong> – Simple board, good for small teams</p>
</li>
<li><p><strong>Slack</strong> – Where standups often happen if async</p>
</li>
<li><p><strong>Notion / Confluence</strong> – Docs, retros, notes</p>
</li>
<li><p><strong>GitHub Projects</strong> – Lightweight planning for devs</p>
</li>
</ul>
<p>Don’t worry if you’re not fluent in these yet. They’re tools – you’ll learn them on the job.</p>
<h2 id="heading-if-youre-preparing-for-a-job-heres-what-you-can-do"><strong>If You’re Preparing for a Job, Here’s What You Can Do</strong></h2>
<ul>
<li><p>✍️ Practice writing user stories from your side projects</p>
</li>
<li><p>🧪 Run a mini-sprint: Plan your weekend project, set goals, and “review” it at the end</p>
</li>
<li><p>🤝 Contribute to an open-source project that uses Scrum or Agile workflows</p>
</li>
<li><p>🧾 Write about what you learned – maybe as a tutorial (<em>hint hint</em>)</p>
</li>
</ul>
<h2 id="heading-final-thoughts"><strong>Final Thoughts</strong></h2>
<p>So to recap, Scrum is a simple yet powerful way for teams to work together, stay organized, and deliver results quickly. It runs in short cycles called <strong>sprints</strong>, where the team plans what to do, checks in daily, shows their progress at the end, and reflects on how to improve.</p>
<p>The four key ceremonies – <strong>Sprint Planning</strong>, <strong>Daily Scrum</strong>, <strong>Sprint Review</strong>, and <strong>Sprint Retrospective</strong> – help keep everyone aligned and focused. With clear roles and regular feedback, Scrum makes it easier to handle changes, solve problems early, and continuously get better as a team.</p>
<p>But scrum isn’t a magic spell. It’s just a way for humans to build complex things – together – without falling apart.</p>
<p>You don’t need to be a Scrum Master. You don’t need a certification. But if you understand how sprints work, what’s expected of you, and how to show up to meetings with clarity and candor, you’re 10 steps ahead of most.</p>
<p>Scrum helps teams talk, plan, build, and learn. And now? You can too.</p>
<p>If you liked this, please do share. You never know who it might help out.</p>
<p>Until then…keep learning, unlearning, and relearning!!!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build Your Own Local AI: Create Free RAG and AI Agents with Qwen 3 and Ollama ]]>
                </title>
                <description>
                    <![CDATA[ The landscape of Artificial Intelligence is rapidly evolving, and one of the most exciting trends is the ability to run powerful Large Language Models (LLMs) directly on your local machine. This shift away from reliance on cloud-based APIs offers sig... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-local-ai/</link>
                <guid isPermaLink="false">681a35d4d5da806f5e9467b1</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Artificial Intelligence ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chaitanya Rahalkar ]]>
                </dc:creator>
                <pubDate>Tue, 06 May 2025 16:16:20 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746545253944/58b04b54-e443-4804-bedd-3290bfda5bb7.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The landscape of Artificial Intelligence is rapidly evolving, and one of the most exciting trends is the ability to run powerful Large Language Models (LLMs) directly on your local machine.</p>
<p>This shift away from reliance on cloud-based APIs offers significant advantages in terms of privacy, cost-effectiveness, and offline accessibility. Developers and enthusiasts can now experiment with and deploy sophisticated AI capabilities without sending data externally or incurring API fees.</p>
<p>This tutorial serves as a practical, hands-on guide to harnessing this local AI power. It focuses on leveraging the Qwen 3 family of LLMs, a state-of-the-art open-source offering from Alibaba, combined with Ollama, a tool that dramatically simplifies running LLMs locally.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before diving into this tutorial, you should have a foundational understanding of Python programming and be comfortable using the command line or terminal. Make sure you have Python 3 installed on your system.</p>
<p>While prior experience with AI or Large Language Models (LLMs) is beneficial, it's not essential, as I’ll introduce and explain core concepts like Retrieval-Augmented Generation (RAG) and AI agents throughout the guide.</p>
<p>This tutorial serves as a practical, hands-on guide to harnessing this local AI power. It focuses on leveraging the Qwen 3 family of LLMs, a state-of-the-art open-source offering from Alibaba, combined with Ollama, a tool that dramatically simplifies running LLMs locally.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-local-ai-power-with-qwen-3-and-ollama">Local AI Power with Qwen 3 and Ollama</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-ollama-your-local-llm-gateway">Ollama: Your Local LLM Gateway</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-tutorial-roadmap">Tutorial Roadmap</a></p>
</li>
</ul>
</li>
</ol>
<ol start="2">
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-your-local-ai-lab">How to Set Up Your Local AI Lab</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-install-ollama">Install Ollama</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-choose-your-qwen-3-model">Choose Your Qwen 3 Model</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-pull-and-run-qwen-3-with-ollama">Pull and Run Qwen 3 with Ollama</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-set-up-your-python-environment">Set Up Your Python Environment</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-a-local-rag-system-with-qwen-3">How to Build a Local RAG System with Qwen 3</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-step-1-prepare-your-data">Step 1: Prepare Your Data</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-load-documents-in-python">Step 2: Load Documents in Python</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-split-documents">Step 3: Split Documents</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-4-choose-and-configure-embedding-model">Step 4: Choose and Configure Embedding Model</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-5-set-up-local-vector-store-chromadb">Step 5: Set Up Local Vector Store (ChromaDB)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-6-index-documents-embed-and-store">Step 6: Index Documents (Embed and Store)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-7-build-the-rag-chain">Step 7: Build the RAG Chain</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-8-query-your-documents">Step 8: Query Your Documents</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-local-ai-agents-with-qwen-3">How to Create Local AI Agents with Qwen 3</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-step-1-define-custom-tools">Step 1: Define Custom Tools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-set-up-the-agent-llm">Step 2: Set up the Agent LLM</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-create-the-agent-prompt">Step 3: Create the Agent Prompt</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-4-build-the-agent">Step 4: Build the Agent</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-5-create-the-agent-executor">Step 5: Create the Agent Executor</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-6-run-the-agent">Step 6: Run the Agent</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-advanced-considerations-and-troubleshooting">Advanced Considerations and Troubleshooting</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-controlling-qwen-3s-thinking-mode-with-ollama">Controlling Qwen 3's Thinking Mode with Ollama</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-managing-context-length-numctx">Managing Context Length (num_ctx)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-hardware-limitations-and-vram">Hardware Limitations and VRAM</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion-and-next-steps">Conclusion and Next Steps</a></p>
</li>
</ol>
<h2 id="heading-local-ai-power-with-qwen-3-and-ollama">Local AI Power with Qwen 3 and Ollama</h2>
<p>Running LLMs locally addresses several key concerns associated with cloud-based AI services.</p>
<ul>
<li><p>Privacy is paramount – data processed locally never leaves the user's machine.</p>
</li>
<li><p>Cost is another major factor – utilizing open-source models and tools like Ollama eliminates API subscription fees and pay-per-token charges, making advanced AI accessible to everyone.</p>
</li>
<li><p>Local execution enables offline functionality – crucial for applications where internet connectivity is unreliable or undesirable.</p>
</li>
</ul>
<h3 id="heading-ollama-your-local-llm-gateway">Ollama: Your Local LLM Gateway</h3>
<p>Ollama acts as a bridge, making the power of models like Qwen 3 accessible on local hardware. It's a command-line tool that simplifies the download, setup, and execution of various open-source LLMs across macOS, Linux, and Windows.</p>
<p>Ollama handles the complexities of model configuration and GPU utilization, providing a straightforward interface for developers and users. It also exposes an OpenAI-compatible API endpoint, allowing seamless integration with popular frameworks like LangChain.</p>
<h3 id="heading-tutorial-roadmap">Tutorial Roadmap</h3>
<p>This tutorial will guide you through the process of:</p>
<ol>
<li><p><strong>Setting up a local AI environment:</strong> Installing Ollama and selecting/running appropriate Qwen 3 models.</p>
</li>
<li><p><strong>Building a local RAG system:</strong> Creating a system that allows chatting with personal documents using Qwen 3, Ollama, LangChain, and ChromaDB for vector storage.</p>
</li>
<li><p><strong>Creating a basic local AI agent:</strong> Developing a simple agent powered by Qwen 3 that can utilize custom-defined tools (functions).</p>
</li>
</ol>
<h2 id="heading-how-to-set-up-your-local-ai-lab">How to Set Up Your Local AI Lab</h2>
<p>The first step is to prepare your local machine with the necessary tools and models.</p>
<h3 id="heading-install-ollama">Install Ollama</h3>
<p>Ollama provides the simplest path to running LLMs locally.</p>
<ul>
<li><p><strong>Linux / macOS:</strong> Open a terminal and run the official installation script:</p>
<pre><code class="lang-bash">  curl -fsSL https://ollama.com/install.sh | sh
</code></pre>
</li>
<li><p><strong>Windows:</strong> Download the installer from the Ollama website (<a target="_blank" href="https://ollama.com/download">https://ollama.com/download</a>) and follow the setup instructions.</p>
</li>
</ul>
<p>After installation, verify it by opening a new terminal window and running:</p>
<pre><code class="lang-bash">ollama --version
</code></pre>
<p>Ollama typically stores downloaded models in <code>~/.ollama/models</code> on macOS and <code>/usr/share/ollama/.ollama/models</code> on Linux/WSL.</p>
<h3 id="heading-choose-your-qwen-3-model">Choose Your Qwen 3 Model</h3>
<p>Selecting the right Qwen 3 model is crucial and depends on your intended task and available hardware, primarily system RAM and GPU VRAM. Running larger models requires more resources but generally offers better performance and reasoning capabilities.</p>
<p>Qwen 3 offers two main architectures available through Ollama:</p>
<ul>
<li><p><strong>Dense Models:</strong> (like <code>qwen3:0.6b</code>, <code>qwen3:4b</code>, <code>qwen3:8b</code>, <code>qwen3:14b</code>, <code>qwen3:32b</code>) These models activate all their parameters during inference. Their performance is predictable, but resource requirements scale directly with parameter count.</p>
</li>
<li><p><strong>Mixture-of-Experts (MoE) Models:</strong> (like <code>qwen3:30b-a3b</code>) These models contain many "expert" sub-networks but only activate a small fraction for each input token. This allows them to achieve the performance characteristic of their large total parameter count (for example, 30 billion) while having inference costs closer to their smaller <em>active</em> parameter count (for example, 3 billion). They offer a compelling balance of capability and efficiency, especially for reasoning and coding tasks.</p>
</li>
</ul>
<p><strong>Recommendation for this tutorial:</strong> For the examples that follow, <code>qwen3:8b</code> strikes a good balance between capability and resource requirements for many modern machines. If resources are more constrained, <code>qwen3:4b</code> is a viable alternative. The MoE model <code>qwen3:30b-a3b</code> offers excellent performance, especially for coding and reasoning, and runs surprisingly well on systems with 16GB+ VRAM due to its sparse activation.</p>
<h3 id="heading-pull-and-run-qwen-3-with-ollama">Pull and Run Qwen 3 with Ollama</h3>
<p>Once you’ve chosen a model, you’ll need to download it (pull it) via Ollama.</p>
<p><strong>Pull the model:</strong> Open the terminal and run (replace <code>qwen3:8b</code> with the desired tag):</p>
<pre><code class="lang-bash">ollama pull qwen3:8b
</code></pre>
<p>This command downloads the model weights and configuration.</p>
<p><strong>Run interactively (optional test):</strong> To chat directly with the model from the command line:</p>
<pre><code class="lang-bash">ollama run qwen3:8b
</code></pre>
<p>Type prompts directly into the terminal. Use <code>/bye</code> to exit the session. Other useful commands within the interactive session include <code>/?</code> for help and <code>/set parameter &lt;name&gt; &lt;value&gt;</code> (for example, <code>/set parameter num_ctx 8192</code>) to temporarily change model parameters for the current session. Use <code>ollama list</code> outside the session to see downloaded models.</p>
<p><strong>Run as a server:</strong> For integration with Python scripts (using LangChain), Ollama needs to run as a background server process, exposing an API. Open a <em>separate</em> terminal window and run:</p>
<pre><code class="lang-bash">ollama serve
</code></pre>
<p>Keep this terminal window open while running the Python scripts. This command starts the server, typically listening on <code>http://localhost:11434</code>, providing an OpenAI-compatible API endpoint.</p>
<h3 id="heading-set-up-your-python-environment">Set Up Your Python Environment</h3>
<p>A dedicated Python environment is recommended for managing dependencies.</p>
<p><strong>Create a virtual environment:</strong></p>
<pre><code class="lang-bash">python -m venv venv
</code></pre>
<p><strong>Activate the environment:</strong></p>
<ul>
<li><p>macOS/Linux: <code>source venv/bin/activate</code></p>
</li>
<li><p>Windows: <code>venv\Scripts\activate</code></p>
</li>
</ul>
<p><strong>Install necessary libraries:</strong></p>
<pre><code class="lang-bash">pip install langchain langchain-community langchain-core langchain-ollama chromadb sentence-transformers pypdf python-dotenv unstructured[pdf] tiktoken
</code></pre>
<ul>
<li><p><code>langchain</code>, <code>langchain-community</code>, <code>langchain-core</code>: The core LangChain framework for building LLM applications.</p>
</li>
<li><p><code>langchain-ollama</code>: Specific integration for using Ollama models with LangChain.</p>
</li>
<li><p><code>chromadb</code>: The local vector database for storing document embeddings.</p>
</li>
<li><p><code>sentence-transformers</code>: Used for an alternative local embedding method (explained later).</p>
</li>
<li><p><code>pypdf</code>: A library for loading PDF documents.</p>
</li>
<li><p><code>python-dotenv</code>: For managing environment variables (optional but good practice).</p>
</li>
<li><p><code>unstructured[pdf]</code>: An alternative, powerful document loader, especially for complex PDFs.</p>
</li>
<li><p><code>tiktoken</code>: Used by LangChain for token counting.</p>
</li>
</ul>
<p>The local setup involves coordinating several independent components: Ollama itself, the specific Qwen 3 model weights, the Python environment, and various libraries like LangChain and ChromaDB. Ensuring compatibility between these pieces and correctly configuring parameters (like Ollama's context window size or selecting a model appropriate for the available VRAM) is key to a smooth experience.</p>
<p>While this modularity offers flexibility – allowing components like the LLM or vector store to be swapped – it also means the initial setup requires careful attention to detail. This tutorial aims to provide clear steps and sensible defaults to minimize potential friction points.</p>
<h2 id="heading-how-to-build-a-local-rag-system-with-qwen-3">How to Build a Local RAG System with Qwen 3</h2>
<p>Retrieval-Augmented Generation (RAG) is a powerful technique that enhances LLMs by providing them with external knowledge.</p>
<p>Instead of relying solely on its training data, the LLM can retrieve relevant information from a specified document set (like local PDFs) and uses that information to answer questions. This significantly reduces "hallucinations" (incorrect or fabricated information) and allows the LLM to answer questions about specific, private data without needing retraining.</p>
<p>The core RAG process involves:</p>
<ol>
<li><p>Loading and splitting documents into manageable chunks.</p>
</li>
<li><p>Converting these chunks into numerical representations (embeddings) using an embedding model.</p>
</li>
<li><p>Storing these embeddings in a vector database for efficient searching.</p>
</li>
<li><p>When a query comes in, embedding the query and searching the vector database for the most similar document chunks.</p>
</li>
<li><p>Providing these relevant chunks (context) along with the original query to the LLM to generate an informed answer.</p>
</li>
</ol>
<p>Let's build this locally using Qwen 3, Ollama, LangChain, and ChromaDB.</p>
<h3 id="heading-step-1-prepare-your-data">Step 1: Prepare Your Data</h3>
<p>Create a directory named <code>data</code> in the project folder. Place the PDF document that you intend to query into this directory. For this tutorial, using a single, primarily text-based PDF (like a research paper or a report) for simplicity.</p>
<pre><code class="lang-bash">mkdir data
<span class="hljs-comment"># Copy your PDF file into the 'data' directory</span>
<span class="hljs-comment"># e.g., cp ~/Downloads/some_paper.pdf./data/mydocument.pdf</span>
</code></pre>
<p>If you don’t have a PDF readily available that you’d like to use, you can download a sample PDF (the Llama 2 paper) for this tutorial using the following command in your terminal:</p>
<pre><code class="lang-bash">
wget --user-agent <span class="hljs-string">"Mozilla"</span> <span class="hljs-string">"https://arxiv.org/pdf/2307.09288.pdf"</span> -O <span class="hljs-string">"data/llama2.pdf"</span>
</code></pre>
<p>This command creates the <code>data</code> directory and downloads the PDF, saving it as <code>llama2.pdf</code> inside the <code>data</code> directory. If you prefer to use your own document, place your PDF file into the <code>data</code> directory and update the filename in the subsequent Python code.</p>
<h3 id="heading-step-2-load-documents-in-python">Step 2: Load Documents in Python</h3>
<p>Use LangChain's document loaders to read the PDF content. <code>PyPDFLoader</code> is straightforward for simple PDFs. <code>UnstructuredPDFLoader</code> (requires <code>unstructured[pdf]</code>) can handle more complex layouts but has more dependencies.</p>
<pre><code class="lang-python"><span class="hljs-comment"># rag_local.py</span>
<span class="hljs-keyword">import</span> os
<span class="hljs-keyword">from</span> dotenv <span class="hljs-keyword">import</span> load_dotenv
<span class="hljs-keyword">from</span> langchain_community.document_loaders <span class="hljs-keyword">import</span> PyPDFLoader <span class="hljs-comment"># Or UnstructuredPDFLoader</span>

load_dotenv() <span class="hljs-comment"># Optional: Loads environment variables from.env file</span>

DATA_PATH = <span class="hljs-string">"data/"</span>
PDF_FILENAME = <span class="hljs-string">"mydocument.pdf"</span> <span class="hljs-comment"># Replace with your PDF filename</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">load_documents</span>():</span>
    <span class="hljs-string">"""Loads documents from the specified data path."""</span>
    pdf_path = os.path.join(DATA_PATH, PDF_FILENAME)
    loader = PyPDFLoader(pdf_path)
    <span class="hljs-comment"># loader = UnstructuredPDFLoader(pdf_path) # Alternative</span>
    documents = loader.load()
    print(<span class="hljs-string">f"Loaded <span class="hljs-subst">{len(documents)}</span> page(s) from <span class="hljs-subst">{pdf_path}</span>"</span>)
    <span class="hljs-keyword">return</span> documents

<span class="hljs-comment"># documents = load_documents() # Call this later</span>
</code></pre>
<h3 id="heading-step-3-split-documents">Step 3: Split Documents</h3>
<p>Large documents need to be split into smaller chunks suitable for embedding and retrieval. The <code>RecursiveCharacterTextSplitter</code> attempts to split text semantically (at paragraphs, sentences, and so on) before resorting to fixed-size splits. <code>chunk_size</code> determines the maximum size of each chunk (in characters), and <code>chunk_overlap</code> specifies how many characters should overlap between consecutive chunks to maintain context.</p>
<pre><code class="lang-python"><span class="hljs-comment"># rag_local.py (continued)</span>
<span class="hljs-keyword">from</span> langchain_text_splitters <span class="hljs-keyword">import</span> RecursiveCharacterTextSplitter

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">split_documents</span>(<span class="hljs-params">documents</span>):</span>
    <span class="hljs-string">"""Splits documents into smaller chunks."""</span>
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=<span class="hljs-number">1000</span>,
        chunk_overlap=<span class="hljs-number">200</span>,
        length_function=len,
        is_separator_regex=<span class="hljs-literal">False</span>,
    )
    all_splits = text_splitter.split_documents(documents)
    print(<span class="hljs-string">f"Split into <span class="hljs-subst">{len(all_splits)}</span> chunks"</span>)
    <span class="hljs-keyword">return</span> all_splits

<span class="hljs-comment"># loaded_docs = load_documents()</span>
<span class="hljs-comment"># chunks = split_documents(loaded_docs) # Call this later</span>
</code></pre>
<h3 id="heading-step-4-choose-and-configure-embedding-model">Step 4: Choose and Configure Embedding Model</h3>
<p>Embeddings transform text into vectors (lists of numbers) such that semantically similar text chunks have vectors that are close together in multi-dimensional space.</p>
<h4 id="heading-option-a-recommended-for-simplicity-ollama-embeddings">Option A (Recommended for Simplicity): Ollama Embeddings</h4>
<p>This approach uses Ollama to serve a dedicated embedding model. nomic-embed-text is a capable open-source model available via Ollama.</p>
<p>First, ensure the embedding model is pulled:</p>
<pre><code class="lang-bash">ollama pull nomic-embed-text
</code></pre>
<p>Then, use <code>OllamaEmbeddings</code> in Python:</p>
<pre><code class="lang-python"><span class="hljs-comment"># rag_local.py (continued)</span>
<span class="hljs-keyword">from</span> langchain_ollama <span class="hljs-keyword">import</span> OllamaEmbeddings

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_embedding_function</span>(<span class="hljs-params">model_name=<span class="hljs-string">"nomic-embed-text"</span></span>):</span>
    <span class="hljs-string">"""Initializes the Ollama embedding function."""</span>
    <span class="hljs-comment"># Ensure Ollama server is running (ollama serve)</span>
    embeddings = OllamaEmbeddings(model=model_name)
    print(<span class="hljs-string">f"Initialized Ollama embeddings with model: <span class="hljs-subst">{model_name}</span>"</span>)
    <span class="hljs-keyword">return</span> embeddings

<span class="hljs-comment"># embedding_function = get_embedding_function() # Call this later</span>
</code></pre>
<h4 id="heading-option-b-alternative-sentence-transformers">Option B (Alternative): Sentence Transformers</h4>
<p>This uses the sentence-transformers library directly within the Python script. It requires installing the library (pip install sentence-transformers) but doesn't need a separate Ollama process for embeddings. Models like all-MiniLM-L6-v2 are fast and lightweight, while all-mpnet-base-v2 offers higher quality.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Alternative embedding function using Sentence Transformers</span>
<span class="hljs-keyword">from</span> langchain_community.embeddings <span class="hljs-keyword">import</span> HuggingFaceEmbeddings

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_embedding_function_hf</span>(<span class="hljs-params">model_name=<span class="hljs-string">"all-MiniLM-L6-v2"</span></span>):</span>
     <span class="hljs-string">"""Initializes HuggingFace embeddings (runs locally)."""</span>
     embeddings = HuggingFaceEmbeddings(model_name=model_name)
     print(<span class="hljs-string">f"Initialized HuggingFace embeddings with model: <span class="hljs-subst">{model_name}</span>"</span>)
     <span class="hljs-keyword">return</span> embeddings

embedding_function = get_embedding_function_hf() <span class="hljs-comment"># Use this if choosing Option B</span>
</code></pre>
<p>For this tutorial, we’ll use Option A (Ollama Embeddings with <code>nomic-embed-text</code>) to keep the toolchain consistent.</p>
<h3 id="heading-step-5-set-up-local-vector-store-chromadb">Step 5: Set Up Local Vector Store (ChromaDB)</h3>
<p>ChromaDB provides an efficient way to store and search vector embeddings locally. Using a persistent client ensures the indexed data is saved to disk and can be reloaded without re-processing the documents every time.</p>
<pre><code class="lang-python"><span class="hljs-comment"># rag_local.py (continued)</span>
<span class="hljs-keyword">from</span> langchain_community.vectorstores <span class="hljs-keyword">import</span> Chroma

CHROMA_PATH = <span class="hljs-string">"chroma_db"</span> <span class="hljs-comment"># Directory to store ChromaDB data</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_vector_store</span>(<span class="hljs-params">embedding_function, persist_directory=CHROMA_PATH</span>):</span>
    <span class="hljs-string">"""Initializes or loads the Chroma vector store."""</span>
    vectorstore = Chroma(
        persist_directory=persist_directory,
        embedding_function=embedding_function
    )
    print(<span class="hljs-string">f"Vector store initialized/loaded from: <span class="hljs-subst">{persist_directory}</span>"</span>)
    <span class="hljs-keyword">return</span> vectorstore

embedding_function = get_embedding_function()
vector_store = get_vector_store(embedding_function) <span class="hljs-comment"># Call this later</span>
</code></pre>
<h3 id="heading-step-6-index-documents-embed-and-store">Step 6: Index Documents (Embed and Store)</h3>
<p>This is the core indexing step where document chunks are converted to embeddings and saved in ChromaDB. The <code>Chroma.from_documents</code> function is convenient for the initial creation and indexing. If the database already exists, subsequent additions can use <code>vectorstore.add_documents</code>.</p>
<pre><code class="lang-python"><span class="hljs-comment"># rag_local.py (continued)</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">index_documents</span>(<span class="hljs-params">chunks, embedding_function, persist_directory=CHROMA_PATH</span>):</span>
    <span class="hljs-string">"""Indexes document chunks into the Chroma vector store."""</span>
    print(<span class="hljs-string">f"Indexing <span class="hljs-subst">{len(chunks)}</span> chunks..."</span>)
    <span class="hljs-comment"># Use from_documents for initial creation.</span>
    <span class="hljs-comment"># This will overwrite existing data if the directory exists but isn't a valid Chroma DB.</span>
    <span class="hljs-comment"># For incremental updates, initialize Chroma first and use vectorstore.add_documents().</span>
    vectorstore = Chroma.from_documents(
        documents=chunks,
        embedding=embedding_function,
        persist_directory=persist_directory
    )
    vectorstore.persist() <span class="hljs-comment"># Ensure data is saved</span>
    print(<span class="hljs-string">f"Indexing complete. Data saved to: <span class="hljs-subst">{persist_directory}</span>"</span>)
    <span class="hljs-keyword">return</span> vectorstore

<span class="hljs-comment">#... (previous function calls)</span>
vector_store = index_documents(chunks, embedding_function) <span class="hljs-comment"># Call this for initial indexing</span>
</code></pre>
<p>To load an existing persistent database later:</p>
<pre><code class="lang-python">embedding_function = get_embedding_function()
vector_store = Chroma(persist_directory=CHROMA_PATH, embedding_function=embedding_function)
</code></pre>
<h3 id="heading-step-7-build-the-rag-chain">Step 7: Build the RAG Chain</h3>
<p>Now, assemble the components into a LangChain Expression Language (LCEL) chain. This involves initializing the Qwen 3 LLM via Ollama, creating a retriever from the vector store, defining a suitable prompt, and chaining them together.</p>
<p>A critical parameter when initializing <code>ChatOllama</code> for RAG is <code>num_ctx</code>. This defines the context window size (in tokens) that the LLM can handle. Ollama's default (often 2048 or 4096 tokens) might be too small to accommodate both the retrieved document context and the user's query/prompt.</p>
<p>Qwen 3 models (8B and larger) support much larger context windows (for example, 128k tokens), but practical limits depend on your available RAM/VRAM. Setting <code>num_ctx</code> to a value like 8192 or higher is often necessary for effective RAG.</p>
<pre><code class="lang-python"><span class="hljs-comment"># rag_local.py (continued)</span>
<span class="hljs-keyword">from</span> langchain_ollama <span class="hljs-keyword">import</span> ChatOllama
<span class="hljs-keyword">from</span> langchain_core.prompts <span class="hljs-keyword">import</span> ChatPromptTemplate
<span class="hljs-keyword">from</span> langchain_core.runnables <span class="hljs-keyword">import</span> RunnablePassthrough
<span class="hljs-keyword">from</span> langchain_core.output_parsers <span class="hljs-keyword">import</span> StrOutputParser

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">create_rag_chain</span>(<span class="hljs-params">vector_store, llm_model_name=<span class="hljs-string">"qwen3:8b"</span>, context_window=<span class="hljs-number">8192</span></span>):</span>
    <span class="hljs-string">"""Creates the RAG chain."""</span>
    <span class="hljs-comment"># Initialize the LLM</span>
    llm = ChatOllama(
        model=llm_model_name,
        temperature=<span class="hljs-number">0</span>, <span class="hljs-comment"># Lower temperature for more factual RAG answers</span>
        num_ctx=context_window <span class="hljs-comment"># IMPORTANT: Set context window size</span>
    )
    print(<span class="hljs-string">f"Initialized ChatOllama with model: <span class="hljs-subst">{llm_model_name}</span>, context window: <span class="hljs-subst">{context_window}</span>"</span>)

    <span class="hljs-comment"># Create the retriever</span>
    retriever = vector_store.as_retriever(
        search_type=<span class="hljs-string">"similarity"</span>, <span class="hljs-comment"># Or "mmr"</span>
        search_kwargs={<span class="hljs-string">'k'</span>: <span class="hljs-number">3</span>} <span class="hljs-comment"># Retrieve top 3 relevant chunks</span>
    )
    print(<span class="hljs-string">"Retriever initialized."</span>)

    <span class="hljs-comment"># Define the prompt template</span>
    template = <span class="hljs-string">"""Answer the question based ONLY on the following context:
{context}

Question: {question}
"""</span>
    prompt = ChatPromptTemplate.from_template(template)
    print(<span class="hljs-string">"Prompt template created."</span>)

    <span class="hljs-comment"># Define the RAG chain using LCEL</span>
    rag_chain = (
        {<span class="hljs-string">"context"</span>: retriever, <span class="hljs-string">"question"</span>: RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
    )
    print(<span class="hljs-string">"RAG chain created."</span>)
    <span class="hljs-keyword">return</span> rag_chain

<span class="hljs-comment">#... (previous function calls)</span>
vector_store = get_vector_store(embedding_function) <span class="hljs-comment"># Assuming DB is already indexed</span>
rag_chain = create_rag_chain(vector_store) <span class="hljs-comment"># Call this later</span>
</code></pre>
<p>The effectiveness of the RAG system hinges on the proper configuration of each component. The <code>chunk_size</code> and <code>chunk_overlap</code> in the splitter affect what the retriever finds. Your choice of <code>embedding_function</code> must be consistent between indexing and querying. The <code>num_ctx</code> parameter for the <code>ChatOllama</code> LLM must be large enough to hold the retrieved context and the prompt itself. A poorly designed prompt template can also lead the LLM astray. Make sure you carefully tune these elements for optimal performance.</p>
<h3 id="heading-step-8-query-your-documents">Step 8: Query Your Documents</h3>
<p>Finally, invoke the RAG chain with a question related to the content of the indexed PDF.</p>
<pre><code class="lang-python"><span class="hljs-comment"># rag_local.py (continued)</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">query_rag</span>(<span class="hljs-params">chain, question</span>):</span>
    <span class="hljs-string">"""Queries the RAG chain and prints the response."""</span>
    print(<span class="hljs-string">"\nQuerying RAG chain..."</span>)
    print(<span class="hljs-string">f"Question: <span class="hljs-subst">{question}</span>"</span>)
    response = chain.invoke(question)
    print(<span class="hljs-string">"\nResponse:"</span>)
    print(response)

<span class="hljs-comment"># --- Main Execution ---</span>
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    <span class="hljs-comment"># 1. Load Documents</span>
    docs = load_documents()

    <span class="hljs-comment"># 2. Split Documents</span>
    chunks = split_documents(docs)

    <span class="hljs-comment"># 3. Get Embedding Function</span>
    embedding_function = get_embedding_function() <span class="hljs-comment"># Using Ollama nomic-embed-text</span>

    <span class="hljs-comment"># 4. Index Documents (Only needs to be done once per document set)</span>
    <span class="hljs-comment"># Check if DB exists, if not, index. For simplicity, we might re-index here.</span>
    <span class="hljs-comment"># A more robust approach would check if indexing is needed.</span>
    print(<span class="hljs-string">"Attempting to index documents..."</span>)
    vector_store = index_documents(chunks, embedding_function)
    <span class="hljs-comment"># To load existing DB instead:</span>
    <span class="hljs-comment"># vector_store = get_vector_store(embedding_function)</span>

    <span class="hljs-comment"># 5. Create RAG Chain</span>
    rag_chain = create_rag_chain(vector_store, llm_model_name=<span class="hljs-string">"qwen3:8b"</span>) <span class="hljs-comment"># Use the chosen Qwen 3 model</span>

    <span class="hljs-comment"># 6. Query</span>
    query_question = <span class="hljs-string">"What is the main topic of the document?"</span> <span class="hljs-comment"># Replace with a specific question</span>
    query_rag(rag_chain, query_question)

    query_question_2 = <span class="hljs-string">"Summarize the introduction section."</span> <span class="hljs-comment"># Another example</span>
    query_rag(rag_chain, query_question_2)
</code></pre>
<p>Run the complete script (<code>python rag_local.py</code>). Make sure that the <code>ollama serve</code> command is running in another terminal. The script will load the PDF, split it, embed the chunks using <code>nomic-embed-text</code> via Ollama, store them in ChromaDB, build the RAG chain using <code>qwen3:8b</code> via Ollama, and finally execute the queries. It’ll print the LLM's responses based on the document content.</p>
<h2 id="heading-how-to-create-local-ai-agents-with-qwen-3">How to Create Local AI Agents with Qwen 3</h2>
<p>Beyond answering questions based on provided text, LLMs can act as the reasoning engine for AI agents. Agents can plan sequences of actions, interact with external tools (like functions or APIs), and work towards accomplishing more complex goals assigned by the user.</p>
<p>Qwen 3 models were specifically designed with strong tool-calling and agentic capabilities. While Alibaba provides the Qwen-Agent framework, this tutorial will continue using LangChain for consistency and because its integration with Ollama for agent tasks is more readily documented in the provided materials.</p>
<p>We will build a simple agent that can use a custom Python function as a tool.</p>
<h3 id="heading-step-1-define-custom-tools">Step 1: Define Custom Tools</h3>
<p>Tools are standard Python functions that the agent can choose to execute. The function's docstring is crucial, as the LLM uses it to understand what the tool does and what arguments it requires. LangChain's <code>@tool</code> decorator simplifies wrapping functions for agent use.</p>
<pre><code class="lang-python"><span class="hljs-comment"># agent_local.py</span>
<span class="hljs-keyword">import</span> os
<span class="hljs-keyword">from</span> dotenv <span class="hljs-keyword">import</span> load_dotenv
<span class="hljs-keyword">from</span> langchain.agents <span class="hljs-keyword">import</span> tool
<span class="hljs-keyword">import</span> datetime

load_dotenv() <span class="hljs-comment"># Optional</span>

<span class="hljs-meta">@tool</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_current_datetime</span>(<span class="hljs-params">format: str = <span class="hljs-string">"%Y-%m-%d %H:%M:%S"</span></span>) -&gt; str:</span>
    <span class="hljs-string">"""
    Returns the current date and time, formatted according to the provided Python strftime format string.
    Use this tool whenever the user asks for the current date, time, or both.
    Example format strings: '%Y-%m-%d' for date, '%H:%M:%S' for time.
    If no format is specified, defaults to '%Y-%m-%d %H:%M:%S'.
    """</span>
    <span class="hljs-keyword">try</span>:
        <span class="hljs-keyword">return</span> datetime.datetime.now().strftime(format)
    <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
        <span class="hljs-keyword">return</span> <span class="hljs-string">f"Error formatting date/time: <span class="hljs-subst">{e}</span>"</span>

<span class="hljs-comment"># List of tools the agent can use</span>
tools = [get_current_datetime]
print(<span class="hljs-string">"Custom tool defined."</span>)
</code></pre>
<h3 id="heading-step-2-set-up-the-agent-llm">Step 2: Set Up the Agent LLM</h3>
<p>Instantiate the <code>ChatOllama</code> model again, using a Qwen 3 variant suitable for tool calling. The <code>qwen3:8b</code> model should be capable of handling simple tool use cases.</p>
<p>It's important to note that tool calling reliability with local models served via Ollama can sometimes be less consistent than with large commercial APIs like GPT-4 or Claude. The LLM might fail to recognize when a tool is needed, hallucinate arguments, or misinterpret the tool's output. Starting with clear prompts and simple tools is recommended.</p>
<pre><code class="lang-python"><span class="hljs-comment"># agent_local.py (continued)</span>
<span class="hljs-keyword">from</span> langchain_ollama <span class="hljs-keyword">import</span> ChatOllama

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_agent_llm</span>(<span class="hljs-params">model_name=<span class="hljs-string">"qwen3:8b"</span>, temperature=<span class="hljs-number">0</span></span>):</span>
    <span class="hljs-string">"""Initializes the ChatOllama model for the agent."""</span>
    <span class="hljs-comment"># Ensure Ollama server is running (ollama serve)</span>
    llm = ChatOllama(
        model=model_name,
        temperature=temperature <span class="hljs-comment"># Lower temperature for more predictable tool use</span>
        <span class="hljs-comment"># Consider increasing num_ctx if expecting long conversations or complex reasoning</span>
        <span class="hljs-comment"># num_ctx=8192</span>
    )
    print(<span class="hljs-string">f"Initialized ChatOllama agent LLM with model: <span class="hljs-subst">{model_name}</span>"</span>)
    <span class="hljs-keyword">return</span> llm

<span class="hljs-comment"># agent_llm = get_agent_llm() # Call this later</span>
</code></pre>
<h3 id="heading-step-3-create-the-agent-prompt">Step 3: Create the Agent Prompt</h3>
<p>Agents require specific prompt structures that guide their reasoning and tool use. The prompt typically includes placeholders for user input (<code>input</code>), conversation history (<code>chat_history</code>), and the <code>agent_scratchpad</code>. The scratchpad is where the agent records its internal "thought" process, the tools it decides to call, and the results (observations) it gets back from those tools. LangChain Hub provides pre-built prompts suitable for tool-calling agents.</p>
<pre><code class="lang-python"><span class="hljs-comment"># agent_local.py (continued)</span>
<span class="hljs-keyword">from</span> langchain <span class="hljs-keyword">import</span> hub

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_agent_prompt</span>(<span class="hljs-params">prompt_hub_name=<span class="hljs-string">"hwchase17/openai-tools-agent"</span></span>):</span>
    <span class="hljs-string">"""Pulls the agent prompt template from LangChain Hub."""</span>
    <span class="hljs-comment"># This prompt is designed for OpenAI but often works well with other tool-calling models.</span>
    <span class="hljs-comment"># Alternatively, define a custom ChatPromptTemplate.</span>
    prompt = hub.pull(prompt_hub_name)
    print(<span class="hljs-string">f"Pulled agent prompt from Hub: <span class="hljs-subst">{prompt_hub_name}</span>"</span>)
    <span class="hljs-comment"># print("Prompt Structure:")</span>
    <span class="hljs-comment"># prompt.pretty_print() # Uncomment to see the prompt structure</span>
    <span class="hljs-keyword">return</span> prompt

<span class="hljs-comment"># agent_prompt = get_agent_prompt() # Call this later</span>
</code></pre>
<h3 id="heading-step-4-build-the-agent">Step 4: Build the Agent</h3>
<p>The <code>create_tool_calling_agent</code> function combines the LLM, the defined tools, and the prompt into a runnable unit that represents the agent's core logic.</p>
<pre><code class="lang-python"><span class="hljs-comment"># agent_local.py (continued)</span>
<span class="hljs-keyword">from</span> langchain.agents <span class="hljs-keyword">import</span> create_tool_calling_agent

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">build_agent</span>(<span class="hljs-params">llm, tools, prompt</span>):</span>
    <span class="hljs-string">"""Builds the tool-calling agent runnable."""</span>
    agent = create_tool_calling_agent(llm, tools, prompt)
    print(<span class="hljs-string">"Agent runnable created."</span>)
    <span class="hljs-keyword">return</span> agent

<span class="hljs-comment"># agent_runnable = build_agent(agent_llm, tools, agent_prompt) # Call this later</span>
</code></pre>
<h3 id="heading-step-5-create-the-agent-executor">Step 5: Create the Agent Executor</h3>
<p>The <code>AgentExecutor</code> is responsible for running the agent loop. It takes the agent runnable and the tools, invokes the agent with the input, parses the agent's output (which could be a final answer or a tool call request), executes any requested tool calls, and feeds the results back to the agent until a final answer is reached. Setting <code>verbose=True</code> is highly recommended during development to observe the agent's step-by-step execution flow.</p>
<pre><code class="lang-python"><span class="hljs-comment"># agent_local.py (continued)</span>
<span class="hljs-keyword">from</span> langchain.agents <span class="hljs-keyword">import</span> AgentExecutor

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">create_agent_executor</span>(<span class="hljs-params">agent, tools</span>):</span>
    <span class="hljs-string">"""Creates the agent executor."""</span>
    agent_executor = AgentExecutor(
        agent=agent,
        tools=tools,
        verbose=<span class="hljs-literal">True</span> <span class="hljs-comment"># Set to True to see agent thoughts and tool calls</span>
    )
    print(<span class="hljs-string">"Agent executor created."</span>)
    <span class="hljs-keyword">return</span> agent_executor

<span class="hljs-comment"># agent_executor = create_agent_executor(agent_runnable, tools) # Call this later</span>
</code></pre>
<h3 id="heading-step-6-run-the-agent">Step 6: Run the Agent</h3>
<p>Invoke the agent executor with a user query that should trigger the use of the defined tool.</p>
<pre><code class="lang-python"><span class="hljs-comment"># agent_local.py (continued)</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">run_agent</span>(<span class="hljs-params">executor, user_input</span>):</span>
    <span class="hljs-string">"""Runs the agent executor with the given input."""</span>
    print(<span class="hljs-string">"\nInvoking agent..."</span>)
    print(<span class="hljs-string">f"Input: <span class="hljs-subst">{user_input}</span>"</span>)
    response = executor.invoke({<span class="hljs-string">"input"</span>: user_input})
    print(<span class="hljs-string">"\nAgent Response:"</span>)
    print(response[<span class="hljs-string">'output'</span>])

<span class="hljs-comment"># --- Main Execution ---</span>
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    <span class="hljs-comment"># 1. Define Tools (already done above)</span>

    <span class="hljs-comment"># 2. Get Agent LLM</span>
    agent_llm = get_agent_llm(model_name=<span class="hljs-string">"qwen3:8b"</span>) <span class="hljs-comment"># Use the chosen Qwen 3 model</span>

    <span class="hljs-comment"># 3. Get Agent Prompt</span>
    agent_prompt = get_agent_prompt()

    <span class="hljs-comment"># 4. Build Agent Runnable</span>
    agent_runnable = build_agent(agent_llm, tools, agent_prompt)

    <span class="hljs-comment"># 5. Create Agent Executor</span>
    agent_executor = create_agent_executor(agent_runnable, tools)

    <span class="hljs-comment"># 6. Run Agent</span>
    run_agent(agent_executor, <span class="hljs-string">"What is the current date?"</span>)
    run_agent(agent_executor, <span class="hljs-string">"What time is it right now? Use HH:MM format."</span>)
    run_agent(agent_executor, <span class="hljs-string">"Tell me a joke."</span>) <span class="hljs-comment"># Should not use the tool</span>
</code></pre>
<p>Running <code>python agent_local.py</code> (with <code>ollama serve</code> active) will execute the agent. The <code>verbose=True</code> setting will print output resembling the ReAct (Reasoning and Acting) framework, showing the agent's internal "Thoughts" on how to proceed, the "Action" it decides to take (calling a specific tool with arguments), and the "Observation" (the result returned by the tool).</p>
<p>Building reliable agents with local models presents unique challenges. The LLM's ability to correctly interpret the prompt, understand when to use tools, select the right tool, generate valid arguments, and process the tool's output is critical.</p>
<p>Local models, especially smaller or heavily quantized ones, might struggle with these reasoning steps compared to larger, cloud-based counterparts. If the <code>qwen3:8b</code> model proves unreliable for more complex agentic tasks, consider trying <code>qwen3:14b</code> or the efficient <code>qwen3:30b-a3b</code> if hardware permits.</p>
<p>For highly complex or stateful agent workflows, exploring frameworks like LangGraph, which offers more control over the agent's execution flow, might be beneficial.</p>
<h2 id="heading-advanced-considerations-and-troubleshooting">Advanced Considerations and Troubleshooting</h2>
<p>Running LLMs locally offers great flexibility but also introduces specific configuration aspects and potential issues.</p>
<h3 id="heading-controlling-qwen-3s-thinking-mode-with-ollama">Controlling Qwen 3's Thinking Mode with Ollama</h3>
<p>Qwen 3's unique hybrid inference allows switching between a deep "thinking" mode for complex reasoning and a faster "non-thinking" mode for general chat. While frameworks like Hugging Face Transformers or vLLM might offer explicit parameters (<code>enable_thinking</code>), the primary way to control this when using Ollama appears to be through "soft switches" embedded in the prompt.</p>
<p>Append <code>/think</code> to the end of a user prompt to encourage step-by-step reasoning, or <code>/no_think</code> to request a faster, direct response. You can do this via the Ollama CLI or potentially within the prompts sent via the API/LangChain.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Example using LangChain's ChatOllama</span>
<span class="hljs-keyword">from</span> langchain_ollama <span class="hljs-keyword">import</span> ChatOllama

llm_think = ChatOllama(model=<span class="hljs-string">"qwen3:8b"</span>)
llm_no_think = ChatOllama(model=<span class="hljs-string">"qwen3:8b"</span>) <span class="hljs-comment"># Could also set system prompt</span>

<span class="hljs-comment"># Invoke with prompt modification</span>
response_think = llm_think.invoke(<span class="hljs-string">"Solve the equation 2x + 5 = 15 /think"</span>)
print(<span class="hljs-string">"Thinking Response:"</span>, response_think)

response_no_think = llm_no_think.invoke(<span class="hljs-string">"What is the capital of France? /no_think"</span>)
print(<span class="hljs-string">"Non-Thinking Response:"</span>, response_no_think)

<span class="hljs-comment"># Alternatively, set via system message (might be less reliable turn-by-turn)</span>
llm_system_no_think = ChatOllama(model=<span class="hljs-string">"qwen3:8b"</span>, system=<span class="hljs-string">"/no_think"</span>)
response_system = llm_system_no_think.invoke(<span class="hljs-string">"What is 2+2?"</span>)
print(<span class="hljs-string">"System No-Think Response:"</span>, response_system)
</code></pre>
<p>Note that the persistence of these tags across multiple turns in a conversation might require careful prompt management.</p>
<h3 id="heading-managing-context-length-numctx">Managing Context Length (<code>num_ctx</code>)</h3>
<p>The context window (<code>num_ctx</code>) determines how much information (prompt, history, retrieved documents) the LLM can consider at once. Qwen 3 models (8B+) support large native context lengths (for example, 128k tokens), but Ollama often defaults to a much smaller window (like 2048 or 4096). For RAG or conversations requiring memory of earlier turns, this default is often insufficient.</p>
<p>Set <code>num_ctx</code> when initializing <code>ChatOllama</code> or <code>OllamaLLM</code> in LangChain:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Example setting context window to 8192 tokens</span>
llm = ChatOllama(model=<span class="hljs-string">"qwen3:8b"</span>, num_ctx=<span class="hljs-number">8192</span>)
</code></pre>
<p>Be mindful that larger <code>num_ctx</code> values significantly increase RAM and VRAM consumption. But setting it too low can lead to the model "forgetting" context or even entering repetitive loops. Choose a value that balances the task requirements with hardware capabilities.</p>
<h3 id="heading-hardware-limitations-and-vram">Hardware Limitations and VRAM</h3>
<p>Running LLMs locally is resource-intensive.</p>
<ul>
<li><p><strong>VRAM:</strong> A dedicated GPU (NVIDIA or Apple Silicon) with sufficient VRAM is highly recommended for acceptable performance. The amount of VRAM dictates the largest model size that can run efficiently. Refer to the table in Section 2 for estimates.</p>
</li>
<li><p><strong>RAM:</strong> System RAM is also crucial, especially if the model doesn't fit entirely in VRAM. Ollama can utilize system RAM as a fallback, but this is significantly slower.</p>
</li>
<li><p><strong>Quantization:</strong> Ollama typically serves quantized models (for example., 4-bit or 5-bit), which reduce the model size and VRAM requirements significantly compared to full-precision models, often with minimal performance degradation for many tasks. The tags like <code>:4b</code>, <code>:8b</code> usually imply a default quantization level.</p>
</li>
</ul>
<p>If performance is slow or errors occur due to resource constraints, consider:</p>
<ul>
<li><p>Using a smaller Qwen 3 model (like 4B instead of 8B).</p>
</li>
<li><p>Ensuring Ollama is correctly detecting and utilizing the GPU (check Ollama logs or system monitoring tools).</p>
</li>
<li><p>Closing other resource-intensive applications.</p>
</li>
</ul>
<h2 id="heading-conclusion-and-next-steps">Conclusion and Next Steps</h2>
<p>This tutorial gave you a practical walkthrough for setting up your local AI environment using the powerful and open Qwen 3 LLM family with the user-friendly Ollama tool.</p>
<p>If you’ve followed these steps, you should have successfully:</p>
<ol>
<li><p>Installed Ollama and downloaded/run Qwen 3 models locally.</p>
</li>
<li><p>Built a functional Retrieval-Augmented Generation (RAG) pipeline using LangChain and ChromaDB to query local documents.</p>
</li>
<li><p>Created a basic AI agent capable of reasoning and utilizing custom Python tools.</p>
</li>
</ol>
<p>Running these systems locally unlocks significant advantages in privacy, cost, and customization, making advanced AI capabilities more accessible than ever. The combination of Qwen 3's performance and open license with Ollama's ease of use creates a potent platform for experimentation and development.</p>
<p><strong>Official Resources:</strong></p>
<ul>
<li><p><strong>Qwen 3:</strong> <a target="_blank" href="https://github.com/QwenLM/Qwen3">GitHub</a>, <a target="_blank" href="https://qwen.readthedocs.io/en/latest/">Documentation</a></p>
</li>
<li><p><strong>Ollama:</strong> <a target="_blank" href="https://ollama.com/">Website</a>, <a target="_blank" href="https://ollama.com/library">Model Library</a>, <a target="_blank" href="https://github.com/ollama/ollama">GitHub</a></p>
</li>
<li><p><strong>LangChain:</strong> <a target="_blank" href="https://python.langchain.com/docs/get_started/introduction">Python Documentation</a></p>
</li>
<li><p><strong>ChromaDB:</strong> <a target="_blank" href="https://docs.trychroma.com/">Documentation</a></p>
</li>
<li><p><strong>Sentence Transformers:</strong> <a target="_blank" href="https://www.sbert.net/">Documentation</a></p>
</li>
</ul>
<p>By leveraging these powerful, free, and open-source tools, you can continue to push the boundaries of what's possible with AI running directly on your own hardware.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ From Failure to International Success: How Online Learning Platforms Saved My Life ]]>
                </title>
                <description>
                    <![CDATA[ It is better to be a samurai in a garden than an agricultural worker in a war - Miyamoto Musashi In this article, I’ll share my story. When I was younger, I thought I was destined to be a failure in life. To be isolated from everyone. But years late... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-online-learning-platforms-saved-my-life/</link>
                <guid isPermaLink="false">67ed3edd597c0ff6bdcf4c45</guid>
                
                    <category>
                        <![CDATA[ Learning Journey ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Online education ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Personal growth   ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tiago Capelo Monteiro ]]>
                </dc:creator>
                <pubDate>Wed, 02 Apr 2025 13:42:53 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1743601355025/2f8c32a4-c451-4860-b4e2-f02b690fb928.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <blockquote>
<p>It is better to be a samurai in a garden than an agricultural worker in a war - Miyamoto Musashi</p>
</blockquote>
<p>In this article, I’ll share my story.</p>
<p>When I was younger, I thought I was destined to be a failure in life. To be isolated from everyone. But years later, I realized I was actually destined for success.</p>
<p>I went from wasting thousands of hours playing video games to giving a lecture to medical professionals called “Trustworthy AI: The Role of Small Models in Critical Systems.”</p>
<p>And I went from being told I was dumber than most people based on an IQ test I took as a 14 year old low self-esteem kid, to becoming a frequent contributor to freeCodeCamp. I’ve written articles on interpretable AI, applied math, and advanced tech. And these articles have now reached more than 200,000 people worldwide.</p>
<p><strong>And this is just the beginning.</strong></p>
<p>When it comes to education, I owe gratitude to three people and the organizations they lead:</p>
<ul>
<li><p>Salman Khan, founder of Khan Academy</p>
</li>
<li><p>Quincy Larson, founder of freeCodeCamp</p>
</li>
<li><p>Andrew Ng, co-founder of Coursera and founder of DeepLearning.AI</p>
</li>
</ul>
<p>I also owe a lot to the great author of the book Atomic Habits: An Easy &amp; Proven Way to Build Good Habits &amp; Break Bad Ones – James Clear.</p>
<p>I’m sharing my story to inspire others who are struggling in their lives just like I was.</p>
<p>I’m also writing this for those who know me or will know me personally, so that they can understand where my determination comes from and why I am relentless.</p>
<h3 id="heading-heres-what-ill-cover">Here’s what I’ll cover:</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-where-i-was-misery-depression-and-isolation">Where I Was: Misery, Depression, and Isolation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-my-transformation-learning-triple-integrals-and-programming">My Transformation: Learning Triple Integrals and Programming</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-one-of-the-best-choices-in-my-life-why-i-chose-electrical-and-computer-engineering">One of the Best Choices in My Life: Why I Chose Electrical and Computer Engineering</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-being-restless-and-determined-my-work-ethic-in-university">Being Restless and Determined: My Work Ethic in University</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-my-projects-while-in-nova-fct-ai-projects-international-student-organizations-and-freecodecamp-articles">My Projects while in NOVA FCT: AI Projects, International Student Organizations, and freeCodeCamp Articles</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-my-personal-philosophy-at-21-years-old-and-view-on-envy-and-negativity">My Personal Philosophy at 21 Years Old and View on Envy and Negativity</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-where-i-am-today-a-fraction-of-what-i-have-achieved">Where I Am Today: A Fraction of What I Have Achieved</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-final-thoughts-have-an-adaptive-grand-strategy-for-your-life">Final Thoughts: Have an Adaptive Grand Strategy for Your Life</a></p>
</li>
</ol>
<h2 id="heading-where-i-was-misery-depression-and-isolation">Where I Was: Misery, Depression, and Isolation</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743425427463/49388c13-8c05-41ae-878b-316de0e3ed56.jpeg" alt="Photo by <a href=&quot;https://unsplash.com/@nmbalanial?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash&quot;>Nikko Balanial</a> on <a href=&quot;https://unsplash.com/photos/water-droplets-on-glass-window-4XSdSFgKm8k?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash&quot;>Unsplash</a>       " class="image--center mx-auto" width="2703" height="1850" loading="lazy"></p>
<p>Photo by <a target="_blank" href="https://unsplash.com/@nmbalanial?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">Nikko Balanial</a> <a target="_blank" href="https://unsplash.com/@nmbalanial?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">on Unsplash</a></p>
<blockquote>
<p>"As it turns out, it was that very rock bottom that became the firmest foundation I had ever planted my feet on." — Mandy Hale</p>
</blockquote>
<p>Five years ago, I was in a different place and was a completely different person.</p>
<p>Like many teenagers, I started playing video games and became addicted to them. Over time, games became an escape from reality and all my problems, including my bad grades and many other issues.</p>
<p>At age 14, I still held ambitions in my heart. I dreamed of being someone who would help others, maybe as a doctor or an engineer.</p>
<p>But after an IQ and vocational guidance test, I was told that I was incapable of doing these things. That I lacked the intelligence needed. That it was unrealistic for me to pursue these types of degrees.</p>
<p>Eventually, and because of many comments, opinions, and expectations of others, I began to believe in this lie for years.</p>
<p>Over time, depressed and constantly escaping reality, my grades plummeted and I got worse and worse. And this only made the prospect of going to college less and less likely.</p>
<p>By 11th grade, I was:</p>
<ul>
<li><p>Extremely shy and anxious</p>
</li>
<li><p>Struggling academically</p>
</li>
<li><p>Over 2000 hours in video games on two games alone:</p>
<ul>
<li><p>1000 hours in GTA V</p>
</li>
<li><p>1000 hours in Destiny 2</p>
</li>
</ul>
</li>
</ul>
<p>2000 hours equals nearly 83 days.</p>
<p>This means that in these two games, I lost more than two months of my life.</p>
<p>But from these wasted hours, I learned English. This became crucial when learning online.</p>
<p>In January 2020, I was tired of everything. In particular, I was sick of the misery of always being at the bottom and of so much negativity towards and around me.</p>
<p>So I made these vows to myself for the rest of my life:</p>
<ul>
<li><p>Never again would I worry or care about what other people say about me.</p>
</li>
<li><p>I would no longer accept the limitations imposed by others or myself on my growth.</p>
</li>
<li><p>And as for the limitations I imposed on myself, I would rethink to see if they were really impossible or if I could actually conquer them.</p>
</li>
</ul>
<p>As a result, I started relearning and learning everything by myself to make sure I succeeded in the national exams.</p>
<h2 id="heading-my-transformation-learning-triple-integrals-and-programming">My Transformation: Learning Triple Integrals and Programming</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743425550115/3f61c996-1a20-415f-bc89-65eaf3119799.jpeg" alt="3f61c996-1a20-415f-bc89-65eaf3119799" class="image--center mx-auto" width="3000" height="2000" loading="lazy"></p>
<p>Photo by <a target="_blank" href="https://unsplash.com/@joshuaearle?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">Joshua Earle</a> <a target="_blank" href="https://unsplash.com/@joshuaearle?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">on Unsplash</a></p>
<blockquote>
<p><em>"The expert in anything was once a beginner."</em><br>— Helen Hayes</p>
</blockquote>
<p>I started going through chemistry exercises in the 10th and 11th grades using books from school and YouTube videos. In two weeks, I relearned or learned most of the material I needed to know.</p>
<p>I started doing the same for mathematics, something I always found hard due to a lack of basic foundational mathematics knowledge.</p>
<p>I found it hard, that was, until I discovered Khan Academy.</p>
<p>With the Khan Academy, I rebuilt myself, going from struggling with basic math to mastering double and triple integrals, all within five to six months.</p>
<p>My method was simple:</p>
<ul>
<li><p>Study a little bit every day.</p>
</li>
<li><p>Take detailed notes</p>
</li>
<li><p>Redo quizzes or units tests until I scored more than 90%</p>
<ul>
<li>For topics that I found harder or failed to understand, I did the practice exercizes</li>
</ul>
</li>
<li><p>Use YouTube to close any knowledge gaps</p>
</li>
</ul>
<p>For example, for <a target="_blank" href="https://www.khanacademy.org/math/algebra">Algebra I</a>, where I started to relearn math, I say how many units there were. Each unit had a certain number of topics. As of 2025, Algebra I has, from units with mastery exercises, 89 topics.</p>
<p>For those 89 topics, I watched the videos and did the quizzes. According to my scores, I would either go on to the next video (if I felt confident), or stop, rewatch the video, go through the same material on YouTube, do practice exercises, and then try to do the quiz again.</p>
<p>I decided that I needed to do at least three topics every day. This way, by doing 3 topics per day, I could finish Algebra I by the end of one month.</p>
<p>But I was so motivated and so focused on it that I did more than 3 topics per day.</p>
<p>I did the same for Algebra II, and all the others until <a target="_blank" href="https://www.khanacademy.org/math/ap-calculus-bc">College Calculus BC</a>.</p>
<p>Some days, I completed more than 8 topics. Other days, I struggle to even do 2. But I made sure that I mastered mathematics and its foundation for the rest of my life.</p>
<p>This was not just about grades. It was about regaining belief and confidence in myself.</p>
<p>I also read many books, primarily self-help, to make myself better. Over the years, I have started reading fewer self-help books and have started focusing on non-fictional books that explain to me how the world works.</p>
<h3 id="heading-covid-19-accelerating-my-learning-in-programming-and-machine-learning"><strong>COVID-19: Accelerating My Learning in Programming and Machine Learning</strong></h3>
<p>When the pandemic hit, I started accelerating my learning in other areas, like programming and physics. In many online classes, I didn’t pay attention as well as I should’ve – and I found myself prioritizing self study on topics I found more important. And I always used my time to learn more about programming.</p>
<p>I learned Python and C through free YouTube courses for beginners on freeCodeCamp’s channel.</p>
<p>This was where I first learned Python.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/rfscVS0vtbw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>And C:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/KJgsSFOSQv0" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>Soon after exploring C programming, I realized that programming languages are just tools. Once you master one, others come more naturally.</p>
<p>I studied data science tutorials on the web and on YouTube. This way, I learned how to import Python libraries in virtual environments. I also began building projects with Python libraries I found interesting and made it a habit to explain every line of code to myself as if I were the teacher.</p>
<p>For example, I started working with the <a target="_blank" href="https://scikit-learn.org/stable/index.html">scikit learn</a> Python library to make simple linear and logistic models that could make make predictions.</p>
<p>I also decided to explore Deep Learning and taught myself how to work with <a target="_blank" href="https://www.arduino.cc/">Arduino</a> and circuits. In other words, I learned how to train the architecture of neural networks to predict things.</p>
<p>I found this hard to master compared to triple integrals at the time!</p>
<p>But this way, I understood one very important thing about Deep Learning: to truly understand and master it, I needed to know, deeply, some difficult mathematics concepts. And I also needed to learn quickly about the new research coming out.</p>
<h2 id="heading-one-of-the-best-choices-in-my-life-why-i-choose-electrical-and-computer-engineering">One of the Best Choices in My Life: Why I Choose Electrical and Computer Engineering</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743426438035/92ee17a4-c537-4922-82cc-cbb42c564baa.jpeg" alt="92ee17a4-c537-4922-82cc-cbb42c564baa" class="image--center mx-auto" width="3888" height="2592" loading="lazy"></p>
<p>Photo by <a target="_blank" href="https://unsplash.com/@nicolasthomas?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">Nicolas Thomas</a> <a target="_blank" href="https://unsplash.com/@nicolasthomas?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">on Unsplash</a></p>
<blockquote>
<p><em>"Opportunities multiply as they are seized."</em><br>— Sun Tzu</p>
</blockquote>
<p>After completing the Portuguese national mathematics exam in the 12th grade, I chose Electrical and Computer Engineering (ECE). I choose this area, because it would challenge me and allow me to gain the skills to learn and apply new mathematics by myself without anyone teaching me.</p>
<p>It was also broad:</p>
<ul>
<li><p>If I liked, I could follow an electrical engineering area. Like circuits, power systems, or telecommunications.</p>
</li>
<li><p>If an electrical engineering subarea was not in my best interest, I could follow a computer science path or apply math in banking or other areas where people who know applied math work.</p>
</li>
</ul>
<p>The ECE degree also allwed me to unite the following areas:</p>
<ul>
<li><p>Advanced Mathematics</p>
</li>
<li><p>Programming (from low-level like assembly and C to high-level like Python)</p>
</li>
<li><p>Physics (circuits, robotics, communication systems)</p>
</li>
</ul>
<p>I wanted to become someone who not only mastered knowledge but could also create new systems and ideas from it.</p>
<p>I knew that I was laying the foundation for something greater than just academic success.</p>
<h3 id="heading-what-did-i-gain-exactly"><strong>What Did I Gain Exactly?</strong></h3>
<p>Over time, I learned the many skills I needed to understand all the new AI research coming out after completing AI specializations.</p>
<p>I also learned hard math and applied mathematics areas such as:</p>
<ul>
<li><p>Partial differential equations: how they can represent and model real phenomena, like the economy of a country.</p>
</li>
<li><p>Pure harmonic analysis: Fourier and Laplace transformations and how integral transformations allow us to see problems in other ways.</p>
</li>
<li><p>Complex analysis: application of derivatives and integrals in a complex domain, with real and imaginary numbers.</p>
</li>
<li><p>Numerical analysis: how math used to approximate analytical math is used by computers to get faster results.</p>
</li>
<li><p>Signal and control theory: how the architecture of systems is studied to ensure rocket, train, and car control systems are stable, despite possible disturbances in the systems.</p>
</li>
</ul>
<p>Not to mention physics classes like:</p>
<ul>
<li><p>Classical mechanics</p>
</li>
<li><p>Electromagnetism</p>
</li>
</ul>
<p>While these topics may not be applied in depth to AI, learning them helped me develop an incredible intuition into systems thinking. It also greatly improved my ability to learn hard STEM concepts on my own.</p>
<h2 id="heading-being-restless-and-determined-my-work-ethic-in-university">Being Restless and Determined: My Work Ethic in University</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743421252923/58fa0581-1312-4577-b186-b61a0d7ecac1.png" alt="Me at 18 years old" class="image--center mx-auto" width="460" height="460" loading="lazy"></p>
<p>Me at 18 years old</p>
<blockquote>
<p>"Success is the sum of small efforts, repeated day in and day out." — Robert Collier</p>
</blockquote>
<p>I adopted a very rigorous work ethic.</p>
<p>When my work ethic failed to achieve what I wanted, I adapted with more knowledge and learned very deeply what I did wrong so as not to repeat it.</p>
<p>For example, in the first semester, my first grades were not the best. So, I read:</p>
<ul>
<li><p>Deep Work</p>
</li>
<li><p>The Effective Executive: The Definitive Guide to Getting the Right Things Done</p>
</li>
<li><p>How to Become a Straight-A Student: The Unconventional Strategies Real College Students Use</p>
</li>
</ul>
<p>These books taught me how to focus and prioritize what needed to be done. This became essential as I entered one of the most demanding phases of my life.</p>
<p>In addition, I used Notion as a management system and Google Calendar as a schedule system.</p>
<p>Every week, I transferred next week's tasks from Google Calendar to Notion. This way, I never forgot anything and never worried about forgetting anything.</p>
<p>I had two simple scalable systems that worked very well for managing everything I did.</p>
<p>In the scheduling system, I would place certain events on repeat, for example:</p>
<ol>
<li><p>Every week:</p>
<ul>
<li>Read the top articles of the week on Subreddits dedicated to programming and others topics so I could keep learning and growing. Same with communities on Stack Exchange Network.</li>
</ul>
</li>
</ol>
<ul>
<li>Read new articles on IEEE Spectrum and learn as much as possible about what is happening currently.</li>
</ul>
<ol start="2">
<li><p>Every two weeks:</p>
<ul>
<li>Plan my studying according to time available, as well as all class and other resources I could get for tests, projects, and exams.</li>
</ul>
</li>
<li><p>Every month:</p>
<ul>
<li>Review my annual objectives and prioritize what was important and urgent to do in that month. Also, review new opportunities that appeared that aligned with my objectives this year and in my life.</li>
</ul>
</li>
</ol>
<p>This way, I was always aligned and efficient. And all this was from a Notion database.</p>
<p>Very often, I started working at 8:00am and continued until around 9:00 or 10:30am, when my classes often started. At that time, I studied, did student organization work, completed online courses and specializations, worked on AI projects, wrote freeCodeCamp articles, and many tasks.</p>
<p>I went beyond studying just the subjects from my degree:</p>
<ul>
<li><p>I also studied history, economics, and geopolitics to understand the hidden incentives that shape the world.</p>
</li>
<li><p>I developed the habit of studying the architecture of things, from political systems to technology, understanding how they work to design better systems.</p>
</li>
<li><p>I attended many free online and university events to learn as much as possible.</p>
</li>
</ul>
<p>I also treated weekends as opportunities to grow and work, and did not stop. This was not possible 100% of the time, but most days I was able to do so.</p>
<p>In this way, I completed Coursera’s prestigious Deep Learning Specialization, a very important achievement in my journey.</p>
<p>I also read many books and listened to podcasts while taking public transportation, ensuring that no time was wasted.</p>
<h2 id="heading-my-projects-while-in-nova-fct-ai-projects-international-student-organizations-and-freecodecamp-articles">My Projects While in NOVA FCT: AI Projects, International Student Organizations, and freeCodeCamp Articles</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743422159743/81944517-ee5d-4cd3-a84a-fd9726391175.jpeg" alt="81944517-ee5d-4cd3-a84a-fd9726391175" class="image--center mx-auto" width="2016" height="1512" loading="lazy"></p>
<p>Me at 21 years old.</p>
<blockquote>
<p><em>"The strength of the team is each individual member. The strength of each member is the team."</em><br>— Phil Jackson</p>
</blockquote>
<p>International student organizations often offer opportunities that are rarely found in local college clubs.</p>
<p>These student organizations are also often better managed than some local clubs, which can sometimes suffer from internal politics focused on titles rather than making a real contribution to society.</p>
<p>For this reason, I sought international organizations that pushed members towards real impact and development.</p>
<p>After a while, I became interested in BEST (Board of Engineering Students of Technology), a large international organization of student organizations spread over 80 groups around European universities. I joined the local group, BEST Almada, one of the 80 local BEST groups across Europe that helps foster the development of students through courses and events.</p>
<p>I also became deeply involved in the IEEE, the world’s largest non-profit professional association, where I served as the Vice-Chair of the IEEE NOVA Student Branch. Currently, I contribute nationally in the IEEE Portugal Section by creating videos for social media.</p>
<p>Thanks to IEEE, I was able to go to the IEEE Melecon conference in Porto last year to speak with some amazing scientists and researchers.</p>
<p>Here’s a key thing I learned from IEEE that I want to share: Communication, alignment of expectations between everybody, and knowing how to navigate social dynamics is crucial for any project or initiative to succeed. Of course, the culture of the organization and a lot of other variables are important as well. But I believe communication is one of the most important and critical factors.</p>
<p>Along this path, I worked on projects like Eurostatify AI, which aimed to provide European public data insights and hidden patterns that are accessible to researchers and policymakers. I also led the Doctor AI Project as part of a Hackathon in March 2023, where I developed two AI bots using Flutter and the ChatGPT API to help doctors make better decisions.</p>
<p>Each step helped me forge myself into someone capable of inspiring and leading others. I also taught complex topics in my freeCodeCamp articles, such as how CPUs work in depth, interpretable AI, quantum AI, and even how to design a control system for rockets.</p>
<p>I was involved in local student clubs before I realized the value of joining international organizations. In Europe, these organizations bring unique opportunities, are usually better managed than local groups. They’re a great place for developing soft skills as well.</p>
<p>So in the end, joining international student organizations was one of the best decisions of my university life.</p>
<h2 id="heading-my-personal-philosophy-at-21-years-old-and-view-on-envy-and-negativity">My Personal Philosophy at 21 Years Old and View on Envy and Negativity</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743425739851/135f7a2a-edab-48a4-91ee-e8aa3ed8c416.jpeg" alt="135f7a2a-edab-48a4-91ee-e8aa3ed8c416" class="image--center mx-auto" width="5953" height="3969" loading="lazy"></p>
<p>Photo by <a target="_blank" href="https://unsplash.com/@giamboscaro?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">Giammarco Boscaro</a> <a target="_blank" href="https://unsplash.com/@giamboscaro?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">on Unsplash</a></p>
<blockquote>
<p><em>"Freedom lies in being bold."</em><br>— Robert Frost</p>
</blockquote>
<p>Here’s one thing I’ve learned over the years: You need to make your own path. Chasing social status and falling prey to social pressures isn’t worth it, and you shouldn’t be blinded by these things. True freedom comes from defining your own path. Developing relationships with professors and mentors, learning from books, and taking advantage of solid free learning resource are all things that can help you go further in life.</p>
<p>But what about envy and negativity from others?</p>
<p>Well, unfortunately these will always be part of our lives. Being envious is human nature, and various forms of negativity will likely continue to exist. Anyone who works and achieves any level of success will inevitably attract envy and negativity.</p>
<p>The best response is not to react and to ignore it completely. Just keep growing.</p>
<p>Some people will disappear, mock you, envy you, or hate you – but just try to let it all go. Keep walking your path.</p>
<p>Time is precious. Don’t waste it on:</p>
<ul>
<li><p>Meaningless opinions</p>
</li>
<li><p>Video games</p>
</li>
<li><p>Distractions</p>
</li>
</ul>
<p>I find it sad that, despite living in such an exciting time, and despite unprecedented access to knowledge and education, advances in technology, and immense global connectivity, some people still choose to hate and be envious of others. But as I said before, it’s human nature and there is little we can do about it.</p>
<p>Just remember: you have opportunities today that previous generations could only dream of. Take advantage of them to the fullest and worry about your own personal growth.</p>
<h2 id="heading-where-i-am-today-a-fraction-of-what-i-have-achieved">Where I am Today: A Fraction of What I Have Achieved</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743428837578/9f5359be-4cca-4840-b74c-ca78b44b8672.jpeg" alt="9f5359be-4cca-4840-b74c-ca78b44b8672" class="image--center mx-auto" width="1537" height="1533" loading="lazy"></p>
<p>Me in a Tesla factory in Silicon Valley</p>
<blockquote>
<p><em>"I am not a product of my circumstances. I am a product of my decisions."</em><br>— Stephen R. Covey</p>
</blockquote>
<p>At 21, I am finishing my degree in Electrical and Computer Engineering at NOVA FCT.</p>
<p>So far:</p>
<ul>
<li><p>I’ve been accepted into the Silicon Valley Fellowship Program: Only 18 out of 600 are accepted to visit Silicon Valley's top companies and universities.</p>
</li>
<li><p>I’ve delivered a talk to doctors about AI called "Trustworthy AI - The Role of Small AI Models in Critical Systems.". Before this, I delivered other smaller talks.</p>
</li>
<li><p>I’ve completed Coursera AI specializations such as the Deep Learning Specialization from DeepLearning.AI and Reinforcement Learning Specialization from the University of Alberta.</p>
</li>
<li><p>In IEEE (the largest non-profit professional association in the world), I served as the vice chair of my faculty IEEE NOVA SB student branch, and I am now an IEEE PT Officer, creating videos for social media.</p>
</li>
<li><p>I’ve had twenty articles published on freeCodeCamp since 2023 that have accumulated around 200,000 views. They are related to advanced applied math, AI, and technology. (Link below)</p>
</li>
<li><p>I’ve been recognized as a Top Open Source Contributor for freeCodeCamp in 2022, 2023, and 2024</p>
</li>
</ul>
<h2 id="heading-final-thoughts-have-an-adaptive-grand-strategy-for-your-life">Final Thoughts: Have an Adaptive Grand Strategy for Your Life</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743421784759/80ba16f2-fef7-4a4d-82b9-9287d7b43e53.jpeg" alt="80ba16f2-fef7-4a4d-82b9-9287d7b43e53" class="image--center mx-auto" width="1080" height="1293" loading="lazy"></p>
<p>Silicon Valley Fellowship post about me</p>
<blockquote>
<p><em>"What you do makes a difference, and you have to decide what kind of difference you want to make."</em><br>— Jane Goodall</p>
</blockquote>
<p>My life objective was and still the same when I was 14, 7 years ago:</p>
<ul>
<li>Help as many people as possible. In their opportunities to make their life’s better and in making society better for future generations that will come after mine.</li>
</ul>
<p><strong>My strongest advice for anyone: Have a grand strategy for your life.</strong></p>
<p>A grand strategy is a type of long-term strategy in which nations align power and resources to achieve their objectives. You must align your actions, skills, and knowledge towards your purpose.</p>
<p>I used to be afraid of public speaking and so many other things. Not anymore.</p>
<p>Now, I know I am destined to contribute, inspire, and leave a mark on other people's lives for the better.</p>
<p>If you feel stuck, remember:</p>
<ul>
<li><p>You can change! It will be hard. Many people will not want it.</p>
</li>
<li><p>Ignore all that and focus on yourself.</p>
</li>
</ul>
<p>It takes effort, patience and courage, but it is possible.</p>
<p><strong>Thanks to all organizations for the opportunity to contribute to society and grow as a person:</strong></p>
<ul>
<li><p>NOVA School of Science and Technology and its student association, AEFCT</p>
</li>
<li><p>IEEE Portugal Section</p>
</li>
<li><p>Silicon Valley Fellowship</p>
</li>
<li><p>BEST and BEST Almada</p>
</li>
<li><p>Magma Studio</p>
</li>
</ul>
<p>I also want to thank all the university professors at NOVA FCT who taught me, especially the ones from the department of electrical and computer engineering.</p>
<p>Finally, I want to express my gratitude to Portuguese society. Not long ago, in Portugal, pursuing higher education, especially in STEM, was inaccessible to many. Thanks to the efforts of past generations, today, young people like me can pursue these opportunities and contribute back to society.</p>
<p><strong>This is just the beginning of my impact on society.</strong></p>
<p>My FreeCodeCamp blog:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.freecodecamp.org/news/author/tiagomonteiro/">https://www.freecodecamp.org/news/author/tiagomonteiro/</a></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Real-Time Intrusion Detection System with Python and Open-Source Libraries ]]>
                </title>
                <description>
                    <![CDATA[ An Intrusion Detection System (IDS) is like a security camera for your network. Just as security cameras help identify suspicious activities in the physical world, an IDS will monitor your network to help detect any potential cyber attacks and securi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-real-time-intrusion-detection-system-with-python/</link>
                <guid isPermaLink="false">678faf10f366e60cf6e7b6d0</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Open Source ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chaitanya Rahalkar ]]>
                </dc:creator>
                <pubDate>Tue, 21 Jan 2025 14:28:32 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1737469496956/6cb12a90-de25-46da-aafc-bbd5048d0411.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>An Intrusion Detection System (IDS) is like a security camera for your network. Just as security cameras help identify suspicious activities in the physical world, an IDS will monitor your network to help detect any potential cyber attacks and security breaches.</p>
<p>By the end of this tutorial, you will know how an IDS works and be able to build your own real-time network monitoring system using Python.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-understanding-the-types-of-ids">Understanding the Types of IDS</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-setup-your-development-environment">How to Setup Your Development Environment</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-building-the-core-ids-components">Building the Core IDS Components</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-building-the-packet-capture-engine">Building the Packet Capture Engine</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-building-the-traffic-analysis-module">Building the Traffic Analysis Module</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-building-the-detection-engine">Building the Detection Engine</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-building-the-alert-system">Building the Alert System</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-putting-it-all-together">Putting It All Together</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-ideas-to-extend-the-ids">Ideas to Extend the IDS</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-security-considerations">Security Considerations</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-testing-the-ids-on-mock-data">Testing the IDS on Mock Data</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-wrapping-up">Wrapping Up</a></p>
</li>
</ul>
<h2 id="heading-understanding-the-types-of-ids">Understanding the Types of IDS</h2>
<p>Before we jump into the coding part, let’s understand the types of IDS:</p>
<ol>
<li><p><strong>Network-based IDS (NIDS)</strong>: This system monitors network traffic for suspicious activity.</p>
</li>
<li><p><strong>Host-based IDS (HIDS)</strong>: This system monitors system logs and file changes on individual hosts and is not directly deployed in the network.</p>
</li>
<li><p><strong>Signature-based IDS</strong>: This system is either in the network or on the host and identifies attack patterns based on known patterns.</p>
</li>
<li><p><strong>Anomaly-based IDS</strong>: This system identifies unusual behavior using heuristics and prediction algorithms that are trained on previously seen attack patterns.</p>
</li>
</ol>
<p>For this tutorial, you will be building a hybrid system that combines signature-based and anomaly-based detection systems to monitor network traffic.</p>
<h2 id="heading-how-to-setup-your-development-environment">How to Setup Your Development Environment</h2>
<p>Let’s start by setting up our Python environment (I’m using Python 3) and installing the following prerequisites:</p>
<pre><code class="lang-bash">pip install scapy
pip install python-nmap
pip install numpy
pip install sklearn
</code></pre>
<h2 id="heading-building-the-core-ids-components">Building the Core IDS Components</h2>
<p>Our IDS will comprise of four main components:</p>
<ol>
<li><p>A packet capture system</p>
</li>
<li><p>Traffic analysis module</p>
</li>
<li><p>A detection engine</p>
</li>
<li><p>An alert system</p>
</li>
</ol>
<h3 id="heading-building-the-packet-capture-engine">Building the Packet Capture Engine</h3>
<p>Let’s start with the packet capture engine. We’ll use Scapy for this. Scapy is a networking library that allows us to perform network and network-related operations using Python.</p>
<p>First, we’ll define our <code>PacketCapture</code> class that will serve as the basis of our IDS.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> scapy.all <span class="hljs-keyword">import</span> sniff, IP, TCP
<span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> defaultdict
<span class="hljs-keyword">import</span> threading
<span class="hljs-keyword">import</span> queue

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PacketCapture</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.packet_queue = queue.Queue()
        self.stop_capture = threading.Event()

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">packet_callback</span>(<span class="hljs-params">self, packet</span>):</span>
        <span class="hljs-keyword">if</span> IP <span class="hljs-keyword">in</span> packet <span class="hljs-keyword">and</span> TCP <span class="hljs-keyword">in</span> packet:
            self.packet_queue.put(packet)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">start_capture</span>(<span class="hljs-params">self, interface=<span class="hljs-string">"eth0"</span></span>):</span>
        <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">capture_thread</span>():</span>
            sniff(iface=interface,
                  prn=self.packet_callback,
                  store=<span class="hljs-number">0</span>,
                  stop_filter=<span class="hljs-keyword">lambda</span> _: self.stop_capture.is_set())

        self.capture_thread = threading.Thread(target=capture_thread)
        self.capture_thread.start()

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">stop</span>(<span class="hljs-params">self</span>):</span>
        self.stop_capture.set()
        self.capture_thread.join()
</code></pre>
<p>Let’s quickly walk through the code and understand what these functions do. For this, you will be using threading and queues to efficiently process and capture network packets.</p>
<p>The <code>init</code> method initializes the class by creating a <code>queue.Queue</code> to store captured packets and a threading Event to control when the packet capture should stop. The <code>packet_callback</code> method acts as a handler for each captured packet and checks if the packet contains both IP and TCP layers. If so, it adds it to the queue for further processing.</p>
<p>The <code>start_capture</code> method begins capturing packets on a specified interface (defaulting to <code>eth0</code> to capture packets from the Ethernet interface). Run <code>ifconfig</code> to understand the available interfaces and select the appropriate interface from the list.</p>
<p>The function spawns a separate thread to run Scapy’s sniff function, which continuously monitors the interface for packets. The <code>stop_filter</code> parameter ensures the capture stops when the <code>stop_capture</code> event is triggered.</p>
<p>The <code>stop</code> method stops the capture by setting the <code>stop_capture</code> event and waits for the thread to finish execution, ensuring the process terminates cleanly. This design allows for seamless real-time packet capturing without blocking the main thread.</p>
<h3 id="heading-building-the-traffic-analysis-module">Building the Traffic Analysis Module</h3>
<p>Now, let’s write the traffic analysis module. This module will process captured packets and extract relevant features.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TrafficAnalyzer</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.connections = defaultdict(list)
        self.flow_stats = defaultdict(<span class="hljs-keyword">lambda</span>: {
            <span class="hljs-string">'packet_count'</span>: <span class="hljs-number">0</span>,
            <span class="hljs-string">'byte_count'</span>: <span class="hljs-number">0</span>,
            <span class="hljs-string">'start_time'</span>: <span class="hljs-literal">None</span>,
            <span class="hljs-string">'last_time'</span>: <span class="hljs-literal">None</span>
        })

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">analyze_packet</span>(<span class="hljs-params">self, packet</span>):</span>
        <span class="hljs-keyword">if</span> IP <span class="hljs-keyword">in</span> packet <span class="hljs-keyword">and</span> TCP <span class="hljs-keyword">in</span> packet:
            ip_src = packet[IP].src
            ip_dst = packet[IP].dst
            port_src = packet[TCP].sport
            port_dst = packet[TCP].dport

            flow_key = (ip_src, ip_dst, port_src, port_dst)

            <span class="hljs-comment"># Update flow statistics</span>
            stats = self.flow_stats[flow_key]
            stats[<span class="hljs-string">'packet_count'</span>] += <span class="hljs-number">1</span>
            stats[<span class="hljs-string">'byte_count'</span>] += len(packet)
            current_time = packet.time

            <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> stats[<span class="hljs-string">'start_time'</span>]:
                stats[<span class="hljs-string">'start_time'</span>] = current_time
            stats[<span class="hljs-string">'last_time'</span>] = current_time

            <span class="hljs-keyword">return</span> self.extract_features(packet, stats)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">extract_features</span>(<span class="hljs-params">self, packet, stats</span>):</span>
        <span class="hljs-keyword">return</span> {
            <span class="hljs-string">'packet_size'</span>: len(packet),
            <span class="hljs-string">'flow_duration'</span>: stats[<span class="hljs-string">'last_time'</span>] - stats[<span class="hljs-string">'start_time'</span>],
            <span class="hljs-string">'packet_rate'</span>: stats[<span class="hljs-string">'packet_count'</span>] / (stats[<span class="hljs-string">'last_time'</span>] - stats[<span class="hljs-string">'start_time'</span>]),
            <span class="hljs-string">'byte_rate'</span>: stats[<span class="hljs-string">'byte_count'</span>] / (stats[<span class="hljs-string">'last_time'</span>] - stats[<span class="hljs-string">'start_time'</span>]),
            <span class="hljs-string">'tcp_flags'</span>: packet[TCP].flags,
            <span class="hljs-string">'window_size'</span>: packet[TCP].window
        }
</code></pre>
<p>In this code section, we define the <code>TrafficAnalyzer</code> class to analyze network traffic. Here we track connection flows and calculate statistics for packets in real time. We use the <code>defaultdict</code> data structure in Python to manage connections and flow statistics by organizing data by unique flows.</p>
<p>The <code>__init__</code> method initializes two attributes: <code>connections</code>, which stores lists of related packets for each flow, and <code>flow_stats</code>, which stores aggregated statistics for each flow, such as packet count, byte count, start time, and the time of the most recent packet.</p>
<p>The <code>analyze_packet</code> method processes each packet. If the packet contains IP and TCP layers, it extracts the source and destination IPs and ports, forming a unique <code>flow_key</code> to identify the flow. It updates the statistics for the flow by incrementing the packet count, adding the packet’s size to the byte count, and setting or updating the start and last time of the flow. Eventually, it calls <code>extract_features</code> to calculate and return additional metrics.</p>
<p>The <code>extract_features</code> method computes detailed characteristics of the flow and the current packet. These include the packet size, flow duration, packet rate, byte rate, TCP flags, and the TCP window size. These metrics are quite useful to identify patterns, anomalies, or potential threats in network traffic.</p>
<h3 id="heading-building-the-detection-engine">Building the Detection Engine</h3>
<p>Now we will define our detection engine that will implement both the signature as well as the anomaly-based detection mechanisms:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> sklearn.ensemble <span class="hljs-keyword">import</span> IsolationForest
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DetectionEngine</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self.anomaly_detector = IsolationForest(
            contamination=<span class="hljs-number">0.1</span>,
            random_state=<span class="hljs-number">42</span>
        )
        self.signature_rules = self.load_signature_rules()
        self.training_data = []

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">load_signature_rules</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> {
            <span class="hljs-string">'syn_flood'</span>: {
                <span class="hljs-string">'condition'</span>: <span class="hljs-keyword">lambda</span> features: (
                    features[<span class="hljs-string">'tcp_flags'</span>] == <span class="hljs-number">2</span> <span class="hljs-keyword">and</span>  <span class="hljs-comment"># SYN flag</span>
                    features[<span class="hljs-string">'packet_rate'</span>] &gt; <span class="hljs-number">100</span>
                )
            },
            <span class="hljs-string">'port_scan'</span>: {
                <span class="hljs-string">'condition'</span>: <span class="hljs-keyword">lambda</span> features: (
                    features[<span class="hljs-string">'packet_size'</span>] &lt; <span class="hljs-number">100</span> <span class="hljs-keyword">and</span>
                    features[<span class="hljs-string">'packet_rate'</span>] &gt; <span class="hljs-number">50</span>
                )
            }
        }

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">train_anomaly_detector</span>(<span class="hljs-params">self, normal_traffic_data</span>):</span>
        self.anomaly_detector.fit(normal_traffic_data)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">detect_threats</span>(<span class="hljs-params">self, features</span>):</span>
        threats = []

        <span class="hljs-comment"># Signature-based detection</span>
        <span class="hljs-keyword">for</span> rule_name, rule <span class="hljs-keyword">in</span> self.signature_rules.items():
            <span class="hljs-keyword">if</span> rule[<span class="hljs-string">'condition'</span>](features):
                threats.append({
                    <span class="hljs-string">'type'</span>: <span class="hljs-string">'signature'</span>,
                    <span class="hljs-string">'rule'</span>: rule_name,
                    <span class="hljs-string">'confidence'</span>: <span class="hljs-number">1.0</span>
                })

        <span class="hljs-comment"># Anomaly-based detection</span>
        feature_vector = np.array([[
            features[<span class="hljs-string">'packet_size'</span>],
            features[<span class="hljs-string">'packet_rate'</span>],
            features[<span class="hljs-string">'byte_rate'</span>]
        ]])

        anomaly_score = self.anomaly_detector.score_samples(feature_vector)[<span class="hljs-number">0</span>]
        <span class="hljs-keyword">if</span> anomaly_score &lt; <span class="hljs-number">-0.5</span>:  <span class="hljs-comment"># Threshold for anomaly detection</span>
            threats.append({
                <span class="hljs-string">'type'</span>: <span class="hljs-string">'anomaly'</span>,
                <span class="hljs-string">'score'</span>: anomaly_score,
                <span class="hljs-string">'confidence'</span>: min(<span class="hljs-number">1.0</span>, abs(anomaly_score))
            })

        <span class="hljs-keyword">return</span> threats
</code></pre>
<p>This code defines a hybrid system that combines the signature-based and anomaly-based detection methods. We use the Isolation Forest model to detect anomalies and also use pre-defined rules for identifying specific attack patterns. If you would like to know more about how the Isolation Forest model works, check out <a target="_blank" href="https://medium.com/@corymaklin/isolation-forest-799fceacdda4">this</a> article.</p>
<p>In this code snippet, the <code>train_anomaly_detector</code> method trains the Isolation Forest model using a dataset of normal traffic features. This enables the model to differentiate typical traffic patterns from anomalies.</p>
<p>The <code>detect_threats</code> method evaluates network traffic features for potential threats using two approaches:</p>
<ol>
<li><p><strong>Signature-Based Detection</strong>: It iteratively goes through each of the predefined rules, applying the rule’s condition to the traffic features. If a rule matches, a signature-based threat is recorded with high confidence.</p>
</li>
<li><p><strong>Anomaly-Based Detection</strong>: It processes the feature vector (packet size, packet rate, and byte rate) through the Isolation Forest model to calculate an anomaly score. If the score indicates unusual behavior, the detection engine triggers it as an anomaly and produces a confidence score proportional to the anomaly’s severity.</p>
</li>
</ol>
<p>Finally, we return the aggregated list of identified threats with their respective annotation (either signature or anomaly), the rule or score that triggered the anomaly, and a confidence score that suggests how likely it is that the identified pattern is a threat.</p>
<h3 id="heading-building-the-alert-system">Building the Alert System</h3>
<p>Now let’s build the last component of our IDS which is the alert system. It will process and log detected threats in a structured way. You will also have the option to extend the system to include additional notification mechanisms like Slack, Jira tickets, and so on</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> logging
<span class="hljs-keyword">import</span> json
<span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> datetime

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AlertSystem</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, log_file=<span class="hljs-string">"ids_alerts.log"</span></span>):</span>
        self.logger = logging.getLogger(<span class="hljs-string">"IDS_Alerts"</span>)
        self.logger.setLevel(logging.INFO)

        handler = logging.FileHandler(log_file)
        formatter = logging.Formatter(
            <span class="hljs-string">'%(asctime)s - %(levelname)s - %(message)s'</span>
        )
        handler.setFormatter(formatter)
        self.logger.addHandler(handler)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">generate_alert</span>(<span class="hljs-params">self, threat, packet_info</span>):</span>
        alert = {
            <span class="hljs-string">'timestamp'</span>: datetime.now().isoformat(),
            <span class="hljs-string">'threat_type'</span>: threat[<span class="hljs-string">'type'</span>],
            <span class="hljs-string">'source_ip'</span>: packet_info.get(<span class="hljs-string">'source_ip'</span>),
            <span class="hljs-string">'destination_ip'</span>: packet_info.get(<span class="hljs-string">'destination_ip'</span>),
            <span class="hljs-string">'confidence'</span>: threat.get(<span class="hljs-string">'confidence'</span>, <span class="hljs-number">0.0</span>),
            <span class="hljs-string">'details'</span>: threat
        }

        self.logger.warning(json.dumps(alert))

        <span class="hljs-keyword">if</span> threat[<span class="hljs-string">'confidence'</span>] &gt; <span class="hljs-number">0.8</span>:
            self.logger.critical(
                <span class="hljs-string">f"High confidence threat detected: <span class="hljs-subst">{json.dumps(alert)}</span>"</span>
            )
            <span class="hljs-comment"># Implement additional notification methods here</span>
            <span class="hljs-comment"># (e.g., email, Slack, SIEM integration)</span>
</code></pre>
<p>The <code>init</code> method sets up a logger named <code>IDS_Alerts</code> with an <code>INFO</code> logging level to capture alert information. It writes logs to a specified file, <code>ids_alerts.log</code> by default. A <code>FileHandler</code> directs logs to the file, while the <code>Formatter</code> ensures the logs follow a consistent format.</p>
<p>The <code>generate_alert</code> method is responsible for creating structured alert entries. Each alert includes key information such as the timestamp of detection, the type of threat, the source and destination IPs involved, the confidence level of the detection, and additional threat-specific details. These alerts are logged as <code>WARNING</code> level messages in JSON format.</p>
<p>If the confidence level of a detected threat is high (greater than 0.8), the alert is escalated and logged as a <code>CRITICAL</code> level message. Note that this method is designed to be extensible, allowing for additional notification mechanisms, such as sending alerts via email or integrating with third-party systems like Slack or SIEM solutions.</p>
<h3 id="heading-putting-it-all-together">Putting it All Together</h3>
<p>Now let’s integrate all the components together into our fully functional IDS solution:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IntrusionDetectionSystem</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, interface=<span class="hljs-string">"eth0"</span></span>):</span>
        self.packet_capture = PacketCapture()
        self.traffic_analyzer = TrafficAnalyzer()
        self.detection_engine = DetectionEngine()
        self.alert_system = AlertSystem()

        self.interface = interface

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">start</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f"Starting IDS on interface <span class="hljs-subst">{self.interface}</span>"</span>)
        self.packet_capture.start_capture(self.interface)

        <span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:
            <span class="hljs-keyword">try</span>:
                packet = self.packet_capture.packet_queue.get(timeout=<span class="hljs-number">1</span>)
                features = self.traffic_analyzer.analyze_packet(packet)

                <span class="hljs-keyword">if</span> features:
                    threats = self.detection_engine.detect_threats(features)

                    <span class="hljs-keyword">for</span> threat <span class="hljs-keyword">in</span> threats:
                        packet_info = {
                            <span class="hljs-string">'source_ip'</span>: packet[IP].src,
                            <span class="hljs-string">'destination_ip'</span>: packet[IP].dst,
                            <span class="hljs-string">'source_port'</span>: packet[TCP].sport,
                            <span class="hljs-string">'destination_port'</span>: packet[TCP].dport
                        }
                        self.alert_system.generate_alert(threat, packet_info)

            <span class="hljs-keyword">except</span> queue.Empty:
                <span class="hljs-keyword">continue</span>
            <span class="hljs-keyword">except</span> KeyboardInterrupt:
                print(<span class="hljs-string">"Stopping IDS..."</span>)
                self.packet_capture.stop()
                <span class="hljs-keyword">break</span>

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    ids = IntrusionDetectionSystem()
    ids.start()
</code></pre>
<p>In this code, the <code>IntrusionDetectionSystem</code> class sets up its core components: <code>PacketCapture</code> for capturing packets from a network interface, <code>TrafficAnalyzer</code> for extracting and analyzing packet features, <code>DetectionEngine</code> for identifying threats using both signature-based and anomaly-based methods, and <code>AlertSystem</code> for logging and escalating detected threats. The interface parameter specifies the network interface to monitor, defaulting to <code>eth0</code> (the generally named ethernet interface on most systems).</p>
<p>The <code>start</code> function initiates the IDS. It begins by starting packet capture on the specified interface and enters a loop to continuously process incoming packets. For each packet captured, the system extracts its features using the <code>TrafficAnalyzer</code> and analyzes them for potential threats using the <code>DetectionEngine</code>. If any threats are detected, the system generates detailed alerts through the <code>AlertSystem</code>.</p>
<p>The system runs in a loop until interrupted by either of the two key exceptions: <code>queue.Empty</code>, which occurs if no packets are available for processing, and <code>KeyboardInterrupt</code>, which stops the IDS gracefully by halting packet capture and exiting the loop.</p>
<h2 id="heading-ideas-to-extend-the-ids">Ideas to Extend the IDS</h2>
<p>To enhance or extend the IDS, you can consider designing or implementing the following features / improvements:</p>
<ol>
<li><p><strong>Machine Learning enhancements:</strong> You can enhance the IDS capabilities by incorporating deep learning models like Auto Encoders for anomaly detection and using RNNs for sequential pattern analysis. This will improve the system’s ability to identify complex and evolving threats by leveraging advanced feature engineering.</p>
</li>
<li><p><strong>Performance optimizations</strong>: You can optimize the IDS using PyPy for faster execution, packet sampling to handle high-traffic networks, and parallel processing to scale the system efficiently.</p>
</li>
<li><p><strong>Integration capabilities</strong>: You can extend the IDS by considering support for a REST API for remote monitoring, enabling seamless interaction with external systems.</p>
</li>
</ol>
<h2 id="heading-security-considerations">Security Considerations</h2>
<p>When deploying the IDS, note that the system is a proof-of-concept and is not intended for production use-cases. Also keep the following things in mind:</p>
<ul>
<li><p>Run the system with appropriate permissions (root/admin required for packet capture)</p>
</li>
<li><p>Secure the alert logs and implement proper log rotation</p>
</li>
<li><p>Regularly update signature rules and retrain anomaly detection models</p>
</li>
<li><p>Monitor system resource usage, especially in high-traffic environments</p>
</li>
<li><p>Implement proper access controls for the IDS configuration and alerts</p>
</li>
</ul>
<h2 id="heading-testing-the-ids-on-mock-data">Testing the IDS on Mock Data</h2>
<p>To validate the functionality of your IDS, you can test it using mock data that will simulate real-world network traffic. This will allow you to observe how the system processes packets, analyzes traffic, and generates alerts without requiring a live network environment.</p>
<p>Use the following function to test the IDS:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> scapy.all <span class="hljs-keyword">import</span> IP, TCP

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test_ids</span>():</span>
    <span class="hljs-comment"># Create test packets to simulate various scenarios</span>
    test_packets = [
        <span class="hljs-comment"># Normal traffic</span>
        IP(src=<span class="hljs-string">"192.168.1.1"</span>, dst=<span class="hljs-string">"192.168.1.2"</span>) / TCP(sport=<span class="hljs-number">1234</span>, dport=<span class="hljs-number">80</span>, flags=<span class="hljs-string">"A"</span>),
        IP(src=<span class="hljs-string">"192.168.1.3"</span>, dst=<span class="hljs-string">"192.168.1.4"</span>) / TCP(sport=<span class="hljs-number">1235</span>, dport=<span class="hljs-number">443</span>, flags=<span class="hljs-string">"P"</span>),

        <span class="hljs-comment"># SYN flood simulation</span>
        IP(src=<span class="hljs-string">"10.0.0.1"</span>, dst=<span class="hljs-string">"192.168.1.2"</span>) / TCP(sport=<span class="hljs-number">5678</span>, dport=<span class="hljs-number">80</span>, flags=<span class="hljs-string">"S"</span>),
        IP(src=<span class="hljs-string">"10.0.0.2"</span>, dst=<span class="hljs-string">"192.168.1.2"</span>) / TCP(sport=<span class="hljs-number">5679</span>, dport=<span class="hljs-number">80</span>, flags=<span class="hljs-string">"S"</span>),
        IP(src=<span class="hljs-string">"10.0.0.3"</span>, dst=<span class="hljs-string">"192.168.1.2"</span>) / TCP(sport=<span class="hljs-number">5680</span>, dport=<span class="hljs-number">80</span>, flags=<span class="hljs-string">"S"</span>),

        <span class="hljs-comment"># Port scan simulation</span>
        IP(src=<span class="hljs-string">"192.168.1.100"</span>, dst=<span class="hljs-string">"192.168.1.2"</span>) / TCP(sport=<span class="hljs-number">4321</span>, dport=<span class="hljs-number">22</span>, flags=<span class="hljs-string">"S"</span>),
        IP(src=<span class="hljs-string">"192.168.1.100"</span>, dst=<span class="hljs-string">"192.168.1.2"</span>) / TCP(sport=<span class="hljs-number">4321</span>, dport=<span class="hljs-number">23</span>, flags=<span class="hljs-string">"S"</span>),
        IP(src=<span class="hljs-string">"192.168.1.100"</span>, dst=<span class="hljs-string">"192.168.1.2"</span>) / TCP(sport=<span class="hljs-number">4321</span>, dport=<span class="hljs-number">25</span>, flags=<span class="hljs-string">"S"</span>),
    ]

    ids = IntrusionDetectionSystem()

    <span class="hljs-comment"># Simulate packet processing and threat detection</span>
    print(<span class="hljs-string">"Starting IDS Test..."</span>)
    <span class="hljs-keyword">for</span> i, packet <span class="hljs-keyword">in</span> enumerate(test_packets, <span class="hljs-number">1</span>):
        print(<span class="hljs-string">f"\nProcessing packet <span class="hljs-subst">{i}</span>: <span class="hljs-subst">{packet.summary()}</span>"</span>)

        <span class="hljs-comment"># Analyze the packet</span>
        features = ids.traffic_analyzer.analyze_packet(packet)

        <span class="hljs-keyword">if</span> features:
            <span class="hljs-comment"># Detect threats based on features</span>
            threats = ids.detection_engine.detect_threats(features)

            <span class="hljs-keyword">if</span> threats:
                print(<span class="hljs-string">f"Detected threats: <span class="hljs-subst">{threats}</span>"</span>)
            <span class="hljs-keyword">else</span>:
                print(<span class="hljs-string">"No threats detected."</span>)
        <span class="hljs-keyword">else</span>:
            print(<span class="hljs-string">"Packet does not contain IP/TCP layers or is ignored."</span>)

    print(<span class="hljs-string">"\nIDS Test Completed."</span>)

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    test_ids()
</code></pre>
<p>This will test the system against a variety of attacks like SYN flooding and port scanning.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Now you know how to build a basic intrusion detection system with Python and a few open-source libraries! This IDS demonstrates some core concepts of network security and real-time threat detection.</p>
<p>Keep in mind that this tutorial is for educational purposes only. There are professionally designed enterprise-grade systems like Snort and Suricata that can handle advanced threats and large-scale deployments.</p>
<p>I hope you gained insights into network security fundamentals and learned how Python can be used to build practical security solutions.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Help Someone with Their Code Using the Socratic Method ]]>
                </title>
                <description>
                    <![CDATA[ As a programming community, freeCodeCamp helps many people who have questions about their code. It can be quite tempting to simply provide the learner with the answer and move on, but that’s actually detrimental to the learning process. Here’s why: W... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-help-someone-with-their-code-using-the-socratic-method/</link>
                <guid isPermaLink="false">677d816db702998ae550cebf</guid>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ freeCodeCamp.org ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Naomi Carrigan ]]>
                </dc:creator>
                <pubDate>Tue, 07 Jan 2025 19:33:01 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/2RRq1BHPq4E/upload/904ec5e77783268f025191b07da29f08.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As a programming community, freeCodeCamp helps many people who have questions about their code. It can be quite tempting to simply provide the learner with the answer and move on, but that’s actually detrimental to the learning process. Here’s why:</p>
<p>When you give someone the answer, you are depriving them of that “aha” moment. You are removing the opportunity for them to learn how to reach the conclusion through their own thinking, and instead allowing them to progress with minimal effort or thought.</p>
<p>So how can you best help someone with their code?</p>
<h2 id="heading-what-is-the-socratic-method">What is the Socratic Method?</h2>
<p>The Greek philosopher Plato was a student of another philosopher, Socrates. In Plato’s works, he often writes about the debates that Socrates would have with his colleagues and students.</p>
<p>Socrates would begin these discussions by raising common beliefs and scrutinizing them to question their compatibility with other beliefs, and guide people to reach the truth.</p>
<p>But how does that translate to our modern day interactions in a digital age?</p>
<p>Let’s consider a real example from one of our communities:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736179977371/7e087ee9-4b7e-4321-ade9-18019289320d.png" alt="A Discord message from the user Razzle Dazzle, reading &quot;How do I find the sum of the numbers in an array?&quot;" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>You might be tempted to give them the direct answer, such as this code example:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> sum = nums.reduce(<span class="hljs-function">(<span class="hljs-params">acc, el</span>) =&gt;</span> acc + el, <span class="hljs-number">0</span>);
</code></pre>
<p>But in doing so, you have performed the logical reasoning on behalf of the learner.</p>
<p>Instead, you should focus on asking pointed questions to <em>guide</em> them to the answer. For example, you might start by asking:</p>
<blockquote>
<p>❓ How would you find the sum of a list of numbers on pen and paper, without code?</p>
</blockquote>
<p>It may seem counter-intuitive to ask the learner a question that requires them to step away from the code, but you are actually pointing them to the underlying logic behind their question.</p>
<p>Let’s assume the learner responds with something like:</p>
<blockquote>
<p>I would go through each number, one by one, and add it to the sum of the previous numbers.</p>
</blockquote>
<p>As the learner begins answering your questions, the dialogue should progress in this call-and-response format. Your questions should become increasingly narrow and pointed with the learner’s progress toward the solution.</p>
<p>For example, a series of questions might look like:</p>
<blockquote>
<p>Instructor: “Great, now what is an array of numbers?”<br>Student: “A list?”<br>Instructor: “Good! How would you iterate through that list?”<br>Student: “With a for loop.”<br>Instructor: “And what does your loop need to do on each iteration?”<br>Student: “Add the current number to the sum.”<br>Instructor: “Where can you find the sum?”<br>Student: “I could put it in a variable outside the loop.”<br>Instructor: “Great, now you’re ready to try writing the code.”<br>— original example written for this article</p>
</blockquote>
<p>At this point, the learner will likely connect the dots and reach the final solution.</p>
<h2 id="heading-socrates-in-modern-culture">Socrates in Modern Culture</h2>
<p>Learning the Socratic method is hard. In fact, many do not encounter it until they reach their university studies. But there are examples found in modern pop culture that can help you understand how the Socratic method works.</p>
<p>The TV show House, M.D. is rife with examples. Take this exchange from the episode titled “Three Stories”:</p>
<blockquote>
<p>House: “Kidney stones would cause what?”<br>Student: “Blood in urine.”<br>House: “What colour is your pee?”<br>Student: “Yellow.”<br>House: “What colour is your blood?”<br>Student: “Red.”<br>House: “What colours did I use?”<br>Student: “Red, yellow, and brown.<br>House: “And brown. What causes brown?”<br>Student: “Waste”.<br>— (Frapier, 2008)¹</p>
</blockquote>
<p>You’ll notice how this exchange took place. House’s goal here was not to <em>give</em> the learner the answer, but to ask deductive questions to <em>guide</em> the learner to reach the answer on their own.</p>
<p>Consider the popular movie The Matrix:</p>
<blockquote>
<p>Morpheus: “Have you ever had a dream, Neo, that you were so sure was real?”<br>Neo: “This can't be…”<br>Morpheus: “Be what? Be real?”<br>Morpheus: “What if you were unable to wake from that dream, Neo? How would you know the difference between the dreamworld and the real world?”<br>— (Wachowski &amp; Wachowski, 1999)²</p>
</blockquote>
<p>In this scene, Morpheus is applying the Socratic method to lead Neo to question his perceptions of reality. This is a rather dramatic example, but the premise remains the same: rather than telling the learner how they should think, you guide them to reach the conclusion through their own volition.</p>
<p>Finally, let’s look at an example from Legally Blonde:</p>
<blockquote>
<p>Elle: “Your father was shot while you were in the shower?”<br>…<br>Chutney: “Yes. I was washing my hair.”<br>Elle: “Miss Windham, can you tell us what you'd been doing earlier in the day?”<br>Chutney: “I got up, went to Starbucks, went to the gym, got a perm, and came home.”<br>Elle: “Where you got in the shower.”<br>Chutney: “Yes.”<br>…<br>Elle: “…Had you ever gotten a perm before, Miss Windham?”<br>Chutney: “Yes.”<br>Elle: “How many, would you say?”<br>Chutney: “Two a year since I was twelve. You do the math.”<br>…<br>Elle: “Chutney, why is it that Tracy Marcinko's curls were ruined when she got hosed down?”<br>Chutney: “Because they got wet.”<br>Elle: “That's right. Because isn't the first cardinal rule of perm maintenance that you are forbidden to wet your hair for at least twenty-four hours after getting a perm at the risk of de-activating the ammonium thiglycolate? And wouldn't someone who's had -- thirty perms ? -- throughout her lifetime, be well aware of this rule? And if you, in fact, were not washing your hair, as I suspect you were not, since your curls are still intact, wouldn't you have heard the gunshot?”<br>—(Luketic, 2001)³</p>
</blockquote>
<p>The Socratic method can often be seen in law, and this serves as an excellent example. Through this exchange, Elle is not trying to guide Chutney to reach a conclusion, but rather the <em>spectators</em> (in this case, the jury). This is an important distinction for a community such as ours: where engaging in a Socratic discussion with one member can actually benefit current and future members who may observe or revisit your conversation.</p>
<h2 id="heading-goal-of-the-socratic-method">Goal of the Socratic Method</h2>
<p>It is important to recognize that the goal of the Socratic method is <em>not</em> to present a quick exchange of information. Instead, the aim is to first get the learner to realize that they know less than they believe they do, then guide them to the answer through questions that elicit certain thought processes.⁴</p>
<p>When applying this to learning programming, then, it’s important to remember the phrase “challenge your assumptions”. We often assume that we know what the code we have written is doing, so our first step when it is not working is to examine those assumptions.</p>
<p>As we guide learners through the process of debugging, we want to ask questions that do the same. A common question in your repertoire should be “What does this line of code do?”. When the learner answers with information that is inaccurate, respond with questions that drill down into smaller components of the code – break the problem into pieces, per se.</p>
<p>Consider this example:</p>
<blockquote>
<p>Learner: “but maybe that wouldnt work because I need to find the book not the id in the book”<br>Instructor: “Correct. Now, the good news is that we have a function that would ostensibly do that. The bad news is that function doesn't do that. What does that function do instead?”<br>Learner: “returns bookId”<br>— sourced from our Discord community⁵</p>
</blockquote>
<p>By asking the question “What does that function do instead?”, the instructor has provided the direction for the learner to reach the correct conclusion without having to provide any specific information. The learner already knew that the function did not perform as expected, and the instructor asked the question to challenge the learner’s assumption that the function <em>did</em> perform.</p>
<p>Here’s another example:</p>
<blockquote>
<p>Instructor: “This is the example from the Chalenge (sic). Did you follow that example they gave?”<br>Learner: “yes but i didnt understand the for-in loop, i didnt understand "(const food in refigerator)", having to state the string property name with const or let was confusing (it isnt anymore)”<br>Instructor: “Ok, so lets start here instead of the full solution to the Challenge”<br>Instructor: “What does that code do when you run it?”<br>…<br>Learner: “each of the object's keys were set to the variable food which was made in the for-in loop, it then iterates through the object and logs the key and value assigned to the key?”<br>— sourced from our Discord community⁶</p>
</blockquote>
<p>Again we can see how the instructor focuses on asking pointed questions that guide the user toward the solutions <em>through their own reasoning</em>.</p>
<blockquote>
<p>❗ That is the ultimate goal of the Socratic method: to guide the learner to reach the logical conclusion solely through their own reasoning.</p>
</blockquote>
<h2 id="heading-long-term-benefits-of-the-socratic-method">Long-Term Benefits of the Socratic Method</h2>
<p>The Socratic method is not solely beneficial for resolving the immediate solution. The deductive reasoning process that is applied in this approach can also serve the learner well over the long-term.</p>
<p>The process of asking a learner questions to challenge their assumptions and knowledge, and guide them to the solution, is something that can be internalized as well. It’s a powerful tool to have in your repertoire for approaching debugging, isolating assumptions, and even learning to articulate an issue.</p>
<p>That is, by walking a learner through this call-and-response conversation, the learner can also walk away with the ability to ask <em>themselves</em> these questions. They can take the same process of asking increasingly narrowing questions as a logical pathway and run through it mentally when they encounter future issues with their code (or even in other aspects of life)!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Providing a solution directly to a learner inhibits their intellectual growth and deprives them of the rewarding experience that comes from reaching their own logical conclusion. By leveraging techniques like the Socratic method, we can foster a stronger and more effective educational environment that allows learners to grow and thrive.</p>
<blockquote>
<p>💡 If you were sent this article in response to a forum post, Reddit comment, Discord message, or other communication where you gave a fellow learner a working solution, please consider the merits of this method instead.</p>
</blockquote>
<p>This approach can seem tedious and lengthy, and at times it is. It is far quicker (and arguably easier) to hand someone the code that resolves their problem.</p>
<p>But that approach, more often than not, harms the learner in the end. And, if you’ll forgive this author for an anecdote, I have seen people get frustrated when they are the subject of a Socratic approach, or lose patience with the back and forth conversation. But I have <em>never</em> seen them upset with or disappointed by that end result – the “aha” moment where they deduce the solution to the problem through their own reasoning.</p>
<h3 id="heading-sources">Sources:</h3>
<ol>
<li><p>¹ Frapier, M. (2008). Being Nice is Overrated: House and Socrates on the Necessity of Conflict. In <em>House and Philosophy</em> (pp. 100–101). John Wiley &amp; Sons, Inc.</p>
</li>
<li><p>² Wachowski, L., &amp; Wachowski, L. (Directors). (1999, March 24). <em>The Matrix</em> (Z. Staenberg, Ed.). Warner Bros.</p>
</li>
<li><p>³ Luketic, R. (Director). (2001, July 13). <em>Legally Blonde</em> (A. Brandt-Burgoyne, Ed.). MGM Distribution Co.</p>
</li>
<li><p>⁴ Frapier, M. (2008). Being Nice is Overrated: House and Socrates on the Necessity of Conflict. In <em>House and Philosophy</em> (p. 103). John Wiley &amp; Sons, Inc.</p>
</li>
<li><p>⁵ lightskingeneral &amp; plamoni (2024, January 4). [Discord conversation]. Discord. Retrieved 2025, January 6, from <a target="_blank" href="https://discord.com/channels/692816967895220344/718214639669870683/1192488621043888198">https://discord.com/channels/692816967895220344/718214639669870683/1192488621043888198</a></p>
</li>
<li><p>⁶ lightskingeneral &amp; jeremylt (2023, November 13). [Discord conversation]. Discord. Retrieved 2025, January 6, from <a target="_blank" href="https://discord.com/channels/692816967895220344/718214639669870683/1173733715109761065">https://discord.com/channels/692816967895220344/718214639669870683/1173733715109761065</a></p>
</li>
</ol>
<p>Special thanks to ArielLeslie and JeremyLT for their help with this article.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use SSH to Safely Connect to GitHub: A Simple Guide for Windows OS ]]>
                </title>
                <description>
                    <![CDATA[ In this article, we will explore the Secure Shell (SSH) protocol, a vital tool for securing network communications. SSH is widely used for accessing remote servers and managing code repositories securely, particularly in environments like GitHub. You... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-ssh-to-connect-to-github-guide-for-windows/</link>
                <guid isPermaLink="false">66f6c252eda714770c805738</guid>
                
                    <category>
                        <![CDATA[ ssh ]]>
                    </category>
                
                    <category>
                        <![CDATA[ networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Beginner Developers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Programming Blogs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oghenekparobo Stephen ]]>
                </dc:creator>
                <pubDate>Fri, 27 Sep 2024 14:33:54 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727226065318/c1522ad1-df49-4bc9-aa31-567d4012585a.avif" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, we will explore the Secure Shell (SSH) protocol, a vital tool for securing network communications.</p>
<p>SSH is widely used for accessing remote servers and managing code repositories securely, particularly in environments like GitHub. You’ll learn about the fundamental concepts of SSH, how it works, and practical steps to set it up on Windows. We will cover everything from generating SSH keys to testing your connection and cloning repositories.</p>
<p>By the end of this guide, you will have a solid understanding of SSH and be equipped to enhance your workflow with secure connections.</p>
<h3 id="heading-what-well-cover">What we’ll cover:</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-what-is-ssh">What is SSH?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-does-the-secure-shell-protocol-work">How Does the Secure Shell Protocol Work?</a></p>
</li>
</ol>
<ul>
<li><p><a class="post-section-overview" href="#heading-tcpip">TCP/IP</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-ssh-connection-process">The SSH Connection Process</a></p>
</li>
</ul>
<ol start="3">
<li><a class="post-section-overview" href="#heading-how-to-use-ssh-in-windows">How to Use SSH in Windows</a></li>
</ol>
<ul>
<li><p><a class="post-section-overview" href="#heading-windows-powershell-or-command-prompt">Windows PowerShell or Command Prompt</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-windows-subsystem-for-linux-wsl">Windows Subsystem for Linux (WSL)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-third-party-ssh-clients-for-example-putty">Third-Party SSH Clients (for example, PuTTY)</a></p>
</li>
</ul>
<ol start="4">
<li><a class="post-section-overview" href="#heading-how-to-use-ssh-in-windows-to-connect-to-github">How to Use SSH In Windows To Connect To GitHub</a></li>
</ol>
<ul>
<li><p><a class="post-section-overview" href="#heading-install-through-windows-optional-features">Install Through Windows Optional Features</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-download-and-install-from-github">Download And Install From Github</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-generate-ssh-keys">How To Generate SSH Keys</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-add-the-public-key-to-github">How To Add The Public Key To GitHub</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-testing-the-ssh-connection">Testing The SSH Connection</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-cloning-a-repository-using-ssh">Cloning A Repository Using SSH</a></p>
</li>
</ul>
<ol start="5">
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ol>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>Before you begin this tutorial, ensure you have the following:</p>
<ul>
<li><p><strong>Basic Understanding of Command Line</strong>: You should be familiar with using the command line interface (CLI) on Windows, including how to open PowerShell or Command Prompt.</p>
</li>
<li><p><strong>Windows Operating System</strong>: This tutorial is specifically tailored for users running Windows 10 or later versions.</p>
</li>
<li><p><strong>OpenSSH Client Installed</strong>: Ensure that you have the OpenSSH client installed on your system. You can check this by typing <code>ssh</code> in your command line interface.</p>
</li>
<li><p><strong>GitHub Account</strong>: You’ll need a GitHub for testing SSH connections and managing repositories.</p>
</li>
<li><p><strong>Text Editor</strong>: You’ll also need a code editor (like Visual Studio Code, Notepad++, or similar) to edit configuration files if needed.</p>
</li>
</ul>
<h1 id="heading-what-is-ssh">What is SSH?</h1>
<p><strong>SSH</strong> stands for secure shell (protocol). The secure shell protocol is a cryptographic network protocol for operating network services securely over an unsecured network.</p>
<p>In simpler terms, <strong>SSH</strong> is a way to safely use services on a network, like accessing a remote computer, even when the network itself isn’t fully secure. It protects your data and communications by scrambling (encrypting) everything, so no one can eavesdrop or tamper with it, even if they intercept it.</p>
<p>This is especially useful when connecting to services like GitHub, where you want to securely manage code on a remote server.</p>
<h3 id="heading-how-does-the-secure-shell-protocol-work">How Does The Secure Shell Protocol Work?</h3>
<p>SSH runs on the <a target="_blank" href="https://www.freecodecamp.org/news/what-is-tcp-ip-layers-and-protocols-explained/">TCP/IP set of rules</a> that computers use to communicate over the internet.</p>
<h3 id="heading-tcpip">TCP/IP</h3>
<p><strong>TCP</strong> stands for <strong>Transmission Control Protocol</strong>. It’s one of the core protocols in the <strong>TCP/IP suite</strong>, which is used to send data over the internet. The <strong>IP</strong> stands for <strong>Internet Protocol</strong>. It's part of the TCP/IP set of rules also, and its job is to guide packets of data to the right destination on the internet.</p>
<p>You can read more about the TCP/IP protocol <a target="_blank" href="https://www.cloudflare.com/learning/ddos/glossary/tcp-ip/">here</a> if you’d like to go deeper.</p>
<h3 id="heading-the-ssh-connection-process">The SSH Connection Process</h3>
<p>The <strong>Secure Shell protocol</strong> operates by establishing a secure connection between a client (your local machine) and a remote server.</p>
<p>First, the client initiates the connection by specifying the server's address (IP or domain) and login credentials. During the authentication phase, the server verifies the identity of the client, typically using a password or, more securely, SSH keys. These are a pair consisting of a private key stored on the client and a public key on the server.</p>
<p>Once authenticated, SSH encrypts all data transferred between the client and the server, ensuring confidentiality and integrity. This secure channel allows the client to execute commands, transfer files, and manage the server remotely as if physically present while safeguarding the data from potential interception or tampering.</p>
<p><strong>IP</strong> is responsible for addressing and routing the initial connection request from the client to the server. It ensures that the request, which includes the server's address, is sent to the correct destination.</p>
<p>Once the SSH connection request reaches the server, <strong>TCP</strong> establishes a reliable communication channel. It manages data transmission between the client and the server, ensuring that all packets are delivered accurately and in the correct order.</p>
<p>During the SSH session, <strong>TCP</strong> ensures that data <a target="_blank" href="https://www.cloudflare.com/learning/network-layer/what-is-a-packet/">packets</a> are correctly transmitted and reassembled, while <strong>IP</strong> handles the addressing. SSH then uses this secure and reliable channel to authenticate the client, encrypt all transferred data, and maintain a secure connection. This allows remote management and file transfer with confidentiality and integrity.</p>
<h2 id="heading-how-to-use-ssh-in-windows">How to Use SSH in Windows</h2>
<p>Windows provides a few different ways to use SSH:</p>
<h3 id="heading-windows-powershell-or-command-prompt"><strong>Windows PowerShell or Command Prompt</strong></h3>
<p>Windows comes with a built-in OpenSSH client. You can access this by opening PowerShell or Command Prompt and typing <code>ssh</code> This method is simple and requires no additional software.</p>
<h3 id="heading-windows-subsystem-for-linux-wsl"><strong>Windows Subsystem for Linux (WSL)</strong></h3>
<p>You can enable Windows Subsystem for Linux to run a Linux distribution directly on your Windows PC. Many Linux distros come with OpenSSH pre-installed, allowing you to use <code>ssh</code> commands from the Linux terminal. This method is great if you prefer a Linux-like environment.</p>
<h3 id="heading-third-party-ssh-clients-for-example-putty"><strong>Third-Party SSH Clients (for example, PuTTY)</strong></h3>
<p>If you prefer a standalone application, tools like PuTTY offer a graphical interface to manage SSH connections. PuTTY is widely used for connecting to servers and supports advanced options like saving connection profiles.</p>
<p>Windows 10 and later versions come with a native OpenSSH client, which allows you to securely connect to remote systems over an SSH (Secure Shell) connection.</p>
<h2 id="heading-how-to-use-ssh-in-windows-to-connect-to-github">How to Use SSH in Windows to Connect to GitHub</h2>
<p>If you're using Windows 10 or a later version, you can take advantage of the built-in SSH capabilities.</p>
<p>To get started, open your Windows Terminal or PowerShell, preferably as an administrator. In the command line interface, you can check if SSH is installed by typing the command <code>ssh</code>. This will confirm if the SSH client is available on your system.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727215416889/9985624e-ffe6-4aff-9e58-2fe3e6b36f26.png" alt="ssh cli command result, in this case a positive one that ssh is installed on the system" class="image--center mx-auto" width="620" height="157" loading="lazy"></p>
<p>If you got the above image, it means SSH is available on your local system.</p>
<p>The first thing you'll need to set up an SSH connection is a pair of SSH keys – a public key and a private key. These are typically located in the <code>.ssh</code> directory in your home directory if generated already.</p>
<p>On Windows, your home directory is usually <code>C:\Users\owner\.ssh</code>. This is where you will find your SSH key files if they've already been generated.</p>
<p>You can easily install OpenSSH on your Windows system. There are a couple of ways to do this:</p>
<h3 id="heading-install-through-windows-optional-features">Install Through Windows Optional Features</h3>
<ol>
<li><p>Open the Windows Start menu and type "optional features" in the search bar.</p>
</li>
<li><p>Click on "Add or remove Windows optional features" to open the Optional Features window.</p>
</li>
<li><p>In the Optional Features window, scroll down and find the "OpenSSH Client" option.</p>
</li>
<li><p>Check the box next to it and click the "Install" button at the bottom to install the OpenSSH client.</p>
</li>
</ol>
<h3 id="heading-download-and-install-from-github">Download and Install from GitHub</h3>
<ol>
<li><p>Visit the GitHub repository for the Win32-OpenSSH (32-bit) or Win64-OpenSSH (64-bit) release, depending on your Windows version:</p>
<ul>
<li><p>32-bit: <a target="_blank" href="https://github.com/PowerShell/Win32-OpenShell/releases">https://github.com/PowerShell/Win32-OpenShell/releases</a></p>
</li>
<li><p>64-bit: <a target="_blank" href="https://github.com/PowerShell/Win64-OpenShell/releases">https://github.com/PowerShell/Win64-OpenShell/releases</a></p>
</li>
</ul>
</li>
<li><p>Download the latest .msi installer file that matches your Windows architecture.</p>
</li>
<li><p>Run the .msi installer to install the OpenSSH client on your system.</p>
</li>
</ol>
<p>After installing OpenSSH, you can now generate SSH keys by opening the Windows Terminal or PowerShell and running the <code>ssh-keygen</code> command. This will walk you through the process of creating a new public-private key pair that you can use to authenticate your SSH connections, such as to your GitHub account.</p>
<p>The public key can then be added to your GitHub account settings, allowing you to connect to your repositories using the SSH protocol instead of HTTPS. Remember to keep your private key safe and secure, as it provides access to your GitHub account.</p>
<p>By installing OpenSSH, you've set up the necessary foundation to work with SSH keys and establish secure connections to remote systems and services like GitHub.</p>
<p>Now you can check if the OpenSSH server is running by accessing the Windows Services utility. To do this, press the Windows key + R to open the Run dialog, then input "services.msc" and press Enter. This will open the services manager.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727217366905/348ece20-432c-443e-951c-5c61ae4c7b94.png" alt="a windows prompt, generated by clicking &quot;windows + r&quot;" class="image--center mx-auto" width="395" height="197" loading="lazy"></p>
<p>The services manager:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727217489636/dffca024-3cb2-4b2b-8a03-fb4a2b5cc629.png" alt="The services manager generated after clicking &quot;windows + r&quot;" class="image--center mx-auto" width="796" height="563" loading="lazy"></p>
<p>Scroll and look for the openSSH SSH server:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727217823859/accbf838-e6cb-491a-ad1a-affa0dd59230.png" alt="this is image indicates that openSSH server is runing in the system, automatically as far as the system is powered on " class="image--center mx-auto" width="451" height="19" loading="lazy"></p>
<p>If the OpenSSH Server service is running in the Services window, it means that the OpenSSH server component is properly set up on your Windows system. This is an important first step in enabling secure SSH connections.</p>
<p>To ensure the OpenSSH server starts automatically whenever your PC is turned on, you can further configure the service's startup type. In the Services window, right-click on the "OpenSSH Server" service and select "Properties."</p>
<p>In the service properties, look for the "Startup type" dropdown and select "Automatic." This will ensure the OpenSSH Server service starts up automatically whenever your computer is powered on, rather than requiring you to manually start it each time.</p>
<p>By setting the OpenSSH Server service to start automatically, you can be confident that the server will be ready to accept incoming SSH connections at all times, without needing to remember to start it manually. This streamlines the process of using SSH-based authentication and remote access on your Windows machine.</p>
<p>Remember, having the OpenSSH Server service running and set to start automatically is just the first step. You'll still need to generate SSH keys and configure your GitHub account (or other services) to use the public key for authentication. But this initial setup of the OpenSSH server lays the foundation for seamless SSH usage going forward.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727218121688/a902b304-8103-49a5-8852-7094b4f70d5a.png" alt="opened the openSSH on the services manager" class="image--center mx-auto" width="901" height="584" loading="lazy"></p>
<p>Now that you've confirmed the OpenSSH Server is running on your Windows system, the next step is to ensure it can communicate through the Windows Firewall. The easiest way to do this is by using a PowerShell command.</p>
<p>Open PowerShell as an administrator and run the following command:</p>
<pre><code class="lang-plaintext">New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH SSH Server' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 -Program "C:\Program Files\OpenSSH\sshd.exe"
</code></pre>
<p>This PowerShell command will create a new firewall rule that allows inbound TCP traffic on port 22 (the default SSH port) for the OpenSSH Server executable located at "C:\Program Files\OpenSSH\sshd.exe".</p>
<p>Here's a breakdown of the different parameters used in the command:</p>
<ul>
<li><p><code>-Name sshd</code>: Assigns the name "sshd" to the new firewall rule.</p>
</li>
<li><p><code>-DisplayName 'OpenSSH SSH Server'</code>: Provides a descriptive display name for the rule.</p>
</li>
<li><p><code>-Enabled True</code>: Ensures the rule is active and enabled.</p>
</li>
<li><p><code>-Direction Inbound</code>: Specifies that the rule applies to inbound network traffic.</p>
</li>
<li><p><code>-Protocol TCP</code>: Configures the rule to allow TCP protocol connections.</p>
</li>
<li><p><code>-Action Allow</code>: Instructs the firewall to allow the specified traffic.</p>
</li>
<li><p><code>-LocalPort 22</code>: Sets the local port to 22, which is the default SSH port.</p>
</li>
<li><p><code>-Program "C:\Program Files\OpenSSH\sshd.exe"</code>: Identifies the specific program (the OpenSSH Server executable) that the rule should apply to.</p>
</li>
</ul>
<p>By running this PowerShell command, you're creating a dedicated firewall rule that permits the OpenSSH Server to communicate through the Windows Firewall, enabling you to establish secure SSH connections to your system.</p>
<p>Remember, it's always a good practice to review your firewall settings periodically, especially if you make changes to your network configuration or want to refine access to the OpenSSH Server further.</p>
<p>If successful, you should get this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727219301264/fb58d5ce-f8cf-49d2-9b56-6f1571c08652.png" alt=" dedicated firewall rule that permits the OpenSSH Server to communicate through the Windows Firewall" class="image--center mx-auto" width="1364" height="435" loading="lazy"></p>
<h4 id="heading-summary-of-the-above-cli-response">Summary of the above CLI response:</h4>
<ul>
<li><p><strong>Rule Name</strong>: sshd</p>
</li>
<li><p><strong>Display Name</strong>: OpenSSH SSH Server</p>
</li>
<li><p><strong>Direction</strong>: Inbound</p>
</li>
<li><p><strong>Action</strong>: Allow</p>
</li>
<li><p><strong>Enabled</strong>: True</p>
</li>
<li><p><strong>Profile</strong>: Any</p>
</li>
</ul>
<p>The rule is designed to allow inbound traffic, enabling external clients to connect to the server. The "Enabled" status confirms that the rule is currently active, while the "Profile" set to "Any" indicates that it applies to all network types, including public, private, and domain.</p>
<h4 id="heading-security-policies">Security Policies:</h4>
<ul>
<li><p><strong>Edge Traversal Policy</strong>: Block</p>
</li>
<li><p><strong>Loose Source Mapping</strong>: False</p>
</li>
<li><p><strong>Local Only Mapping</strong>: False</p>
</li>
</ul>
<p>The "EdgeTraversalPolicy" is configured to "Block," preventing traffic from traversing the network boundary, specifically disallowing connections from public networks to private ones. This helps enhance security by mitigating potential vulnerabilities.</p>
<p>The settings for "LooseSourceMapping" and "LocalOnlyMapping" are both set to false, ensuring that only direct connections are allowed without additional mapping.</p>
<h4 id="heading-status-and-enforcement">Status and Enforcement:</h4>
<ul>
<li><p><strong>Primary Status</strong>: OK</p>
</li>
<li><p><strong>Status</strong>: The rule was parsed successfully from the store.</p>
</li>
<li><p><strong>Enforcement Status</strong>: NotApplicable</p>
</li>
<li><p><strong>Policy Store Source</strong>: PersistentStore</p>
</li>
<li><p><strong>Policy Store Source Type</strong>: Local</p>
</li>
</ul>
<p>The "Status" field confirms that the rule has been successfully parsed from the policy store, indicating no configuration issues. The "EnforcementStatus" marked as "NotApplicable" suggests there are no restrictions that would prevent the rule from being enforced.</p>
<p>Remember, to set up an SSH connection we need a pair of SSH keys – a public key and a private key. Let’s see how to do that now.</p>
<h3 id="heading-how-to-generate-ssh-keys">How to Generate SSH Keys</h3>
<ul>
<li><p>Open your Windows Terminal or PowerShell.</p>
</li>
<li><p>Run the command <code>ssh-keygen</code> to generate a new SSH key pair.</p>
</li>
<li><p>Follow the prompts to specify the save location and passphrase (optional) for your keys.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727220068539/7ee02096-da9e-4a26-8da8-106ec2dcefee.png" alt="cli command for generating ssh keys and its response" class="image--center mx-auto" width="698" height="362" loading="lazy"></p>
<p>You will get what you see in the above image if you’re successful.</p>
<p>The public key will be saved as <code>id_</code><a target="_blank" href="http://rsa.pub"><code>rsa.pub</code></a> in the <code>.ssh</code> directory of your user's home folder (for example, <code>C:\Users\you\.ssh\id_</code><a target="_blank" href="http://rsa.pub"><code>rsa.pub</code></a>).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727220167279/b04fed4a-17d1-49e6-ad34-d5cb41692d13.png" alt="viewing the private and public ky oon our local system in our home-directory/.ssh" class="image--center mx-auto" width="766" height="171" loading="lazy"></p>
<h3 id="heading-how-to-add-the-public-key-to-github">How to Add the Public Key to GitHub</h3>
<ul>
<li><p>Log in to your GitHub account and go to your account settings.</p>
</li>
<li><p>Navigate to the "SSH and GPG keys" section.</p>
</li>
<li><p>Click on the "New SSH key" button. Give your key a descriptive title, and then copy the contents of the <code>id_</code><a target="_blank" href="http://rsa.pub"><code>rsa.pub</code></a> file (your public key) into the "Key" field.</p>
</li>
<li><p>Click "Add SSH key" to save the new key.</p>
</li>
</ul>
<h3 id="heading-testing-the-ssh-connection">Testing the SSH Connection</h3>
<p>In your Windows Terminal or PowerShell, execute the following command to test your SSH connection to GitHub:</p>
<pre><code class="lang-plaintext">bashCopy codessh -T git@github.com
</code></pre>
<p>If prompted, enter your passphrase if you set one during the key generation process. If you did not set a passphrase, simply type "yes" when asked for a response to the handshake.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727220975104/6ed54e15-00a9-4cad-b95e-3424be855596.png" alt="6ed54e15-00a9-4cad-b95e-3424be855596" class="image--center mx-auto" width="680" height="93" loading="lazy"></p>
<p>If the connection is successful, you should see a message like "Hi username! You've successfully authenticated, but GitHub does not provide shell access."</p>
<p>You can solve this by following the process <a target="_blank" href="https://gist.github.com/bsara/5c4d90db3016814a3d2fe38d314f9c23">here</a>.</p>
<h3 id="heading-cloning-a-repository-using-ssh">Cloning a Repository Using SSH</h3>
<p>Navigate to one of your GitHub repositories and copy the SSH clone URL, which typically starts with <a target="_blank" href="mailto:git@github.com"><code>git@github.com</code></a>:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727222441040/926444a1-bdf8-4f33-980c-0c2c87691a6b.png" alt="ssh link to clone a github repo" class="image--center mx-auto" width="208" height="135" loading="lazy"></p>
<p>In your local terminal, run the command <code>git clone</code> <a target="_blank" href="mailto:git@github.com"><code>git@github.com</code></a><code>:username/repository.git</code> to clone the repository using the SSH protocol.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>You now have SSH working between your Windows computer and your GitHub account. This means you can work with your GitHub projects more easily and securely.</p>
<h3 id="heading-why-ssh-is-cool">Why SSH is Cool:</h3>
<ol>
<li><p>It's super secure. SSH scrambles your data so others can't snoop on it.</p>
</li>
<li><p>It's convenient. No more typing passwords all the time!</p>
</li>
<li><p>It's flexible. You can use it for more than just GitHub.</p>
</li>
<li><p>You can have different "keys" for different projects.</p>
</li>
<li><p>It works well with automatic coding tools.</p>
</li>
</ol>
<p>But it’s not perfect:</p>
<ol>
<li><p>Keeping track of many SSH keys can be a headache.</p>
</li>
<li><p>If someone gets your private key, they could access your stuff.</p>
</li>
<li><p>Setting it up the first time can be tricky.</p>
</li>
<li><p>You need to remember to change your keys yourself for extra safety.</p>
</li>
<li><p>Some networks might block SSH, which can be annoying.</p>
</li>
</ol>
<p>Remember to keep your private SSH key safe. It's like a special password for your GitHub account, so guard it well.</p>
<p>Even with these small downsides, SSH is still awesome for most coders. You are now all set to work on your GitHub projects more easily and safely. Have fun with your improved coding setup, and keep learning about ways to keep your work secure.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How AI Tools Can Help You Reuse Code ]]>
                </title>
                <description>
                    <![CDATA[ Reusing code is an important part of software development. Instead of writing the same code again and again, developers can save time and effort by using code that already works. This not only speeds up the development process but also helps improve ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/tools-for-code-reuse/</link>
                <guid isPermaLink="false">66f46fb236ee3dad69878324</guid>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Programming Tips ]]>
                    </category>
                
                    <category>
                        <![CDATA[ optimization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oluwadamisi Samuel ]]>
                </dc:creator>
                <pubDate>Wed, 25 Sep 2024 20:16:50 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727102263215/bcd245a1-4e4e-4563-8f6c-1715b5f8ed13.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Reusing code is an important part of software development. Instead of writing the same code again and again, developers can save time and effort by using code that already works. This not only speeds up the development process but also helps improve the quality of the final product.</p>
<p>There are several popular ways to create reusable code, and each has its strengths and weaknesses. But they all share a common goal: making it easier for you to avoid reinventing the wheel.</p>
<p>And now, with the improvements in AI, you can take advantage of the available technology to make the development process easier, faster, and more efficient.</p>
<p>In this article, we’ll explore the benefits of code reuse, discuss popular tools for finding reusable code (which, in my opinion, are the best tools to use), and examine how different solutions can help you work more efficiently.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-the-benefits-of-code-reuse">Benefits of Code Reuse</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-popular-options-for-code-reuse">Popular Options for Code Reuse</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-the-benefits-of-code-reuse">The Benefits of Code Reuse</h2>
<p>Reusing code brings many advantages that make software development faster and better. Using code that already works helps you avoid doing the same tasks again and again. It also helps you follow the “DRY” principle, and lets you focus on more important parts of your projects.</p>
<h3 id="heading-time-savings-and-faster-development-cycles">Time Savings and Faster Development Cycles</h3>
<p>A key benefit of reusing code is the amount of time it saves. You no longer need to spend hours rewriting common functions or tasks that have already been solved. This allows you to quickly add these pieces to new projects and spend more time building new features that make your product unique.</p>
<h3 id="heading-improved-code-quality">Improved Code Quality</h3>
<p>Code that has already been tested and proven tends to have fewer mistakes. Using reusable code that has been checked before means you can trust that it will work properly, reducing the chances of bugs and errors in the final product.</p>
<h3 id="heading-increased-consistency">Increased Consistency</h3>
<p>Reusing code helps create consistency across different projects. The same functions and logic are applied in every project, ensuring everything works in a similar way. This makes the codebase easier to understand and maintain.</p>
<h3 id="heading-enhanced-collaboration-and-knowledge-sharing">Enhanced Collaboration and Knowledge Sharing</h3>
<p>When teams share and reuse components, collaboration becomes easier. Team members can work together more efficiently, using familiar code pieces. This also helps spread knowledge across the team, as everyone benefits from understanding and using the same code.</p>
<h3 id="heading-cost-efficiency">Cost Efficiency</h3>
<p>Reusing existing solutions helps reduce costs. Since you spend less time creating new code from scratch, the development process becomes cheaper. This can also lead to faster project completion, which saves money in the long run.</p>
<h2 id="heading-popular-options-for-code-reuse">Popular Options for Code Reuse</h2>
<p>There are several tools and platforms that developers rely on to find reuseable code. There are widely used options like Google, StackOverflow, and documentation. And on the other hand there are newer AI tools like ChatGPT, Gemini, and Codiumate to mention a few.</p>
<p>Each option has its own strengths and weaknesses, but they all aim to make coding easier and faster by offering pre-existing solutions. Below, we’ll look at some of the most popular options and compare how they help with code reuse.</p>
<h3 id="heading-google-search">Google Search</h3>
<p>Google is one of the most widely-used tools for finding code snippets and tutorials. Developers often search for specific solutions, reading through blog posts, forums, and official documentation to find what they need.</p>
<p><strong>Advantages</strong>:</p>
<ul>
<li><p>Access to a vast amount of information, tutorials, and resources across the web.</p>
</li>
<li><p>Great for finding niche solutions or specific examples.</p>
</li>
<li><p>Helpful for discovering documentation and learning new technologies.</p>
</li>
</ul>
<p><strong>Disadvantages</strong>:</p>
<ul>
<li><p>Finding the right solution often involves sifting through a lot of content.</p>
</li>
<li><p>Not all resources are trustworthy or up-to-date.</p>
</li>
<li><p>It can take longer to find specific, reusable code compared to other platforms.</p>
</li>
</ul>
<p><strong>Google in Action</strong>: A quick goggle search will show results comprised of articles and publications related to your question. Going through these articles might help with the exact code you are searching for.</p>
<h3 id="heading-stack-overflow">Stack Overflow</h3>
<p>Stack Overflow is a popular online forum where developers ask questions and share solutions to programming problems, and it’s been a reliable friend to developers over the years.</p>
<p>It has a massive library of answers and code snippets provided by the developer community. It also now has an AI feature which we’ll discuss in the next section. You get access to different solutions to the same problem provided by developers.</p>
<p><strong>Advantages</strong>:</p>
<ul>
<li><p>Large collection of real-world code examples and solutions.</p>
</li>
<li><p>Answers are often reviewed and voted on by other users, making it easier to find high-quality code.</p>
</li>
<li><p>Covers a wide range of coding topics and issues.</p>
</li>
</ul>
<p><strong>Disadvantages</strong>:</p>
<ul>
<li><p>Requires manual searching, which can be time-consuming.</p>
</li>
<li><p>Some solutions may be outdated or not relevant to modern development practices.</p>
</li>
<li><p>It’s not always easy to find code that fits perfectly with your specific project needs.</p>
</li>
</ul>
<p><strong>StackOverflow in Action</strong>: You can just open up the site in your browser and search what ever question you need and the highest rated answers will be provided:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727287523667/2d476910-327a-42b2-a52f-6247e3b0e1f9.png" alt="StackOverflow search results example" class="image--center mx-auto" width="1856" height="1320" loading="lazy"></p>
<h3 id="heading-multi-purpose-ai-tools-like-chatgpt-and-gemini">Multi-Purpose AI Tools (like ChatGPT and Gemini)</h3>
<p>ChatGPT and Gemini are AI tools that help developers by providing code snippets and answering programming questions. They are known for their versatility, supporting a wide range of programming languages and offering quick suggestions on how to solve coding problems.</p>
<p>These tools are growing each day and have truly revolutionised the tech space. They can provide code snippets quickly and with sources.</p>
<p><strong>Advantages</strong>:</p>
<ul>
<li><p>Can generate code for various languages and frameworks.</p>
</li>
<li><p>Provides quick explanations and examples and sources.</p>
</li>
<li><p>Easy to use for beginners and experienced developers alike.</p>
</li>
</ul>
<p><strong>Disadvantages</strong>:</p>
<ul>
<li><p>These AI toools are general-purpose, so they may not always provide the most optimized or accurate code for complex tasks and sometimes struggle with context.</p>
</li>
<li><p>Since they’re not focused solely on coding, they might miss important details or suggest outdated solutions.</p>
</li>
</ul>
<p><strong>ChatGPT in Action</strong>: Let’s see ChatGPT in action with a simple question and the sample code it gives us:</p>
<p><strong>Question:</strong> “Can you generate a function to validate form inputs in JavaScript?"</p>
<p><strong>Response:</strong> Here’s a reusable JavaScript function to validate form inputs. This function will validate if inputs are not empty, and optionally check for conditions such as valid email addresses, minimum character length, and numeric validation. You can expand it depending on the form requirements.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validateForm</span>(<span class="hljs-params">inputs</span>) </span>{
  <span class="hljs-keyword">let</span> errors = {};

  inputs.forEach(<span class="hljs-function"><span class="hljs-params">input</span> =&gt;</span> {
    <span class="hljs-keyword">const</span> { name, value, type, required, minLength, pattern } = input;

    <span class="hljs-comment">// Check if the input is required and empty</span>
    <span class="hljs-keyword">if</span> (required &amp;&amp; !value) {
      errors[name] = <span class="hljs-string">`<span class="hljs-subst">${name}</span> is required`</span>;
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-comment">// Check for minimum length</span>
    <span class="hljs-keyword">if</span> (minLength &amp;&amp; value.length &lt; minLength) {
      errors[name] = <span class="hljs-string">`<span class="hljs-subst">${name}</span> must be at least <span class="hljs-subst">${minLength}</span> characters`</span>;
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-comment">// Check for valid email format</span>
    <span class="hljs-keyword">if</span> (type === <span class="hljs-string">'email'</span> &amp;&amp; !<span class="hljs-regexp">/\S+@\S+\.\S+/</span>.test(value)) {
      errors[name] = <span class="hljs-string">'Invalid email address'</span>;
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-comment">// Check if the input matches the specified pattern (e.g., phone number)</span>
    <span class="hljs-keyword">if</span> (pattern &amp;&amp; !<span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(pattern).test(value)) {
      errors[name] = <span class="hljs-string">`<span class="hljs-subst">${name}</span> is invalid`</span>;
      <span class="hljs-keyword">return</span>;
    }
  });

  <span class="hljs-keyword">return</span> <span class="hljs-built_in">Object</span>.keys(errors).length ? errors : <span class="hljs-literal">true</span>;
}

<span class="hljs-comment">// Example usage:</span>
<span class="hljs-keyword">const</span> inputs = [
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'username'</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">'john_doe'</span>, <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">minLength</span>: <span class="hljs-number">5</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'email'</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">'john@example'</span>, <span class="hljs-attr">type</span>: <span class="hljs-string">'email'</span>, <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span> },
  { <span class="hljs-attr">name</span>: <span class="hljs-string">'password'</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">'1234'</span>, <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">minLength</span>: <span class="hljs-number">6</span> },
];

<span class="hljs-keyword">const</span> validation = validateForm(inputs);
<span class="hljs-built_in">console</span>.log(validation);
</code></pre>
<p>This response will save you the trouble of thinking about the logic and still gives space for customization. Just make sure to test the code to make sure it works for your purposes.</p>
<h3 id="heading-overflow-ai-from-stack-overflow">Overflow AI (from Stack Overflow)</h3>
<p>Overflow AI is a generative AI tool integrated into the Stack Overflow platform where users can ask questions in natural language and receive summarized answers. The answers include proper citations for existing content from Stack Overflow’s massive library.</p>
<p>Overflow AI can provide code snippets and solutions to your problems using the highest rated answers. Just keep in mind that there doesn’t appear to be a free version at the moment, so you may have to pay for the service.</p>
<p><strong>Advantages</strong>:</p>
<ul>
<li><p>Access to Stack Overflow’s large collection of real-world code examples and solutions.</p>
</li>
<li><p>Answers provided are the highest voted answers to your specific question.</p>
</li>
<li><p>Code provided is usually of the highest quality.</p>
</li>
<li><p>It can be integrated into your IDE and Slack platform for teams.</p>
</li>
</ul>
<p><strong>Disadvantages</strong>:</p>
<ul>
<li><p>Some answers may not suit your specific needs for more complex problems or code.</p>
</li>
<li><p>It struggles with context as other multi-purpose AI tools do as there is no way to train it specifically for your project.</p>
</li>
</ul>
<p><strong>OverFlow AI in Action</strong>: OverFlow AI is currently only available for Stack Overflow for Teams Enterprise. Companies are required to have a subscription for their teams.</p>
<h3 id="heading-codiumate">Codiumate</h3>
<p>Codiumate is an open-source AI-powered coding assistant designed specifically to enhance the software development process. It’s trained solely for the purpose of assisting developers by providing high quality and reusable code, iterative tests, PR reviews, and code completion.</p>
<p>It also has a chat feature which lets you ask questions. But the most impressive feature it has, in my view, is the option to input your entire codebase or chunks of it so that it has context for the code you need from it.</p>
<p>When it comes to reusing code effectively, having a tool specifically designed for that purpose makes all the difference. And it’s great that Codiumate is an open-source tool, too.</p>
<h4 id="heading-advantages">Advantages:</h4>
<ul>
<li><p>Codiumate is specialized. While other tools like ChatGPT are useful for many tasks, Codiumate’s focus allows it to deliver more precise and relevant recommendations for code reuse.</p>
</li>
<li><p>It can scan large codebases quickly, identifying opportunities to reuse code, and offering seamless integration options.</p>
</li>
<li><p>It possesses features like automatic test creation and real-time bug detection.</p>
</li>
<li><p>It has smart code completion, a coding assistant, and a PR-agent for Pull Request reviews(chrome extension) which makes it a one-stop shop.</p>
</li>
</ul>
<h4 id="heading-limitations">Limitations:</h4>
<ul>
<li><p>As an open-source tool, Codiumate may require some initial setup or customization to fit your specific development environments. This can take a little extra time upfront, especially for developers who aren't familiar with the tool. But once it's integrated, the time savings and improvements to code quality make it well worth the effort. <a target="_blank" href="https://codiumate-docs.codium.ai/installation/">You can find the link to setup here.</a></p>
</li>
<li><p>Since Codiumate is designed specifically for code reuse, it may not be the best tool for handling broader queries outside the realm of coding. If you’re looking for more general advice or help with non-code-related tasks, you might still need to use other tools like ChatGPT. But for focused, efficient code reuse, Codiumate is a great choice.</p>
</li>
</ul>
<p><strong>Codiumate in Action</strong>: Let’s see Codiumate in action:</p>
<p>After setting Codiumate up (which takes about 2 minutes), you can access the chat feature where you can add the entire codebase or highlight part of it for context to get more specific results:</p>
<p>Question: “Can you generate a function to validate form inputs in JavaScript?"</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727285759800/4ff8044f-30b6-49a7-a9ef-ba264f215f33.png" alt="4ff8044f-30b6-49a7-a9ef-ba264f215f33" class="image--center mx-auto" width="994" height="224" loading="lazy"></p>
<p>Response:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727285642041/d56681a4-94f0-410d-ac4d-b4706bc6c363.gif" alt="Codiumate generating the code to validate inputs in JavaScript" class="image--center mx-auto" width="1152" height="648" loading="lazy"></p>
<p>You can expand this function to include more validations as needed, such as checking for special characters in the password, matching passwords, and so on by clicking the “continue this chat” button.</p>
<h3 id="heading-additional-resources">Additional Resources</h3>
<p>There are a ton of AI tools and platforms available with similar features and we’re almost spoiled for choice at this point.</p>
<p>Here are a few additional resources about some of my favorite tools I discussed:</p>
<ul>
<li><p>Read more on <a target="_blank" href="https://codiumate-docs.codium.ai/">Codiumate</a></p>
</li>
<li><p><a target="_blank" href="https://stackoverflow.co/teams/resources/introducing-overflowai/">Read more on OverflowAI</a></p>
</li>
<li><p><a target="_blank" href="https://youtu.be/ui5SdYR7Ivs?si=UEyIeg1UtsXxkk2O">How to reuse code with codiumate (Youtube)</a></p>
</li>
<li><p><a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-ai-to-improve-code-quality/">Using AI to improve code quality</a></p>
</li>
</ul>
<h3 id="heading-conclusion">Conclusion</h3>
<p>Reusing code is a useful practice that makes development faster and easier. It allows developers to focus on creating new features while keeping their projects consistent. Reusing code also helps teams work together better and share knowledge more easily.</p>
<p>There are a ton of AI platforms available like to help with code reuse, and each has its own benefits (and I haven’t covered them all here.</p>
<p>You should take advantage of these AI tools and make your choice based on which tools suits you more. Codiumate and OverflowAI stand out above the rest to me, but the right tool will depend on what you need at that moment.</p>
<p>In the end, AI tools are there to make the development process more streamlined, cheaper, and to ultimately make your life easier as a developer.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What I Learned from The Pragmatic Programmer and The Clean Coder ]]>
                </title>
                <description>
                    <![CDATA[ By Ramón Morcillo I recently finished reading The Pragmatic Programmer 20th Anniversary Edition (2019) and The Clean Coder (2011). You'll find these books on almost every “top 10 Software Development books” list out there.  My goal was to learn, impr... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/lessons-learned-from-the-pragmatic-programmer-and-the-clean-coder/</link>
                <guid isPermaLink="false">66d460c9d14641365a050967</guid>
                
                    <category>
                        <![CDATA[ books ]]>
                    </category>
                
                    <category>
                        <![CDATA[ clean code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ self-improvement  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 24 Nov 2021 16:38:09 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/11/pragmatic_programmer_and_clean_coder_book_covers-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ramón Morcillo</p>
<p>I recently finished reading <em>The Pragmatic Programmer 20th Anniversary Edition</em> (2019) and <em>The Clean Coder</em> (2011). You'll find these books on almost every “top 10 Software Development books” list out there. </p>
<p>My goal was to learn, improve, and get the kind of knowledge that a teacher from mine used to say “<em>can’t be obtained from just reading articles</em>.”</p>
<p>When you are developing software, you may get stuck at a point where YouTube videos and StackOverflow answers don’t help. You end up reaching for the official docs, or the source code of that technology to find the answer. </p>
<p>The same thing happens when you want to understand the subject really deeply. <strong>Articles can sometimes fall short, and reading well-known books is the often best approach.</strong></p>
<p>These books focus not only on how to write code, but on teaching you best practices for developing software and even useful life lessons. I’ll share some lessons I learned from them in this article. </p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li>How to Take Responsibility</li>
<li>Testing is Important</li>
<li>Teamwork Makes the Dream Work</li>
<li>How to Estimate</li>
<li>Tracer Bullet Development</li>
<li>How to Handle Pressure</li>
<li>The Importance of Refactoring</li>
<li>Main Differences Between These Books</li>
<li>Conclusion</li>
<li>Resources</li>
</ul>
<h2 id="heading-how-to-take-responsibility">How to Take Responsibility</h2>
<p>As a software developer, you are responsible for the code you create. You must ensure that it not only works now but will do so in the best possible way for a long time (nothing lasts forever). </p>
<p>The best way to make sure the code won’t fail is by testing it – having automated tests that you run each time you write new lines to be sure everything is still working.</p>
<blockquote>
<p>Take Responsibility. Responsibility is something you actively agree to.
— The Pragmatic Programmer</p>
</blockquote>
<p>Responsibility is not only related to coding, though. You have to <strong>take responsibility for improving yourself</strong> too and get better by scheduling time for it. </p>
<blockquote>
<p>Professionals spend time caring for their profession. Presumably, you became a software developer because you are passionate about software and your desire to be a professional is motivated by that passion.
— The Clean Coder</p>
<p>Your knowledge and experience are your most important day-to-day professional assets.
— The Pragmatic Programmer</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/responsibility.gif" alt="Responsibility" width="600" height="400" loading="lazy"></p>
<h2 id="heading-testing-is-important">Testing is Important</h2>
<p>The importance of testing in software development is so great that both books focus on this topic. </p>
<p>You have to <strong>look at tests as the first users of your code</strong>, so they are the best feedback that guides your coding.</p>
<p>Practice <a target="_blank" href="https://en.wikipedia.org/wiki/Test-driven_development">TDD Test Driven Development</a>. How does it work? Here are its three main steps:</p>
<ol>
<li>Choose a feature to add and write a test that will pass after implementing it. Now, all tests but the new one should pass. </li>
<li>Write the code required to pass it.</li>
<li>Refactor the code and check that all tests still pass.</li>
</ol>
<p>This said, it is important to look at the big picture and not to miss the main goal by writing too many tests.</p>
<blockquote>
<p>It is easy to become seduced by the green "tests passed" message, writing lots of code that doesn’t actually get you closer to a solution.
— The Pragmatic Programmer</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/tests.gif" alt="Tests" width="600" height="400" loading="lazy"></p>
<p>There are three ways of testing: <em>First, During,</em> and <em>Never.</em> First (TDD) is the best one. During is a fallback when First is not useful. And Never is often called “Test Later” but sadly <strong>in most cases Later means Never.</strong></p>
<blockquote>
<p>The need to test first forces you to think about "good design."
— The Clean Coder</p>
</blockquote>
<p>Having tests give you the confidence to refactor code more often because you can check to make sure that the tests still pass after you've made your changes.</p>
<blockquote>
<p>Tests should be run as frequently as possible to provide maximum feedback and to ensure that the system remains continuously clean.
— The Clean Coder</p>
</blockquote>
<p>Use acceptance tests to <em>define when a requirement is done</em> collaborating with the stakeholders.</p>
<p>Developers take the responsibility to ensure that tests are <em>always automated</em> for a simple reason: <strong>cost.</strong></p>
<p>Developers have should have the goal that “QA should find nothing”. You can accomplish this by implementing different kinds of tests, in different measures from unit to exploratory tests.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/the_test_automation_pyramid.png" alt="The Test Automation Pyramid - The Clean Coder" width="600" height="400" loading="lazy"></p>
<h2 id="heading-teamwork-makes-the-dream-work">Teamwork Makes the Dream Work</h2>
<p>When working on a team, you have to be a "team player", communicate frequently, keep an eye out for your teammates, and execute your responsibilities as effectively as possible.</p>
<blockquote>
<p>Good communication is key to avoiding these problems. And by "good" we mean instant and frictionless. Frictionless means it’s easy and low-ceremony to ask questions, share your progress, your problems, your insights and learnings, and to stay aware of what your teammates are doing.
— The Pragmatic Programmer</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/tobias-mrzyk-iuqmGmst5Po-unsplash.jpg" alt="tobias-mrzyk-iuqmGmst5Po-unsplash" width="600" height="400" loading="lazy"></p>
<p>Teams should be <strong>small, less than 10-12 members</strong>, where everyone knows and trusts each other. This team environment is <strong>hard to achieve</strong> therefore once you get it you have to <strong>care for it changing the projects the team works on rather than the members.</strong></p>
<blockquote>
<p>As team size grows, communication paths grow at the rate of O(n^2), where n is the number of team members. On larger teams, communication begins to break down and becomes ineffective.
— The Pragmatic Programmer</p>
<p>To form teams around projects is a foolish approach. Individuals are only on the project for a short time and therefore never learn how to deal with each other. Teams are harder to build than projects. Therefore, it is better to form persistent teams that move together from one project to the next and can take on more than one project at a time.
— The Clean Coder</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/tobias-mrzyk-Px3oXvVXRxc-unsplash.jpg" alt="tobias-mrzyk-Px3oXvVXRxc-unsplash" width="600" height="400" loading="lazy"></p>
<p>Furthermore, great teams will face and solve issues together where each individual will provide their best effort. They <em>get things done as a unit</em>. In the end, they will be known for their performance and quality of work.</p>
<blockquote>
<p>Quality can come only from the individual contributions of all team members. Quality is built in, not bolted on.
— The Pragmatic Programmer</p>
<p>A gelled team can work miracles, anticipate each other, cover for each other, support each other, and demand the best from each other. They make things happen.
— The Clean Coder</p>
<p>Great project teams have a distinct personality. People look forward to meetings with them, because they know that they’ll see a well-prepared performance that makes everyone feel good. The documentation they produce is crisp, accurate, and consistent.
— The Pragmatic Programmer</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/natalie-pedigo-wJK9eTiEZHY-unsplash.jpg" alt="natalie-pedigo-wJK9eTiEZHY-unsplash" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-estimate">How to Estimate</h2>
<p>This lesson, like the majority from both books, is as important in software development as in real life. The more you practice and develop it, the more intuitive will be your ability to determine the feasibility of any task. </p>
<p>First, I want to clarify what <em>estimating</em> means by sharing The Clean Coder's definition of an estimate which refers to it as a <em>probability distribution.</em></p>
<blockquote>
<p>An estimate is not a number. An estimate is a <em>probability distribution,</em> the likelihood of completion.
— The Clean Coder</p>
</blockquote>
<p>To help you understand it, here is a figure of the likelihood of completion of a task for the next 11 days.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/probability_distribution.png" alt="probability_distribution" width="600" height="400" loading="lazy"></p>
<p>One of the basics to make great estimations is to <strong>have proper knowledge of what you are estimating.</strong> </p>
<blockquote>
<p>The first part of any estimation exercise is building an understanding of what’s being asked. You need to have a grasp of the scope of the domain.
— The Pragmatic Programmer</p>
</blockquote>
<p>Don’t estimate alone, <strong>communicate with other people to be as accurate as possible.</strong></p>
<blockquote>
<p>The most important estimation resource you have are the people around you. They can see things that you don’t. They can help you estimate your tasks more accurately than you can estimate them on your own.
— The Clean Coder</p>
<p>A basic estimating trick that always gives good answers: ask someone who’s already done it.
— The Pragmatic Programmer</p>
</blockquote>
<p>When asked for an estimation choose the units that better reflect the accuracy you intend to convey. This Estimation times scale from The Pragmatic Programmer may help you.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Duration</td><td>Quote estimate in</td></tr>
</thead>
<tbody>
<tr>
<td>1–15 days</td><td>Days</td></tr>
<tr>
<td>3–6    weeks</td><td>Weeks</td></tr>
<tr>
<td>8–20    weeks</td><td>Months</td></tr>
<tr>
<td>20+    weeks</td><td>Think hard before giving an estimate</td></tr>
</tbody>
</table>
</div><p>Although Business likes to view estimates as commitments, remember that <strong>an estimate is just a guess therefore no commitment is implied.</strong> </p>
<blockquote>
<p>A commitment is something you must achieve. If you commit to getting something done by a certain date, then you simply have to get it done by that date. Professionals don’t make commitments unless they know they can achieve them. Missing a commitment is an act of dishonesty only slightly less onerous than an overt lie.
— The Clean Coder</p>
</blockquote>
<p>Thus said, to help Business measuring requirements and making appropriate plans, you have to <strong>remove the requirement’s ambiguity before estimating.</strong> Afterwards, <strong>keep them updated about the progress.</strong> </p>
<blockquote>
<p>The trick to managing lateness is early detection and transparency. Regularly measure your progress against your goal. Be as honest as you can about all dates. Do not incorporate hope into your estimates!
— The Clean Coder</p>
</blockquote>
<p>Do not reinvent the wheel, use well-known estimation techniques for tasks. Here I made a summary of some techniques mentioned in both books.</p>
<ul>
<li><a target="_blank" href="https://reymon359.github.io/book-sentences/#/The%20Clean%20Coder/index?id=pert">PERT</a></li>
<li><a target="_blank" href="https://reymon359.github.io/book-sentences/#/The%20Clean%20Coder/index?id=wideband-delphi">Wideband Delphi</a></li>
<li><a target="_blank" href="https://reymon359.github.io/book-sentences/#/The%20Clean%20Coder/index?id=flying-fingers">Flying Fingers</a></li>
<li><a target="_blank" href="https://reymon359.github.io/book-sentences/#/The%20Clean%20Coder/index?id=planning-poker">Planning Poker</a></li>
<li><a target="_blank" href="https://reymon359.github.io/book-sentences/#/The%20Clean%20Coder/index?id=affinity-estimation">Affinity Estimation</a></li>
<li><a target="_blank" href="https://reymon359.github.io/book-sentences/#/The%20Clean%20Coder/index?id=trivariate-estimates">Trivariate Estimates</a></li>
<li><a target="_blank" href="https://reymon359.github.io/book-sentences/#/The%20Clean%20Coder/index?id=the-law-of-large-numbers">The Law of Large Numbers</a></li>
</ul>
<p>The more experience you have on a certain project, the better you will estimate its tasks. Therefore don’t worry if the first estimates you make are not as accurate as they could be. It is an incremental process as with every long term goal you want to achieve. </p>
<p>Like one of my favorite quotes states:</p>
<blockquote>
<p>There is only <strong>one</strong> way to <strong>eat an elephant</strong>: a <strong>bite at a time</strong>.
— Desmond Tutu</p>
</blockquote>
<p>However, there is no way you can eat such cuteness:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/elephant.gif" alt="Elephant" width="600" height="400" loading="lazy"></p>
<h2 id="heading-tracer-bullet-development">Tracer Bullet Development</h2>
<p>Tracer bullets are a special kind of bullet used in movies to mark the path they’ve taken as feedback for the shooter to aim better the next time. Therefore, the main goal of Tracer Bullet Development is to "shoot" new features into the project and get quick feedback to "aim" better on the next ones.</p>
<blockquote>
<p>Tracer development is consistent with the idea that a project is never finished: there will always be changes required and functions to add. It is an incremental approach.
— The Pragmatic Programmer</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/tracer_bullets.png" alt="Tracer Bullets. Source: The Pragmatic Programmer" width="600" height="400" loading="lazy"></p>
<p>This method helps developers focus on the main features to be implemented so others can be built on. </p>
<p>In addition, it serves as <strong>proof the architecture is compatible and feasible</strong> by providing a functional and demonstrable skeleton to work from the beginning of the development process.</p>
<blockquote>
<p>Look for the important requirements, the ones that define the system. Look for the areas where you have doubts, and where you see the biggest risks. Then prioritize your development so that these are the first areas you code.
— The Pragmatic Programmer</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/outer-digit-Ys78stblUyY-unsplash.jpg" alt="outer-digit-Ys78stblUyY-unsplash" width="600" height="400" loading="lazy"></p>
<p>Lastly, <strong>Tracer Bullet Development should not be confused with prototyping.</strong> The code from prototypes isn’t supposed to be part of the project, whereas the code from the tracer bullets isn’t thrown away. It works and is improved each iteration with new features.</p>
<blockquote>
<p>Prototyping generates disposable code. Tracer code is lean but complete, and forms part of the skeleton of the final system. Think of prototyping as the reconnaissance and intelligence gathering that takes place before a single tracer bullet is fired.
— The Pragmatic Programmer</p>
</blockquote>
<h2 id="heading-how-to-handle-pressure">How to Handle Pressure</h2>
<p>I liked this one as well, since it helps you outside software development too. Soon or later you will be under pressure, and the best tricks to handling it are to <strong>avoid it when you can, and weather it when you can’t.</strong></p>
<blockquote>
<p>The best way to stay calm under pressure is to avoid the situations that cause pressure.
— The Clean Coder</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/avoiding.gif" alt="Avoiding" width="600" height="400" loading="lazy"></p>
<p>You mainly <strong>avoid it by managing commitments, keeping clean, and following your disciplines.</strong> </p>
<p>The best way to manage commitments is by <em>saying no</em> to those deadlines you aren’t sure you can meet. Keeping clean basically means that you have no mess on your systems, code, and design.</p>
<blockquote>
<p>The way to go fast, and to keep the deadlines at bay, is to stay clean. Professionals do not succumb to the temptation to create a mess in order to move quickly. “Quick and dirty” is an oxymoron. Dirty always means slow!
— The Clean Coder</p>
</blockquote>
<p><strong>Follow disciplines you truly believe in and stick to them all the time</strong> no matter the situation. Crisis times will come, and that’s when you have to pay attention to how you behave. If you follow your disciplines it means you believe in them. </p>
<p>Changing your behavior and not following your disciplines would mean you don’t truly believe in your normal behavior, and you have to shift those disciplines to improve it.</p>
<blockquote>
<p>If you keep your code clean during normal times but make messes in a crisis, then you don’t really believe that messes slow you down. If you pair in a crisis but don’t normally pair, then you believe pairing is more efficient than non-pairing.
— The Clean Coder</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/federico-lancellotti-YBuVjp5Mtrw-unsplash.jpg" alt="federico-lancellotti-YBuVjp5Mtrw-unsplash" width="600" height="400" loading="lazy"></p>
<p>Choose disciplines that you feel comfortable following in a crisis. <em>Then follow them all the time.</em> Following these disciplines is the best way to avoid getting into a crisis. Don’t change your behavior when the crunch comes. If your disciplines are the best way to work, then they should be followed even in the depths of a crisis.</p>
<p>But you can’t always avoid pressure, so you have to learn how to get through it. <strong>You weather it by staying calm, communicating, following your disciplines, and getting help.</strong></p>
<p>To stay calm, <strong>don’t panic,</strong> manage your stress, and think the problem through to find the best possible outcome. Then go for it at a steady pace, <em>like eating an elephant</em>. Make sure you're <strong>communicating</strong> all the time with your team and superiors to let them know when you are in trouble so you can get input and guidance. This way there won’t be any unexpected surprises in the end.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/good_communication_is_the_key_to_success.jpg" alt="Communication is the key" width="600" height="400" loading="lazy"></p>
<blockquote>
<p>Avoid creating surprises. Nothing makes people more angry and less rational than surprises. Surprises multiply the pressure by ten.
— The Clean Coder</p>
</blockquote>
<p>In the same way you relied on your disciplines to avoid pressure, you should also rely on them when the moment gets tough. In fact, these times you have to pay special attention to them and neither question nor abandon them.</p>
<p>The communication tip includes <strong>asking for help</strong> from teammates to pair, superiors, or internet sites and forums. </p>
<p>Don't forget to be there for others too when they are under pressure and need help.</p>
<blockquote>
<p>When the heat is on, find an associate who is willing to pair program with you. You will get done faster, with fewer defects. Your pair partner will help you hold on to your disciplines and keep you from panicking.
— The Clean Coder</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/pairing.gif" alt="pairing" width="600" height="400" loading="lazy"></p>
<h2 id="heading-the-importance-of-refactoring">The Importance of Refactoring</h2>
<p>The term <em>Refactoring</em> is defined by Martin Fowler as a:</p>
<blockquote>
<p>Disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.
— Martin Fowler</p>
</blockquote>
<p>Sometimes you will find code that does not feel right and should be fixed or improved. And you have to keep in mind the best moment to do so is <strong>now</strong>, when you find it.</p>
<p><strong>It is inevitable: a program’s code needs to grow, evolve, and improve.</strong> To do so, you'll need to rethink some decisions, and the code will need to change. So be sure to have it covered with <strong>automated tests</strong> to guarantee that the external behavior does not change.</p>
<blockquote>
<p>Rather than construction, software is more like gardening – it is more organic than concrete. You plant many things in a garden according to an initial plan and conditions. You constantly monitor the health of the garden, and make adjustments as needed.
— The Pragmatic Programmer</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/bobs_burger_gardening.gif" alt="Bob gardening" width="600" height="400" loading="lazy"></p>
<p>When should you refactor the code? Here is a list of situations that qualify:</p>
<ul>
<li>To remove <strong>code duplication.</strong></li>
<li>To make some parts of the code more <strong>orthogonal.</strong></li>
<li>To <strong>update</strong> code and/or documentation that's outdated.</li>
<li>To improve <strong>performance.</strong></li>
</ul>
<p>And here are Martin Fowler's tips on how to refactor without doing more harm than good:</p>
<ol>
<li>Don’t try to refactor and add functionality at the same time.</li>
<li>Make sure you have good tests before you begin refactoring. Run the tests as often as possible.</li>
<li>Take short, deliberate steps: move a field from one class to another, split a method, rename a variable. Refactoring often involves making many localized changes that result in a larger-scale change.</li>
</ol>
<p>The most important thing to keep in mind is that <strong>refactoring is not a certain task, it is a habit</strong>. And, as with most things in life, it is easier to do while the issues are small, as an ongoing activity while coding. </p>
<p><strong>The less you refactor now the greater time you’ll have to invest to fix the problem down the road.</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/cat_refactoring.gif" alt="Cat refactoring" width="600" height="400" loading="lazy"></p>
<blockquote>
<p>Refactoring as "a growth." Removing it requires invasive surgery. You can take it out while it is still small. Or, you could wait while it grows and spreads – but removing it then will be both more expensive and more dangerous. Wait even longer, and you may lose the patient entirely.
— The Pragmatic Programmer</p>
</blockquote>
<h2 id="heading-main-differences-between-these-books">Main Differences Between These Books</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/11/differences.gif" alt="Differences" width="600" height="400" loading="lazy"></p>
<p>I did not want this article to be a comparison – but although these books focus on similar subjects, the content and the way each is narrated are not the same. </p>
<p>Here are the main impressions I got from them that are not related to the content itself. These observations can help you have an idea of what to expect while reading them.</p>
<ul>
<li>The Clean Coder speaks about the developer in a more day by day at work way. It makes references to common situations that are given in such an environment like the relationship with sales or business people, working in a team, or saying no to clients. The developer in the Pragmatic Programmer isn’t really placed in job situations. Rather, it grants an overview of the field, structuring the book on advice: <em>topics and tips</em>, for any situation. </li>
<li>The Clean Coder refers to the figure of the Software Developer as a <em>Professional Programmer</em> while The Pragmatic Programmer uses the totally unexpected term <em>Pragmatic Programmer</em>.</li>
<li>In general terms, The Clean Coder has a more subjective sense since it shares more personal experiences from the author. On the other hand, The Pragmatic Programmer feels more objective, focusing mostly on the advice itself.</li>
<li>The Pragmatic Programmer contains more code examples in different programming languages than the Clean Coder, which helps you understand the concepts discussed.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Keep in mind that what I've discussed here is just my own personal impressions and lessons I got from reading these two books. Each book has much more to offer, and the best thing you can do is read both yourself to form your own opinion and conclusions. </p>
<p>If you are interested in software development and want to get better, you should read both of them. It's worth it – they're very different and each is worth your time. And they'll bring you different knowledge and best practices for your career. </p>
<p>Having said that, if you still want to go the lazy way, I made this <a target="_blank" href="https://github.com/reymon359/book-sentences">open-source project with the core sentences from each book</a>.</p>
<p><a target="_blank" href="https://github.com/reymon359/book-sentences"><img src="https://www.freecodecamp.org/news/content/images/2021/11/book_sentences.png" alt="[Book Sentences Project](https://github.com/reymon359/book-sentences)" width="600" height="400" loading="lazy"></a></p>
<h2 id="heading-resources">Resources</h2>
<p>The main resources are both books, which you can find easily on the internet and <a target="_blank" href="https://github.com/reymon359/book-sentences/">the project</a> where I noted down the sentences I found most important.</p>
<p>I hope you enjoyed this article. You can read it too <a target="_blank" href="https://ramonmorcillo.com/7-lessons-learned-from-the-pragmatic-programmer-and-the-clean-coder/">on my site</a> along with others! If you've got any questions, suggestions, or feedback in general, don't hesitate to reach out on any of the social networks from <a target="_blank" href="https://ramonmorcillo.com/">my site</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Learn Something New Every Day as a Software Developer ]]>
                </title>
                <description>
                    <![CDATA[ As software developers, we must be willing to learn continuously. While it helps us accomplish our day-to-day tasks at work, it is equally important to stay up to date with new technologies and innovations.  After spending 12+ years in software devel... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-something-new-every-day-as-a-software-developer/</link>
                <guid isPermaLink="false">66be000d0b4523e3b8b990a8</guid>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Lifelong Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tapas Adhikary ]]>
                </dc:creator>
                <pubDate>Mon, 25 Jan 2021 17:45:07 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/01/freeCodeCamp-Cover_3.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As software developers, we must be willing to learn continuously. While it helps us accomplish our day-to-day tasks at work, it is equally important to stay up to date with new technologies and innovations. </p>
<p>After spending 12+ years in software development, I've found it challenging to keep learning consistently. But if you identify what you're passionate about and follow a solid learning path, you'll learn new things all the time.</p>
<p>This article will discuss three important areas of developer education that you may find useful in your learning journey. I have been following this path for the last two years and I've seen very positive results.</p>
<h1 id="heading-tldr">TL;DR</h1>
<p>Become a better learner and developer by:</p>
<ul>
<li>Being an active part of the developer community</li>
<li>Starting your own blog</li>
<li>Building side projects</li>
</ul>
<p>This article is all about experience sharing and how to make these things happen. Just chill and read it with an open mind 🧘.</p>
<h1 id="heading-be-an-active-part-of-the-developer-community">Be an Active Part of the Developer Community</h1>
<p>When we focus all our attention on something, learning becomes easy. The challenging part, though, is to know what to learn. </p>
<p>Where should we find help? Is there a better way to solve certain problems? How do we not reinvent the wheel? And finally, how do we make it happen continuously?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/16.png" alt="Image" width="600" height="400" loading="lazy">
<em>Developer Community to grow together</em></p>
<p>Being part of one or more developer communities in your areas of interest helps solve these challenges in a significant way. </p>
<p>Don't worry if you do not have anything to contribute in the early days. Just hang in there and soak up information, connect with like-minded people, observe best practices, and so on. You will eventually contribute, and that comes naturally.</p>
<p>Here are the developer communities, learning platforms, and social media outlets that I've found immensely helpful. Please note that opinions are mine, and some of you may not agree or might want to add more to the list. That's perfectly fine, and you are welcome to do so.</p>
<ul>
<li><a target="_blank" href="https://twitter.com/home"><strong>Twitter</strong></a><strong>:</strong> When it comes to staying relevant with technologies, soft mentoring, and getting quick tips and tricks, Twitter is a great platform. If you don't have one already, create a Twitter account and join the platform. Follow topics that interest you (using hashtags) and people who post about things you want to learn more about to get started.<br>I've had a dormant Twitter account since 2009! I started using it actively a year ago and can tell you how useful it is.</li>
<li><a target="_blank" href="https://www.freecodecamp.org/"><strong>freeCodeCamp</strong></a><strong>:</strong> If you are looking for focused learning, give freeCodeCamp a try. There are thousands of hours of study materials available, and it's free! You should <a target="_blank" href="https://forum.freecodecamp.org/">join the forum</a> to get insights, answers, and solutions. You can earn free verified certifications as well. If you are reading this article, you are probably aware of the freeCodeCamp curriculum already.</li>
<li><a target="_blank" href="https://hashnode.com/"><strong>Hashnode:</strong></a> This is one of the fastest-growing developer communities out there today. Once you join Hashnode, you can follow the tags and community members of your choice to see articles, discussions, and more in your feed. Another USP is that you get a free blogging domain where you can write your articles and publish them.</li>
<li><a target="_blank" href="http://dev.to"><strong>Dev.to</strong></a><strong>:</strong> a mature developer community with many contributors who write articles, discusses topics, and share thoughts. You can follow the topics of your interest to create a personalized feed.</li>
<li><a target="_blank" href="https://daily.dev/"><strong>daily.dev:</strong></a> This is not precisely a community yet, but rather an aggregator of many. It does an excellent job of bringing you a list of hot articles you might be interested in without looking for them. Just install their browser extension, and you are all set to go.</li>
</ul>
<p>Apart from those I mentioned above, <a target="_blank" href="https://www.linkedin.com/">LinkedIn</a>, <a target="_blank" href="https://www.reddit.com/">Reddit</a>, <a target="_blank" href="http://hackernoon.com/">Hackernoon</a>, <a target="_blank" href="https://www.codenewbie.org/">Code Newbie</a>, <a target="_blank" href="https://www.womenwhocode.com/">Women who code</a>, <a target="_blank" href="https://stackoverflow.com/">StackOverflow</a>, and <a target="_blank" href="https://news.ycombinator.com/">Hackernews</a> are other fantastic communities to look out for.</p>
<h1 id="heading-start-your-own-blog-or-something-equivalent">Start Your Own Blog (or Something Equivalent)</h1>
<p>Teaching and sharing knowledge is the best way to gain more knowledge. It is a universal truth that you can not teach a topic well without learning it well. </p>
<p>Having a technology blog (or something like a YouTube channel) can help you participate in the learning-sharing cycle.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/17.png" alt="Image" width="600" height="400" loading="lazy">
<em>Start Blogging</em></p>
<p>My key takeaways from blogging for the last couple of years are:</p>
<ul>
<li>Your research on a topic helps you gain more knowledge about it.</li>
<li>You get better visibility in the developer community by contributing to that community.</li>
<li>You create a series of knowledge bases for yourself that you can refer to or use (maybe as a speaker, in a video, and so on).</li>
<li>If you are a non-English speaker and write your articles in English, it helps you get a better grasp of the language.</li>
<li>You can create a strong portfolio for yourself by mentioning your blog. I found that this is beneficial when you pitch to writing for publications like freeCodeCamp News.</li>
<li>Last but not least, you can earn money from your articles. Some publications pay you per article. You can be a guest writer for certain organization's blogging programs. If you are just getting started with blogging, do not put much emphasis on earning money. Focus on delivering useful content to the community. Then financial opportunities will come naturally.</li>
</ul>
<p>If you are thinking about starting a blog with your own domain, check out <a target="_blank" href="https://hashnode.com/">Hashnode</a>. It has everything you need as a blogging platform, and it is free. If you have an existing domain, you can map that to it too. So give it a try. </p>
<p>Alternatively, you can publish on <a target="_blank" href="http://dev.to/">dev.to</a>, <a target="_blank" href="http://hackernoon.com/">Hackernoon</a>, and other communities I mentioned above. You can also apply to become a writer on <a target="_blank" href="https://www.freecodecamp.org/news/developer-news-style-guide/">freeCodeCamp News</a>.</p>
<h1 id="heading-build-some-side-projects">Build Some Side Projects</h1>
<p>An effective way to polish your learning and fuel your passion is by doing side projects. In many cases, you may not be able to work on any technology you like at work. But no one can stop you from doing a side project using that tech.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/18.png" alt="Image" width="600" height="400" loading="lazy">
<em>Do Side Projects</em></p>
<p>A side project can help you:</p>
<ul>
<li>Live your passion</li>
<li>Generate ideas</li>
<li>Learn new skills</li>
<li>Grow in new areas</li>
<li>Contribute to the open-source community</li>
<li>Earn rewards and money</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/01/Your-Passion.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>So how do you get started? First, you should create <a target="_blank" href="https://github.com/">an account with GitHub</a> (or any other source code repository manager). </p>
<p>Next, you need an idea of what to build. Start small, and plan to do many projects. Try making something that you may want to use. </p>
<p>Then identify what you've learned from it, document it as an article, and publish it.</p>
<h1 id="heading-before-we-go">Before we go</h1>
<p>I hope you've found this article insightful, and that it motivates you to check out these learning areas. I would like to hear from you. Let's connect.</p>
<p>You will find me active on <a target="_blank" href="https://twitter.com/tapasadhikary">Twitter (@tapasadhikary)</a>. Please feel free to follow me. You can read some of the other articles from my <a target="_blank" href="https://blog.greenroots.info/">blog (blog.greenroots.info)</a>. All my side projects are in <a target="_blank" href="https://github.com/atapas">GitHub (atapas)</a>, and they are open-source. Please feel free to try/fork/follow.</p>
<p>You may also like:</p>
<ul>
<li><a target="_blank" href="https://blog.greenroots.info/how-to-find-blog-content-ideas-effortlessly-ckghrjv5200o7rhs1ewn40102">How to find blog content ideas effortlessly?</a></li>
<li><a target="_blank" href="https://blog.greenroots.info/why-do-you-need-to-do-side-projects-as-a-developer-ckhn5m5km05teajs1fvjd7u5f">Why do you need to do Side Projects as A Developer?</a></li>
<li><a target="_blank" href="https://blog.greenroots.info/16-side-project-github-repositories-you-may-find-useful-ckk50hic406quhls1dui2d6sd">16 side project GitHub repositories you may find useful</a></li>
<li><a target="_blank" href="https://blog.greenroots.info/how-to-write-consistently-a-guide-for-technical-writers-ckfndb21c00i1szs1hgoshryn">How to write consistently, a guide for technical writers</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Know When You've Learned Everything You Can From a Programming Problem ]]>
                </title>
                <description>
                    <![CDATA[ By Amy Haddad The answer may seem obvious: you’re done with a problem once you’ve solved it.  That’s how I approached problem-solving when I began learning to code. I was on a problem-solving treadmill: solving as many problems as quickly as possible... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/when-are-you-done-with-a-programming-problem/</link>
                <guid isPermaLink="false">66d45dae33b83c4378a517b8</guid>
                
                    <category>
                        <![CDATA[ productivy ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learn to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Problem Solving ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 22 Jun 2020 20:30:26 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/ashkan-forouzani-m0l9NBCivuk-unsplash-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Amy Haddad</p>
<p>The answer may seem obvious: you’re done with a problem once you’ve solved it. </p>
<p>That’s how I approached problem-solving when I began learning to code. I was on a problem-solving treadmill: solving as many <a target="_blank" href="https://www.freecodecamp.org/news/do-you-solve-programming-problems-or-complete-exercises-the-difference-matters/">problems</a> as quickly as possible.</p>
<p>And why not? There’s no shortage of problems to solve. Besides, don’t you get better by solving more problems? More to the point: what else can you do once you have the answer? As it turns out, quite a bit. The fallacy of my approach soon surfaced. </p>
<p>Although I solved the problem, I didn’t learn much from it. That’s because a few days or weeks later when I tried to re-solve the problem or when I came across a related one, I got really <a target="_blank" href="https://www.freecodecamp.org/news/how-to-get-unstuck/">stuck</a>. Mistakes were made. Concepts were confused. Progress was stalled. </p>
<p>I now realize that getting the solution is only part of the problem-solving process. Then, in the words of a mathematician named George Pólya, it’s time to “look back.”</p>
<h2 id="heading-looking-back">Looking Back</h2>
<p>Pólya writes about the problem-solving process in his book, <em>How to Solve It</em>, through the lens of mathematical problem-solving. But his ideas are applicable to programming. What’s particularly interesting to me is his fourth phase: looking back.</p>
<p>“By looking back at the completed solution, by reconsidering and reexamining the result and the path that led to it, [students] could consolidate their knowledge and develop their ability to solve problems,” Pólya writes.</p>
<p>In some ways, solving a problem is like creating a piece of art. There’s always something more we could do. “We could improve any solution, and, in any case, we can always improve our understanding of the solution,” explains Pólya.</p>
<p>For me, “looking back” is a practice of self-improvement and <a target="_blank" href="https://amymhaddad.com/four-ways-to-learn-programming-topics">learning</a>. The aim is to:</p>
<ul>
<li>Learn from my successes: understand what you wrote and why.</li>
<li>Solidify my learning of new concepts.</li>
<li>See patterns and understand the context for using a particular data structure or algorithm. </li>
</ul>
<p>Consider a basketball player who takes 1,000 shots each day. That sounds admirable. But as he rushes to get the 1,000 shots in, his form gets sloppy. He uses the wrong technique. </p>
<p>He’d benefit more from taking a few hundred shots, then evaluating his performance: watching a video recording of his form, seeing the flaws, and correcting them. Then, he'd hit the court again. </p>
<p>Now he’ll be more informed, since he looked back and evaluated his performance. He’ll practice better.</p>
<p>The same is true with solving problems. The idea isn’t to check a box so you can claim you solved “x” number of problems. Instead it’s doing your best work each time and learning as much as possible along the way. </p>
<p>There are three reasons why looking back matters.</p>
<h3 id="heading-reason-1-see-the-patterns-and-understand-the-context">Reason #1: See the Patterns and Understand the Context</h3>
<p>You’ll see similar patterns over and over again in the problems you solve. </p>
<p>Understand how to use a particular algorithm, like binary search. Train your eye so you know <em>when</em> and <em>how</em> to apply it. So when you encounter a related problem in the future, you’ll be ready. Doing so will save time (and frustration) in the long run.</p>
<h3 id="heading-reason-2-solidify-your-learning">Reason #2: Solidify Your Learning</h3>
<p>Say you used something that’s new to you to solve a problem, like a stack or queue. </p>
<p>Do you really know how to use it again? Do you feel comfortable using a stack in a related problem? Take the time to understand anything new you used so you can use it again in the future.</p>
<h3 id="heading-reason-3-learn-from-your-successes">Reason #3: Learn from Your Successes</h3>
<p>Mathematician Richard Hamming gets to the heart of the matter with this quote from his book, <em>The Art of Doing Science and Engineering.</em></p>
<p>“I regard the study of successes as being basically more important than the study of failures...there are so many ways of being wrong and so few of being right, studying successes is more efficient.”</p>
<p>As programmers, we deal with our fair share of errors. And then (many tries later) we run the program and it works. Now is a great time to put Hamming’s words to practice and study your success. </p>
<p>Do you understand <em>how</em> your program works? Do you understand <em>what</em> you wrote and <em>why</em> you wrote it? </p>
<p>By looking back⁠—when the information is still fresh in your mind⁠—you’re preparing your future self. It’ll help you bridge your understanding and solidify your mental models. It’ll help you improve and prevent repeating the same mistakes over again. In short, it’ll help you get better.</p>
<h2 id="heading-four-ways-to-look-back">Four Ways to Look Back</h2>
<p>There are a few ways that I “look back” at problems. Give them a try.</p>
<h3 id="heading-teach-yourself">Teach Yourself</h3>
<p>A fantastic way to help solidify your mental models is to teach yourself. After you complete a program or problem, go through your code and explain it line by line. It’s one of the best ways of “looking back” when you’re learning something new.</p>
<p>I’ve found this process invaluable while learning web development. After I complete a project, I copy my code into a Google Doc. Starting at the top, I make comments throughout to teach myself about important concepts.</p>
<p>Here’s an example of some code and some of the comments I wrote.</p>
<pre><code class="lang-JS"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ManageTeamMembersPage</span>(<span class="hljs-params">props</span>) </span>{

    <span class="hljs-keyword">const</span> [teammate, setTeammate] = useState({
       <span class="hljs-attr">name</span>:<span class="hljs-string">""</span>,
       <span class="hljs-attr">email</span>: <span class="hljs-string">""</span>,
       <span class="hljs-attr">role</span>: <span class="hljs-string">""</span>,
   })

   ...
</code></pre>
<ul>
<li>Use props to access data passed down from the parent component.</li>
<li>Add state hook. The hook takes a default, which is an object that contains everything I need for the form: name, email, role.</li>
</ul>
<p>This method of “looking back” is about understanding. In this example, I was learning about state, props, and forms in React. </p>
<p>Writing out comments to explain your code will help you solidify concepts in your mind. If you can’t type a short explanation of it on the spot, then revisit the topic. </p>
<p>This method is equally useful for future problems and projects. I regularly pull up old problems and programs I’ve notated. I use them as a reference when writing related programs or solving related problems. Doing so reinforces key ideas, and to Hamming’s point, it helps me remember my successes: what to keep doing.</p>
<h3 id="heading-study-solutions-of-great-programmers">Study Solutions of Great Programmers</h3>
<p>It’s not only useful to study your own code, but also the code of others who have solved the same problem. There are a lot of <a target="_blank" href="https://amymhaddad.com/2-traits-of-great-programmers">great programmers</a> out there and we can learn from them.</p>
<p>After I solve a problem, I apply <a target="_blank" href="https://amymhaddad.com/how-ben-franklin-can-help-you-become-a-better-programmer.mdx">a learning technique that Ben Franklin used</a> to become a better writer. His process involved trying to reproduce an article from a publication he admired after he’d forgotten the details of it. </p>
<p>I follow a similar process to become a better programmer.</p>
<p>Here’s how it works:</p>
<ul>
<li><strong>Solve a problem</strong>.</li>
<li><strong>Find a programmer who’s better than you and who’s solved the same problem.</strong></li>
<li><strong>Study their solution</strong>: read each line of code and type a comment in your editor to explain it.</li>
<li><strong>Re-solve the program</strong> after some time has passed. Use the comments you typed out as hints to guide you along the way.</li>
<li><strong>Compare your program</strong> to the one you studied.</li>
</ul>
<p>To be clear, this practice isn’t about memorizing or copying someone else’s code—far from it. Rather, it’s about learning: get practice <a target="_blank" href="https://amymhaddad.com/why-reading-code-matters">reading</a> code; see another way to solve the same problem; experiment with new parts of a language; and get practice teaching yourself. It’s also about applying what you’ve learned by putting it into your own style.</p>
<h3 id="heading-add-a-constraint">Add a Constraint</h3>
<p>See how different techniques apply to the same problem when you add a constraint. For example, you solved the problem using a hash table. Now try solving it using an array.</p>
<p>The idea is to gain another perspective, and adding a constraint can do just that. It’ll get you out of your comfort zone, forcing you to think creatively. </p>
<p>As a result, you may find a slicker approach and cut the length of your program in half. Or may realize what data structure <em>not</em> to use, which is equally important. </p>
<p>Here’s the point: you’ll have another approach at your ready when you’re faced with a related problem in the future.</p>
<h3 id="heading-solve-a-related-problem">Solve a Related Problem</h3>
<p>The programming website LeetCode is great for many reasons. One is providing similar questions for problems that you solve.</p>
<p>In one problem on LeetCode you are given an array of integers and a target number. The aim is to find two numbers that add up to the target and return their indices. </p>
<p>You solve the problem. </p>
<p>Now solve a related one, which LeetCode provides. This time you’re given an array of integers that’s sorted in ascending order, along with a few additional constraints to differentiate this problem from the previous one.</p>
<p>Solving a related problem is a great way to get practice using a similar technique, data structure, or algorithm in a different context.</p>
<p>Looking back focuses on the <em>process</em>, instead of the end result. And revisiting the process matters. It’s getting out of your comfort zone, trying something new whether that’s a data structure or algorithm. It’s realizing there are different ways to solve the same problem. It’s understanding how to write better code. It’s about learning.  </p>
<p>Yes, it takes some time to look back. But it’s time well spent: it’s how we get better.</p>
<p><em>I write about the programming skills you need to master and the concepts you need to learn, and the best ways to learn them (</em><a target="_blank" href="https://amymhaddad.com/">amymhaddad.com</a>).</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How is Visual and UX Design Important as a Developer and What Can You Do to Level Up? ]]>
                </title>
                <description>
                    <![CDATA[ Design is a part of the product process that often gets pushed off. This can come at a cost that your customers or other developers have to pay. How is design important for those of us who aren't just pushing pixels in Photoshop or Figma and what can... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-is-design-important-as-a-developer-and-what-can-you-do-to-level-up/</link>
                <guid isPermaLink="false">66b8e32b9232d58aac300b13</guid>
                
                    <category>
                        <![CDATA[ Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ design resources ]]>
                    </category>
                
                    <category>
                        <![CDATA[ design thinking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Lifelong Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ self-improvement  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ skills development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ UI Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ux design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ visual design ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Thu, 28 May 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/05/design.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Design is a part of the product process that often gets pushed off. This can come at a cost that your customers or other developers have to pay. How is design important for those of us who aren't just pushing pixels in Photoshop or Figma and what can we do to level up?</p>
<h2 id="heading-design-as-a-developer">Design as a developer</h2>
<p>Design is a term that can describe many parts of the process. Most often, it's probably thought of as the visual designers or UX designers who are actively working to make your product usable or beautiful.</p>
<p>A question that I commonly get asked or see online is where should one start to learn the basics of design?</p>
<p>This question makes me happy. It's an important part of the process that is constantly a secondary thought.  And when <a target="_blank" href="https://twitter.com/colbyfayock/status/1258456643274186753">I asked this on Twitter</a>, I received some thoughtful responses!</p>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/colbyfayock/status/1258456643274186753"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<p>We're living in an age where good UX is increasingly seen as important, but it's still nowhere near the top of the list for those who are learning their way through development. It's still an afterthought that's tossed over to the design team when you're at the 2nd half of your last sprint before launch.</p>
<p>So before I share with you some resources, I'm going to start by explaining why these things are important.</p>
<h2 id="heading-giving-something-for-your-visitors-to-use">Giving something for your visitors to use</h2>
<p>Starting from the top – you can have the best, most ingenious product that blows all competition away, but if no one knows how to use it, it realistically has no value.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/02/pied-piper-user-interface.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Fictional Pied Piper's app tanked because of a bad user experience</em></p>
<p>Our fictional friends at <a target="_blank" href="https://www.hbo.com/silicon-valley">Pied Piper</a> learned this the hard way when their product launch with a groundbreaking compression algorithm didn't go over too well because no one knew how to actually use it.</p>
<p>But this is a realistic scenario. We learned from <a target="_blank" href="https://craigslist.org/">Craigslist</a> that your website or app doesn't need to have a slick design, but it has to be usable.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/craigslist-2020-vs-2001.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Craigslist in 2001 vs 2020</em></p>
<p>For nearly 20 years, Craigslist really hasn't changed that much. A few tweaks to make things a little bit cleaner, but overall it's the same basic layout and experience.</p>
<p>Unfortunately, budget is a concern, and sometimes you can only stretch it so much which doesn't always include a designer. But try to at least get some outside perspective – it can even be a family member or a friend! You would be surprised how much insight you can gather by trying to get your family over the holiday to try to use your app.</p>
<p>The goal is ultimately to get your product in front of someone that hasn't been heads down in it for the past year to get a pair of fresh eyes and a new perspective.</p>
<h2 id="heading-becoming-more-productive">Becoming more productive</h2>
<p>Putting on my process hat – another overlooked aspect of prioritizing design time is the amount of overall time you can possibly save.</p>
<p>Designers don't always get it right the first time, let alone leaving developers to create the design. That's not even including the possibility that your customer or product owner doesn't like the direction you took.</p>
<p>Why spend a couple sprints building out a solution only to start from scratch when you have to throw it all away? Not only have you wasted your customer's time, you've wasted your whole team's time.</p>
<p>Get design feedback early. Work with the design resources you have to iterate and work in feedback as you go. It's important to solve the UI problems before you develop the solutions.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/design-prototyping.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Design sketches from <a target="_blank" href="https://unsplash.com/photos/MKDEMlPRoYU">Unsplash.com</a></em></p>
<p>And this can generally help your team flesh out ideas. Visually seeing an idea, even as a rough sketch on a piece of paper or a disposable prototype, can completely change the way you look at the solution.</p>
<p>All of this early feedback and brainstorming will help you achieve the end-goal of a better product and user experience.</p>
<h2 id="heading-developers-are-users">Developers are users</h2>
<p>Most of people reading this post probably have written code in one form or another. But have you ever thought about how your code impacts other developers?</p>
<p>There are many layers to how your code can provide a better experience for another developer. The basic being – is the documentation that you created readable and easy to understand?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/strip-api-documentation.jpg" alt="Image" width="600" height="400" loading="lazy">
_<a target="_blank" href="https://stripe.com/docs/api/balance/balance_retrieve">Stripe's API documentation</a>_</p>
<p>While it's certainly important for your fellow teammates, they should typically be able to message you on Slack or hop on a call when they run into trouble. But how about those developers that only have your documentation?</p>
<p>Beautiful documentation isn't that which has a beautiful design, it's one that thoroughly walks through the code that you've created so that others can understand what it does and how they can use it. Just as a visitor to your app needs to know how to use the UI, a developer working with your services needs to know how to use the API.</p>
<h2 id="heading-a-little-extra-delight">A little extra delight</h2>
<p>But of course everyone wants something nice to look at. Not only can design treats make people happy and smile, it can also help avoid stress and tension.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/josh-w-comeau-website-heart-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Josh W. Comeau includes cute, happy graphics throughout his site</em></p>
<p>Having a page that's ugly or overly thick with data can be unsettling. Not only can it hurt the usability, but the clutter and color choices can make people feel uneasy, stressed, and full of anxiety.</p>
<p>While your team might not have the resources for full-time designers, taking a little time to learn the basics of design can help set you on your <a target="_blank" href="https://www.colbyfayock.com/2020/02/how-to-become-a-full-stack-web-developer-in-2020/">journey of becoming a well rounded developer</a>.</p>
<h2 id="heading-resources-for-learning-design-basics">Resources for learning design basics</h2>
<p>Like it or not – we're all "designers" in a way. We're all building tools and systems that ultimately will be used by another human being. We should do what we can to make our creations friendlier to use for everyone who comes next.</p>
<p>Since you're now inevitably inspired to spend some time and learn about design, there are luckily a lot of resources available for you to get started.</p>
<h3 id="heading-videos">Videos</h3>
<ul>
<li><a target="_blank" href="https://www.netflix.com/title/80057883">Abstract: The Art of Design</a> (Netflix)</li>
<li><a target="_blank" href="https://www.amazon.com/gp/video/detail/amzn1.dv.gti.fab0b754-6362-2da1-96a1-e3e538137141?tag=gmcs-fcc-20">Objectified</a> (Amazon)</li>
</ul>
<h3 id="heading-books">Books</h3>
<ul>
<li><a target="_blank" href="https://www.amazon.com/Design-Hackers-Reverse-Engineering-Beauty-ebook/dp/B005J578EW/?tag=gmcs-fcc-20">Design for Hackers</a> (Amazon)</li>
<li><a target="_blank" href="https://www.amazon.com/Non-Designers-Design-Book-Non-Designers-ebook/dp/B00PWDFWEE/?tag=gmcs-fcc-20">The Non-Designer's Design Book</a>  (Amazon)</li>
</ul>
<h3 id="heading-email-course">Email Course</h3>
<ul>
<li><a target="_blank" href="https://designforhackers.com/">Design for Hackers</a></li>
<li><a target="_blank" href="https://www.designacademy.io/free-course/">Design Academy</a></li>
<li><a target="_blank" href="https://hackdesign.org/">Hack Design</a></li>
</ul>
<h3 id="heading-misc">Misc</h3>
<ul>
<li><a target="_blank" href="https://twitter.com/i/events/994601867987619840">Design Tips from @steveschoger</a></li>
</ul>
<h2 id="heading-whats-your-take-on-design-as-a-developer">What's your take on design as a developer?</h2>
<p>Have any of these worked particularly well for you? Am I missing something that made design click for you? Please <a target="_blank" href="https://twitter.com/colbyfayock">share with me on Twitter</a>!</p>
<h2 id="heading-join-the-conversation">Join the conversation!</h2>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/colbyfayock/status/1265990400591966208"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How MySpace Taught Me How to Code and Where You Should Look to Develop Your Passion ]]>
                </title>
                <description>
                    <![CDATA[ Learning something new is hard. It's even more challenging if you have a hard time trying to find motivation. How can we find things in our everyday lives that can help us learn? Tom is no longer in your extended network It's been almost 10 years sin... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-myspace-taught-me-how-to-code-and-where-you-should-look-to-develop-your-passion/</link>
                <guid isPermaLink="false">66b8e32c6a98b2a27ee1f346</guid>
                
                    <category>
                        <![CDATA[ Career ]]>
                    </category>
                
                    <category>
                        <![CDATA[ career advice ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Career Change ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Career development  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ careers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ developers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learn to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Lifelong Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Self Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ self-improvement  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Thu, 21 May 2020 16:24:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/05/myspace.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Learning something new is hard. It's even more challenging if you have a hard time trying to find motivation. How can we find things in our everyday lives that can help us learn?</p>
<h2 id="heading-tom-is-no-longer-in-your-extended-network">Tom is no longer in your extended network</h2>
<p>It's been almost 10 years since we saw massive changes underway at MySpace. If you don't remember what <a target="_blank" href="https://myspace.com/">MySpace</a> was, it was the popular social network before Facebook was king (though technically it still exists).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/myspace-tom-profile.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Tom's MySpace Profile</em></p>
<p>This was when everyone started with a new friend named Tom who was the co-founder of MySpace. Everyone could set their own "top 8" that could make or break the best friendships if you snubbed someone. </p>
<p>You could also set a song for your profile which would be added as a little player, back when it was “okay” to automatically play a song when your page loaded.</p>
<p>But MySpace is now a thing of the past, so why am I talking about it?</p>
<h2 id="heading-making-myspace-your-space">Making MySpace, your space</h2>
<p>MySpace had a unique characteristic about it that you don't see in any of the popular social networks these days – it allowed you to add HTML and CSS into the page so that you could really do whatever you wanted with the your profile.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/myspace-edit-profile.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Example of custom code in a MySpace profile from <a target="_blank" href="https://www.dummies.com/social-media/myspace/how-to-embed-video-in-your-myspace-profile/">dummies.com</a></em></p>
<p>Though from a simplistic perspective, this gives you some limited options. Maybe you can add some CSS that updates how the headers look and change a background color.</p>
<p>But realistically, this opened the door to adding full webpages that you could overlay on top of your profile by positioning your new layout above the original content with some z-indexing.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/myspace-profile-filmore-band.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Custom MySpace profile for the band Filmore</em></p>
<p>The trick was, you had a limited amount of characters that you could put in each input. That had limitations, but these limitations helped promote creativity whether it was figuring out how to strip all of the whitespace in the code or by figuring out a way to add something with less overall code.</p>
<h2 id="heading-learning-through-hobbies">Learning through hobbies</h2>
<p>Building MySpace profiles was addicting! It was a social medium that you could customize to make your own and stamp your name on it to show everyone what you did. </p>
<p>While you could do the same with your own website, it wasn't as easy at the time. And building out a profile on MySpace was easy, free, and you could connect with all of your friends.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/myspace-custom-profile-colby-fayock-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>One of my portfolio custom profiles</em></p>
<p>Each time I made a new page, I tried to think about what else I could do. I was even involved with small communities where we would share our work and help each other figure out how to hack things into a profile page (shoutout DM!).</p>
<p>This whole time, as I was trying to learn what more I could customize, I was learning how to code! I learned about how I could squeeze every inch of HTML I could out of a document and I also developed an understanding of how CSS selectors worked. I also learned how positioning allowed me to do cool things on the page and how to center things back when we didn’t have the option to <a target="_blank" href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/">flexbox</a> all the things.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/flexbox-all-the-things-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Flexbox all the things!</em></p>
<p>And this led to “business Colby” developing a sense of entrepreneurship.  At this point, I was still in high school, but I was able to spin off a little business from building these pages. </p>
<p>While a modest $50 per profile seems low, that's a lot for a highschooler in 2004, not to mention that was a lot of money for another highschooler to pay to get one created!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/stk-counter-strike-team-website.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>STK Counter-Strike 1.6 team website</em></p>
<p>But this was the start of my code journey. Building off of MySpace, I started creating actual websites for Counter-Strike teams (CAL anyone?) and bands which would ultimately lead me to make a career out of coding.</p>
<h2 id="heading-turning-hobbies-into-jobs">Turning hobbies into jobs</h2>
<p>I've heard others with a similar story, even others who similarly started with MySpace that eventually turned their interest into a coding career. While the MySpace era is something we all look back and laugh at, it really inspired a lot of people to find what they love to do.</p>
<p>Finding this kind of inspiration can be important to discovering how you want to spend your time. Whether it's a hobby or learning on the side to turn it into a career, keeping engaged with something you're actually interested in is important to learning a new craft.</p>
<p>But it's important to pay attention to how you engage with that new interest. You don't want to force it into a career and quickly burn yourself out. That will lead to regret and resentment.</p>
<p>While I got lucky that my interest in coding ended up turning into my career, I make sure to not "take my work home" as it's important to separate the work from your personal interests like <a target="_blank" href="https://wwdc-memoji.netlify.app/">random</a> <a target="_blank" href="https://github.com/colbyfayock">OSS projects</a> on the side.</p>
<h2 id="heading-find-what-motivates-you">Find what motivates you</h2>
<p>The important thing is to find something that can motivate and inspire you to develop your passion whether for a career or hobby. Each of us have our own journey, whether code related or not, and we should try to find something that will make us happy.</p>
<p>What was your inspiration for your interests? <a target="_blank" href="https://twitter.com/colbyfayock">Share with me on Twitter!</a></p>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Overcome Your Fear of Writing and Find Motivation to Start ]]>
                </title>
                <description>
                    <![CDATA[ Writing about our work is one of those things that most of us have on our to-do list. But whether it's due to procrastination or fear, we never actually get to it. Here's some more motivation and reasons why you should give it a shot! Why should we w... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/overcoming-your-fear-of-writing-and-how-you-can-find-motivation/</link>
                <guid isPermaLink="false">66bee941dceb56d88f491c64</guid>
                
                    <category>
                        <![CDATA[ Blogging ]]>
                    </category>
                
                    <category>
                        <![CDATA[ code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ education ]]>
                    </category>
                
                    <category>
                        <![CDATA[ goal-setting ]]>
                    </category>
                
                    <category>
                        <![CDATA[ goals ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learn to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ motivation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ self-improvement  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teaching ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technical writing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ writing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ writing tips ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Thu, 30 Apr 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/04/writing-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Writing about our work is one of those things that most of us have on our to-do list. But whether it's due to procrastination or fear, we never actually get to it. Here's some more motivation and reasons why you should give it a shot!</p>
<h2 id="heading-why-should-we-write-in-the-first-place">Why should we write in the first place?</h2>
<p>Maybe you've never thought about writing before or maybe you're looking for a little more motivation. Whatever the case, there are a lot of good reasons why writing can help us grow.</p>
<h3 id="heading-helping-others-to-learn">Helping others to learn</h3>
<p>Coding can be tough. And we all started somewhere at the beginning.</p>
<p>It's a long journey that each of us go through and it's even harder to go at it alone. Luckily, we've had websites like <a target="_blank" href="https://www.freecodecamp.org/">freecodecamp.org</a> and <a target="_blank" href="https://css-tricks.com/">css-tricks.com</a> along the way that have made that journey more manageable, but there's always going to be a challenge that just doesn't make sense.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/css-tricks-around-2011.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>CSS-Tricks around 2011 when I got my first official coding job via <a target="_blank" href="https://web.archive.org/web/20110701022701/http://css-tricks.com/">Way Back Machine</a></em></p>
<p>This is where we have an opportunity to share our experiences to help others grow. While our favorite coding sites have tons of amazing tutorials, maybe they're missing a key point someone needed to fully grasp the solution. </p>
<p>Whether you're at the beginning or middle of your journey, every experience, big or small, can help another developer on their own journey.</p>
<p>And this is where it can be rewarding. One of my favorite parts of writing has been getting a <a target="_blank" href="https://twitter.com/colbyfayock">Twitter</a> DM from someone about how <a target="_blank" href="https://www.freecodecamp.org/news/author/colbyfayock/">one of my tutorials</a> helped them learn. It's a great feeling knowing you helped someone else on their journey.</p>
<p>Take this as a way for you to give back to the community that helped you learn and grow.</p>
<h3 id="heading-reinforcing-your-learning">Reinforcing your learning</h3>
<p>Thinking back to your grade school Spanish class, one of the tricks to helping the students learn was to reinforce learning. Teachers use different methods like reading, writing, speaking, flashcards, or even that Cinco de Mayo fiesta where you learned about and celebrated Mexico's heritage to help make the language stick.</p>
<p>This applies to development concepts as well. While your solution is still fresh in your head, write it down! Being able to teach what you've learned by writing about it will help those concepts stick in your head.</p>
<p>And just because you write it, it doesn't mean you have to share it. If you're not comfortable sharing it with the world, just keep a copy in a private notebook. You'll always be able to reference it yourself and still reinforce what you know by writing it down.</p>
<h3 id="heading-documenting-our-experiences">Documenting our experiences</h3>
<p>Doubling up on reinforcing your learning, by writing about your experiences, you're kind of creating your own personal <a target="_blank" href="https://stackoverflow.com/">StackOverflow</a> with a list of problems you've already solved.</p>
<p>As much as we had hoped we would remember how to speak Spanish from the classes we took, 10 years goes by pretty quickly and you suddenly realize you can only correctly say "hola" in Spanish.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/hola-sign.jpg" alt="Image" width="600" height="400" loading="lazy">
_Hola sign from Jon Tyson on <a target="_blank" href="https://unsplash.com/photos/8MMtYM_3xMY">Unsplash</a>_</p>
<p>If you were the ambitious type, maybe you saved all of your notes. If not, maybe you remember a good website that has flashcards.</p>
<p>Either way, having resources to go back to, whether it's your own notes or that website you still have bookmarked, helps us to quickly reference challenges we've already come across. By writing down your experiences, you're adding to that digital notebook that you know you can always use to remember that quirk you fixed.</p>
<h3 id="heading-growing-your-personal-network">Growing your personal network</h3>
<p>Everyone has their own reasons for wanting to write and share content – and that's okay! While some of us might be doing this to help others learn, others might be simply trying to get a job or grow their Twitter following.</p>
<p>One of the benefits of sharing your experiences is that you're immediately growing the network of developers that have a little more insight into who you are and the work you've done.</p>
<p>This doesn't guarantee a job, but it certainly can help. All teams are a little different in how they recruit. Smaller teams tend to include other developers more in the beginning of the process who are probably more likely to open your blog and not only read a little bit, but actually understand it.</p>
<p>But even if you don't immediately get hired, you're playing the long game. Opportunities will start to come in small ways that lead to bigger opportunities down the road.</p>
<h2 id="heading-why-you-might-be-hesitating-and-how-we-can-look-at-it-another-way">Why you might be hesitating and how we can look at it another way</h2>
<p>Sometimes motivation isn't enough. We all have our personal challenges that might prevent us from doing something we want to do. But sometimes it's a matter of finding a different perspective to give you that bit of inspiration to finally dive in.</p>
<h3 id="heading-imposter-syndrome-who-am-i-to-write-about-this">Imposter syndrome – who am I to write about this?</h3>
<p>This is something I've personally struggled with for the majority of my career. Whether I was confident in my ability to do my job or not, I never felt like it was enough to be one of the people writing guides for others.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/colby-fayock-personal-website.jpg" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://www.colbyfayock.com/">My website and blog</a></em></p>
<p>It wasn't until another team member brought another perspective to this argument (thanks Marquet) – everyone learns differently and maybe my way of telling a story can help someone learn. </p>
<p>If someone doesn't read my work, what are the consequences beyond a little bit of wasted time? On the other hand, maybe my blog post resonated with someone in a way that other blog posts didn't and they were finally able to solve their problem.</p>
<p>And this goes for any level of experience. As <a target="_blank" href="https://twitter.com/swyx">Swyx</a> says, <a target="_blank" href="https://www.swyx.io/writing/learn-in-public/">the fastest way to learn is in public</a>. If you're not helping someone else, you're at least helping yourself grow.</p>
<h3 id="heading-finding-time-it-takes-a-while-to-write-a-post">Finding time – it takes a while to write a post</h3>
<p>Time is a funny thing – it becomes an excuse that we use when we don't want to admit the real reason we're holding back.</p>
<p>Of course that's not always the case. Realistically a lot of us have a ton on our plates already whether we work, take care of a family, or are volunteering to help others. It can be a struggle to not want to just sit on the couch after a hard day's work.</p>
<p>But consider the free time you do have. Can you spare 10 minutes jotting down a few notes or even starting an outline of some things you want to say?</p>
<p>While 10 minutes won't write a whole post, if you start the habit and write another paragraph or two every day, you'll slowly end up with a blog post that you can feel good about sharing.</p>
<p>Just don't set the bar too high. If you start off with an unrealistic goal, you're likely to burn out fast and end up back in the same position you're at now.</p>
<h3 id="heading-no-topic-not-knowing-what-to-write-about">No topic – not knowing what to write about</h3>
<p>From speaking with other developers, I've noticed this seems to be tied a little bit to imposter syndrome. Maybe you're getting confident enough that you're more willing to write, but you're struggling to find what to write about. Is it because you can't think of a topic or is it because every topic you think about, you don't think you're enough of an expert to write about it?</p>
<p>Not having a topic can be a legitimate problem, but there's inspiration all around us. If you're working every day as a developer, you're working on problems that you ultimately need to solve. Why not write about those problems? And if you can't write about the problems due to contract concerns, what about writing about them in an abstract way without any sensitive information?</p>
<p>Inspiration for me comes from my experience talking with others. I'm lucky to be on a team that encourages growth of junior developers and during my time helping them out, their questions lead me to think about topics that I took for granted.</p>
<p>Whenever a topic like that comes up, I immediately note it down for later. This topic was on that list! Over time, my list of topics has grown to a point where I don't think I'll even finish it by the end of the year.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/list-of-topic-ideas.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>My personal list of topic ideas</em></p>
<p>While that could feel overwhelming, it's also motivates me to have a bigger selection of what I'm in the mood to write about rather than forcing myself to both think of a new topic and write about something I don't want to write about each week.</p>
<p>Whatever the case, find your source of inspiration. You don't need to be an expert on it. It doesn't matter if someone more experienced already wrote about it. Write what you know. Share your experiences. Maybe you'll help someone see the problem from a different perspective.</p>
<h2 id="heading-finding-what-motivates-you">Finding what motivates you</h2>
<p>At the end of the day, writing is something that each of us will need to find our own motivation to do.</p>
<p>Try to evaluate your goals. What are you looking to achieve? If writing is something you truly want to do, you'll need to find your own source of inspiration.</p>
<p>While some reasons might be more valid than others, it's easier to find reasons not to do something than it is to do it.</p>
<p>You got this! ?</p>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How I Passed the CompTIA Linux+ Exam ]]>
                </title>
                <description>
                    <![CDATA[ By Clark Jason Ngo Summary of this article: The backstory: why CompTIA Linux+ exam. Review of learning resources: what is good and what is not good. Retrospective on studying: what worked and did not work. My experience during the exam: how the test... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-linux-exam-story/</link>
                <guid isPermaLink="false">66d45e26230dff01669057e1</guid>
                
                    <category>
                        <![CDATA[ comptia ]]>
                    </category>
                
                    <category>
                        <![CDATA[ exam  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 30 Apr 2020 10:01:32 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/04/Screen-Shot-2020-04-29-at-10.33.10-PM.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Clark Jason Ngo</p>
<h3 id="heading-summary-of-this-article">Summary of this article:</h3>
<ul>
<li>The backstory: why CompTIA Linux+ exam.</li>
<li>Review of learning resources: what is good and what is not good.</li>
<li>Retrospective on studying: what worked and did not work.</li>
<li>My experience during the exam: how the test was conducted and how I felt.</li>
<li>My approach during the exam: what strategies to use and mindset to have.</li>
<li>Getting an awesome badge: what it looks like and what's in it for me?</li>
<li>Bonus: as most of my materials are sponsored by the school, I've looked for free content for you to study for the exam, such as <a target="_blank" href="https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard">filesystem hierarchy</a>, <a target="_blank" href="https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.html#binEssentialUserCommandBinaries">basic linux commands</a>, using <a target="_blank" href="https://aws.amazon.com/mp/linux/">AWS EC2 Ubuntu</a> as your Linux environment.  I also created a flash card in Trello, available <a target="_blank" href="https://trello.com/b/viGl7wam/linux-prep">here</a>.  Disclaimer: free content might not be sufficient. </li>
<li>Exam objectives: <a target="_blank" href="https://www.comptia.jp/pdf/comptia-linux-xk0-004-exam-objectives.pdf">Official CompTIA Linux+ Exam Objectives</a>. </li>
</ul>
<h3 id="heading-tldr-exam-tips-i-had-no-professional-experience-with-linux">TLDR exam tips (I had no professional experience with Linux):</h3>
<ul>
<li>Focus on the Activity Section of the CompTIA Study Guide and follow along with your own Linux environment.</li>
<li>Practice on Performance-Based Questions (PBQs). They show around 10 choices that all <em>look</em> correct.</li>
<li>Play around with Linux command combinations using piping (|)</li>
<li>Configure IP tables, firewall, and troubleshooting.</li>
<li>Learn the configuration steps, boot process, and backing up files.</li>
<li>Basic bash scripting and regular expressions.</li>
</ul>
<p><em>Read until the end for tips on how to have the correct mindset and strategies to answer difficult questions. Also, a video of me summarizing this article during a club meeting at our school is available at the bottom of the article. Do check the video out as it has a Q&amp;A section towards the end.</em></p>
<p>I'd like to start off with a big thank you to <a target="_blank" href="https://ciae.cityu.edu/programs/">School of Technology and Computing</a> of <a target="_blank" href="https://www.cityu.edu/">City University of Seattle</a> (CityU). They provided me with a job, career growth, and sponsored my CompTIA learning materials and exam voucher. </p>
<p>As an F-1 Student Visa holder with limited job opportunities, this allowed me to earn extra income, of which I <a target="_blank" href="https://www.freecodecamp.org/donate/">donate</a> a portion to freeCodeCamp on a monthly basis. </p>
<p>This is a loose continuation from my story: <em><a target="_blank" href="https://www.freecodecamp.org/news/cjn-why-i-abandoned-my-mba-to-get-a-masters-in-computer-science/">Why I abandoned my MBA to get a master's in Computer Science</a></em>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*cSvQ_M7qvgXFrIrA.jpg" alt="Image" width="540" height="210" loading="lazy">
<em>City University of Seattle Campus</em></p>
<h2 id="heading-why-comptia-linux">Why CompTIA Linux+?</h2>
<p>In July 2019, our school, with the help of our director of external relations, landed a contract with Amazon Web Services (AWS) and Washington Technology Industry Association (WTIA), called the AWS Apprenticeship Program (AAP). </p>
<p>We had the opportunity to train 23 military veterans and veteran spouses. Their requirement was to pass CompTIA Linux+ Exam and CityU's Full Stack System Developer Program which includes CompTIA Linux+ Exam preparation. Once they met both criteria, they'd be able to transition to on-the-job training with AWS. </p>
<p>My role at the time was a Lead Teaching Assistant (TA) and I was tasked to help build the Dean's program proposal. I coordinated with 6 other TAs to build the courses, which consisted the following: Linux I, Linux II, Networking, Web Development, JavaScript/TypeScript, Full Stack - MEAN Stack, Python, and Full Stack - Django.</p>
<p>As this was our first contract, we were building the plane while trying to fly it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-295.png" alt="Image" width="600" height="400" loading="lazy">
<em>Picture looks fun! But not in real life lol!</em></p>
<h3 id="heading-we-utilized-the-following-resources-for-our-linux-operating-system-course">We utilized the following resources for our Linux Operating System course:</h3>
<ul>
<li>Textbook: Pro Bash Programming: Scripting the GNU/Linux Shell, Second Edition, by Chris F. A. Johnson, Jayant Varma </li>
<li>Student's Linux environment: AWS EC2 Instance with Ubuntu</li>
<li>Virtual Lab: InfoSec Learning</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-296.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-what-i-learned">What I learned</h3>
<ul>
<li>A lot of bash scripting exercises and coding challenges</li>
<li>How to SSH to a remote server (EC2 Instance)</li>
<li>Various Linux commands and configuration setups related to CompTIA Linux+</li>
</ul>
<p>After a few weeks into the program, we researched more and listened to student feedback. Turns out we were doing too much bash scripting and lacked on CompTIA Linux+ Exam preparation.</p>
<blockquote>
<p>The students were in hell during the first few weeks of bash scripting</p>
</blockquote>
<p>We immediately partnered with CompTIA to get CompTIA Linux+ Exam Study materials at bulk price. We pivoted hard and changed parts of our program to integrate the new study materials.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-299.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cool badge</em></p>
<blockquote>
<p>Good thing our department was practicing Agile methodology and it made us very nimble.</p>
</blockquote>
<h3 id="heading-the-new-resources-are-as-follows">The new resources are as follows:</h3>
<ul>
<li>CertMaster Learn - includes eBook, Performance-Based Question (PBQ), and CompTIA Videos (Note: This was last year. If you purchased this year, you won't have the PBQs, but you get a new interface, and an additional practice test).</li>
<li>CertMaster Practice - multiple-choice questions on steroids. Once you've accumulated a good amount of wrong answers, you'd get feedback on why your answers are wrong and it explains the other choices as well. Then, it pushes your progress bar back.</li>
<li>CertMaster Labs - shorter lab activities compared to InfoSec Labs.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-298.png" alt="Image" width="600" height="400" loading="lazy">
<em>The CompTIA Linux+ Learning bundle</em></p>
<h3 id="heading-my-thoughts-on-the-new-resources">My thoughts on the new resources</h3>
<p>I read the eBook from top to bottom and it was helpful to obtain an overview. However, I wasn't able to retain any knowledge from reading it. I breezed through both the CertMaster Practice and CertMaster Labs and I gained nothing as well. </p>
<blockquote>
<p>What's wrong with me? Hmm..</p>
</blockquote>
<p>Because of an opportunity to teach the JavaScript/TypeScript course in the AAP program and the unfortunate event of my dad's passing, my road to Linux+ Exam was eventually derailed and forgotten.</p>
<blockquote>
<p>Man.... What a bummer...</p>
</blockquote>
<h2 id="heading-fast-forward-to-the-end-of-the-aws-apprenticeship-program">Fast forward to the end of the AWS Apprenticeship Program</h2>
<p>In November 2019, we successfully transitioned all 23 students! A 100%! We were the only partner school to have done that.</p>
<p>Most credit goes to the School of Technology &amp; Computing Dean's repeated quotes of "leave no man behind" - similar to the soldier's creed: "I will never leave a fallen comrade behind", and "we stay together, we survive" (from the movie Gladiator).</p>
<p>The program's success was largely attributed to TAs, who supported the students since Day 1.</p>
<p>We asked for feedback from our students on what worked and what did not in regards to the CompTIA Linux+ materials. We got the following:</p>
<ul>
<li>Focus on Activity Section of the Study Guide</li>
<li>Do the virtual labs repeatedly</li>
<li>Going through the practice exam is not effective</li>
<li>Watch ITPro.tv videos (which we were not able to provide that time)</li>
</ul>
<p>I did not study for the Linux+ Exam for several months as I focused on learning the MEAN Stack (especially the Angular front end framework). I regularly tackled leetcode coding challenges to prepare for software developer job interviews. </p>
<p>I was also finishing my capstone project: <a target="_blank" href="https://www.freecodecamp.org/news/cjn-understanding-mean-stack-through-diagrams/"><em>Software Documentation and Architectural Analysis of Full Stack Development</em></a>, and teaching two classes: Information Systems, and Data Management Communications and Networking.</p>
<blockquote>
<p>No time... no time at all... or was it just excuses?</p>
</blockquote>
<p>When I was nearing the end of my last quarter, I felt guilty and started studying again for the Linux+ Exam. </p>
<blockquote>
<p>This time, a new plan of attack. </p>
</blockquote>
<p>I started reading the eBook again from top to bottom. What was different the second time around was that for every theory, definition, command, option, subcommands, etc. that I'd encounter, I would create a flash card in Trello (available <a target="_blank" href="https://trello.com/b/viGl7wam/linux-prep">here</a>). I used this to train with friends to do a pop quiz and execute commands in the Linux terminal as well. </p>
<p>On my own, I would have my own Linux environment following along with the Activity Section of the eBook. This really helped me retain my knowledge on Linux commands and configurations. I also incorporated using Linux commands in my personal laptop with MacBook Pro, as MacOS has Unix-like terminal.</p>
<p>I utilized the CertMaster Practice Exam again. And this time, I had a friend to go over and discuss why each choice was right or wrong, using the process of elimination.</p>
<blockquote>
<p>It seems like doing hands-on and having a discussion with a friend truly helps you master a topic.</p>
</blockquote>
<p>I really didn't like the CertMaster Labs and did not use it during my study.</p>
<h3 id="heading-i-hesitated-to-study-the-following">I hesitated to study the following:</h3>
<ul>
<li>bash scripting - I'm a software developer and I know how to code already. I have built bash scripts to boost my productivity, from class notes to web applications.</li>
<li>version control - I've been using git and GitHub in my classes and personal projects.</li>
<li>containers and orchestration - I have a good foundation as I've been reading DevOps books.</li>
</ul>
<h2 id="heading-the-binge-worthy-itprotv-videos">The Binge-Worthy ITPro.tv Videos</h2>
<blockquote>
<p>I accidentally discovered it. It was timely and effective.</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-304.png" alt="Image" width="600" height="400" loading="lazy">
<em>where you can binge-watch IT videos</em></p>
<p>At the start of April 2020, we got news of incoming AAP students. The Dean asked me to check the CompTIA store again for materials, and find out what these ITPro.tv videos were all about. </p>
<p>At first, I was reluctant to even purchase the videos because I remembered the CompTIA Study Guide having the ITPro.tv logo at the start of their videos. I started calculating the total hours of the CompTIA Study Guide videos. The total duration was only 22 minutes. </p>
<p>This was a big difference compared to the standalone ITPro.tv videos with 16 hours of content. I went ahead and purchased it (with reimbursement of course).</p>
<p>And boy, I did not regret it. Those videos were fantastic. They dove deeper into the topics and explained the commands throughly with the help of a co-host to ask why we needed to use those commands. </p>
<p>The average duration of a video is about 15 minutes. A big contrast compared to the other resource, which averaged about 2 minutes per video.</p>
<p>I started picking videos to watch based on the topics that I knew I couldn't explain to anyone. I combined this strategy with the multiple-choice-on-steroids CertMaster Practice to fill in my knowledge gaps.</p>
<p>In the middle of April 2020, I scheduled my CompTIA Linux+ Exam Online Testing. They created the online testing environment due to the pandemic. As it was nearing the scheduled date, I relaxed my study patterns and limited myself to watching the ITPro.tv videos.</p>
<h2 id="heading-exam-procedures">Exam Procedures</h2>
<p>The online exam requires you to abide by the following procedures:</p>
<ul>
<li>have an internet connection</li>
<li>have an external webcam or laptop webcam</li>
<li>have an external microphone or laptop microphone</li>
<li>have a photo of valid ID</li>
<li>have pictures of your front, back, left, and right of your own testing environment</li>
<li>No headphones, and smartphones and electronics should be out of reach</li>
</ul>
<p>View the full details <a target="_blank" href="https://www.comptia.org/testing/testing-options/take-online-exam">here</a>.</p>
<h2 id="heading-exam-time">Exam Time</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-308.png" alt="Image" width="600" height="400" loading="lazy">
<em>instagram post of my ever supportive partner</em></p>
<blockquote>
<p>I totally appreciate the support!</p>
</blockquote>
<h3 id="heading-my-experience-with-the-online-test-app">My Experience with the Online Test App</h3>
<ul>
<li>The exam was scheduled 12:15 midnight. This was my intention to avoid any noise in the house. </li>
<li>The proctor can see you through the webcam, and you can't see them.</li>
<li>The online testing app slowed and crashed several times. The proctor said it was due to the high volume of test takers.</li>
</ul>
<h3 id="heading-what-i-felt-during-the-exam">What I felt during the exam</h3>
<p>The first few questions I got in the exam were Performance-Based Questions. It was freaking hard. I really couldn't answer with 100% confidence. I encountered a problem using Linux commands <em>grep</em> and <em>awk</em> with piping to another command. </p>
<p>Another problem was about investigating an SELinux policy violation, which requires you have to inspect each command and their respective output to pinpoint which file or directory needed additional configuration.</p>
<blockquote>
<p>If only I had that professional experience, this would have been much easier.</p>
</blockquote>
<p>As I went through more questions, I really felt so dumb and lost my confidence. I didn't know how to answer the questions about network, system, or user configurations. In the bash scripting portion, I knew I wasn't really good at RegEx (regular expressions). </p>
<blockquote>
<p>I had 30 minutes left in my exam and felt like failing...</p>
</blockquote>
<p>My thoughts of plan B were coming back – I would just take the exam again. This was partly due to my own perspective in life. I always tell people I'm used to failure and I'm fine failing as long as I can be persistent until I reach my goal. </p>
<p>Around the 28-minute mark I was about to call it quits, when I heard another voice in my brain (I'm not crazy I tell you. It's the Jedi Mind trick, read <em><a target="_blank" href="https://www.freecodecamp.org/news/cjn-how-to-teach-yourself-to-learn-again/">How to teach yourself to learn again</a></em>). </p>
<blockquote>
<p>The voice said: "don't think about failure now, use the remaining minutes and do your best!"</p>
</blockquote>
<p>So I used the remaining time to jump around to different questions until I'd covered them all. This time with more focus. I changed almost 80% of my answers and I started to do the following strategies to increase my chances of getting the right answer:</p>
<ul>
<li>Process of elimination - I removed choices that I knew were totally wrong.</li>
<li>I stuck with what I knew - I didn't choose an answer if I didn't know what it meant.</li>
<li>Deeper focus - I read word by word and tried to use both comprehension and logical thinking.</li>
<li>Eyes closed, mind opened - I convinced myself that I'd studied really hard for this exam so it must be stored in my brain somewhere. With that in mind, I tried to retrieve those memories to achieve 100% confidence in some questions that I had around 70% confidence answering.</li>
</ul>
<p>I kept repeating these strategies until the last minute. </p>
<h2 id="heading-exam-results">Exam Results</h2>
<p>The exam ended and I passed – 739 out of 1000! A passing grade point is 720. After 30 minutes, I got an email from CompTIA.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-312.png" alt="Image" width="600" height="400" loading="lazy">
<em>my cool instagram post celebrating my achievement</em></p>
<p>I will still be humbled and say to people that I got lucky. But for myself, I won't say I got lucky because I changed most of my answers using a better mindset and more effective strategies.</p>
<h2 id="heading-lessons-learned">Lessons Learned</h2>
<ul>
<li>I should really stop taking these exams when I don't have professional experience yet. Why? I encountered the same kind of difficulty and failed my AWS Developer Certification Exam before (here's the article: <em><a target="_blank" href="https://www.freecodecamp.org/news/cjn-i-failed-my-aws-developer-exam/">I failed my AWS Developer Exam. What now?</a></em>). </li>
<li>In studying, I should've done more assessment early on to focus on my knowledge gap instead of speeding through all the materials.</li>
<li>During the exam, I needed to remind myself this is my reality now. What can I do to be great in this situation? This mindset is something I can apply to my current work as well.</li>
<li>Remember to have study sessions with friends or colleagues, as you'll have the chance to grow your knowledge exponentially.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-284.png" alt="Image" width="600" height="400" loading="lazy">
<em>quote from Gladiator (2000) movie</em></p>
<h2 id="heading-what-now-clark">What now, Clark?</h2>
<p>I rejoined CityU as a full-timer with a position of Program Manager for AWS Apprentice Program (Full Stack Web Systems Developer) last April 20, 2019. </p>
<p>With the Linux+ Certified under my belt, I have gained additional experience, along with my previous experience being a TA Lead with the same program. It's allowed me to better lead, teach, and mentor the new cohort. This includes my team that includes new TAs that I know for sure will be more successful than I was.</p>
<p>I will do my best to keep teaching and mentoring students while sharpening my software development skills, as I'm still on a journey to find a software developer job in the tech industry. I know it's hard coming from a non-tech background to transition, but we'll all get there in time.</p>
<p>To my readers, thank you for reading my article. I really want to focus more on technical articles but I couldn't let a good story slip away.=)</p>
<p>Connect with me in LinkedIn <a target="_blank" href="https://www.linkedin.com/in/clarkngo/">here</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-322.png" alt="Image" width="600" height="400" loading="lazy">
<em>I couldn't decide on my LinkedIn headline lol</em></p>
<p><strong>Article Video Summary and Q&amp;A</strong></p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/5evBAfJi4l0" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
