<?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[ data - 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[ data - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 26 May 2026 04:43:34 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/data/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Traditional Scraping vs AI Scraping: A Practical Guide for Developers and Data Teams ]]>
                </title>
                <description>
                    <![CDATA[ Enormous amounts of data are constantly generated on the open web. Product prices change, job listings go live and get taken down, news articles are published, and company information gets updated. Fo ]]>
                </description>
                <link>https://www.freecodecamp.org/news/traditional-scraping-vs-ai-scraping/</link>
                <guid isPermaLink="false">69e156abffbb787634ffa61a</guid>
                
                    <category>
                        <![CDATA[ web scraping ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Joel Olawanle ]]>
                </dc:creator>
                <pubDate>Thu, 16 Apr 2026 21:37:47 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/c7f16b00-5245-48e2-a864-38a86d4292ae.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Enormous amounts of data are constantly generated on the open web. Product prices change, job listings go live and get taken down, news articles are published, and company information gets updated.</p>
<p>For developers and teams that rely on this kind of data, the question has never been whether to scrape the web, but how to do so reliably over time.</p>
<p>For a long time, the approach has been straightforward. You inspect a page, write selectors, and extract the data using tools like <a href="https://pypi.org/project/beautifulsoup4/">BeautifulSoup</a> or browser automation libraries like <a href="https://playwright.dev/">Playwright</a> and <a href="https://www.selenium.dev/">Selenium</a>. This works well, but it comes with a familiar problem: the moment the structure of a page changes, your scraper breaks and needs fixing.</p>
<p>Recently, a different approach has started gaining attention. Instead of writing selectors, you describe what you want and let the system figure out how to extract it. This is what people refer to as AI scraping.</p>
<p>Both approaches are widely used today, but they solve the problem in very different ways. This guide breaks down how each one works, where each one fits, and how to decide which approach makes sense for your use case.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-what-is-traditional-web-scraping">What is Traditional Web Scraping?</a></p>
</li>
<li><p><a href="#heading-traditional-scraping-in-practice">Traditional Scraping in Practice</a></p>
</li>
<li><p><a href="#heading-what-is-ai-web-scraping">What is AI Web Scraping?</a></p>
</li>
<li><p><a href="#heading-ai-scraping-in-practice">AI Scraping in Practice</a></p>
</li>
<li><p><a href="#heading-traditional-scraping-vs-ai-scraping-when-to-use-each">Traditional Scraping vs AI Scraping: When to Use Each</a></p>
</li>
</ul>
<h2 id="heading-what-is-traditional-web-scraping">What is Traditional Web Scraping?</h2>
<p><a href="https://www.freecodecamp.org/news/web-scraping-in-javascript-with-puppeteer/">Traditional web scraping</a> scraping is built on a simple idea that if a browser can load a page and display data to a user, then a program should be able to do the same and extract that data automatically.</p>
<p>This is done with CSS selectors and XPath. For CSS selectors, a selector like <code>.product-card .price</code> means “find the price element inside a product card.” It's easy to understand and works well for most use cases.</p>
<p>XPath, on the other hand, is more powerful but more complex. It allows you to navigate the structure of a page in more detail, including moving up and down the DOM, filtering by text, or handling deeply nested elements.</p>
<p>In practice, most developers start with CSS selectors and only use XPath when the structure becomes too complex.</p>
<p>This idea has been around since the early days of the web. Instead of manually copying information from a page, developers started writing scripts that send requests, receive HTML responses, and extract the pieces they care about.</p>
<p>At its core, nothing about that model has really changed.</p>
<p>You still fetch a page, inspect its structure, and extract data from it. The difference today is not the concept, but how sophisticated the tooling and scale have become.</p>
<h3 id="heading-the-tools-behind-traditional-scraping">The Tools Behind Traditional Scraping</h3>
<p>Over time, a solid ecosystem of tools has developed around this approach.</p>
<ul>
<li><p><a href="https://pypi.org/project/requests/"><strong>Requests</strong></a> is the de facto Python library for making HTTP calls. Most traditional scrapers use <code>requests</code> to fetch pages and then pass the response to BeautifulSoup for parsing. It's simple and reliable for static sites.</p>
</li>
<li><p><a href="https://pypi.org/project/beautifulsoup4/"><strong>BeautifulSoup</strong></a> is a Python library for parsing HTML and XML. It takes raw HTML and builds a navigable tree of objects from it. It's fast to learn, very readable, and excellent for static pages. Its main limitation is that it has no browser engine, so it can't execute JavaScript. If a site renders content dynamically after page load, BeautifulSoup will see an empty container.</p>
</li>
<li><p><a href="https://www.selenium.dev/"><strong>Selenium</strong></a> and <a href="https://playwright.dev/"><strong>Playwright</strong></a> are browser automation tools that control a real browser. They can click buttons, scroll, and wait for JavaScript to finish loading before extracting data. The trade-off is that they are slower and more resource-intensive than simple HTTP requests, but they are necessary for dynamic sites.</p>
</li>
</ul>
<h2 id="heading-traditional-scraping-in-practice">Traditional Scraping in Practice</h2>
<p>Let's build a real, working scraper using <a href="https://books.toscrape.com/">Books to Scrape</a>, a sandbox site built specifically for practicing web scraping. The goal is to extract the title, price, and star rating for every book listed on the first page.</p>
<h3 id="heading-step-1-install-dependencies">Step 1: Install Dependencies</h3>
<pre><code class="language-plaintext">pip install requests beautifulsoup4
</code></pre>
<h3 id="heading-step-2-inspect-the-page">Step 2: Inspect the Page</h3>
<p>Before writing a single line of code, open the target page in your browser and inspect its HTML. Right-click any book title and choose "Inspect" to see the structure.</p>
<img src="https://cdn.hashnode.com/uploads/covers/5e33f66ffc003cfb0c64069e/3b47f64a-8ac8-4cf2-9237-b117355bec5f.png" alt="Inspecting the page structure" style="display:block;margin:0 auto" width="3018" height="1654" loading="lazy">

<p>You'll notice each book lives inside an <code>&lt;article class="product_pod"&gt;</code> element, and within it:</p>
<ul>
<li><p>The title is in the <code>&lt;h3&gt;</code> tag, inside an <code>&lt;a&gt;</code> element (as a <code>title</code> attribute)</p>
</li>
<li><p>The price is in a <code>&lt;p class="price_color"&gt;</code> element</p>
</li>
<li><p>The star rating is encoded in the CSS class of a <code>&lt;p&gt;</code> element — for example, <code>&lt;p class="star-rating Three"&gt;</code> means three stars</p>
</li>
</ul>
<p>This is the core detective work of traditional scraping: you study the HTML, find the patterns, and write selectors to match them.</p>
<h3 id="heading-step-3-write-the-scraper">Step 3: Write the Scraper</h3>
<pre><code class="language-python">import requests
from bs4 import BeautifulSoup

# 1. Fetch the page
url = "https://books.toscrape.com/"
response = requests.get(url)

# Always check the request succeeded before going further
if response.status_code != 200:
    print(f"Failed to fetch page: {response.status_code}")
    exit()

# 2. Parse the HTML
soup = BeautifulSoup(response.content, "html.parser")

# 3. Find all book containers on the page
books = soup.select("article.product_pod")

# 4. Extract data from each book
results = []

for book in books:
    # Title is stored as an attribute, not visible text
    title = book.select_one("h3 a")["title"]

    # Price is the text inside the price element
    price = book.select_one("p.price_color").get_text(strip=True)

    # Rating is encoded as a word in the CSS class: "star-rating Three"
    # We grab the second class name and map it to a number
    rating_word = book.select_one("p.star-rating")["class"][1]
    rating_map = {"One": 1, "Two": 2, "Three": 3, "Four": 4, "Five": 5}
    rating = rating_map.get(rating_word, 0)

    results.append({
        "title": title,
        "price": price,
        "rating": rating
    })

# 5. Display results
for book in results:
    print(f"{book['title']} | {book['price']} | {book['rating']} stars")
</code></pre>
<h3 id="heading-step-4-run-it">Step 4: Run It</h3>
<pre><code class="language-bash">python scraper.py
</code></pre>
<p>Your output will look something like this:</p>
<pre><code class="language-bash">A Light in the Attic | £51.77 | 3 stars
Tipping the Velvet | £53.74 | 1 stars
Soumission | £50.10 | 1 stars
Sharp Objects | £47.82 | 4 stars
Sapiens: A Brief History of Humankind | £54.23 | 5 stars
...
</code></pre>
<p>Twenty books, all structured and clean.</p>
<h3 id="heading-step-5-extend-it-to-multiple-pages">Step 5: Extend It to Multiple Pages</h3>
<p>The site has 50 pages. Extending the scraper to crawl all of them requires following the "next" button:</p>
<pre><code class="language-python">import requests
from bs4 import BeautifulSoup

BASE_URL = "https://books.toscrape.com/catalogue/"
start_url = "https://books.toscrape.com/catalogue/page-1.html"

all_books = []
url = start_url

while url:
    response = requests.get(url)
    soup = BeautifulSoup(response.content, "html.parser")

    for book in soup.select("article.product_pod"):
        title = book.select_one("h3 a")["title"]
        price = book.select_one("p.price_color").get_text(strip=True)
        rating_word = book.select_one("p.star-rating")["class"][1]
        rating_map = {"One": 1, "Two": 2, "Three": 3, "Four": 4, "Five": 5}
        rating = rating_map.get(rating_word, 0)
        all_books.append({"title": title, "price": price, "rating": rating})

    # Check for a "next" button and follow it
    next_btn = soup.select_one("li.next a")
    url = BASE_URL + next_btn["href"] if next_btn else None

print(f"Scraped {len(all_books)} books total.")
</code></pre>
<p>Running this crawls all 1,000 books across all 50 pages.</p>
<h3 id="heading-what-makes-this-approach-fragile">What Makes This Approach Fragile</h3>
<p>This scraper works well today because <code>books.toscrape.com</code> is a static, stable sandbox. In production, the same approach has a well-known weakness: it's completely dependent on the HTML structure staying the same.</p>
<p>If the site's developer renames <code>product_pod</code> to <code>book-card</code>, or moves the price into a <code>&lt;div&gt;</code> instead of a <code>&lt;p&gt;</code>, every selector breaks. You get no data, or worse, incorrect data with no error, and you only discover the breakage when someone notices the output looks wrong.</p>
<p>This is one of the problems AI scraping is designed to address.</p>
<h2 id="heading-what-is-ai-web-scraping">What is AI Web Scraping?</h2>
<p>Traditional scraping works by following the structure of a page. It looks for specific elements, class names, or patterns in the HTML and extracts data based on those rules.</p>
<p>AI-powered scraping approaches the same problem differently. Instead of relying only on structure, it focuses on understanding the content itself. It looks at a page and identifies what something represents, not just where it's located.</p>
<p>In a traditional scraper, you might write something like:</p>
<pre><code class="language-javascript">response.css(".product-card .price::text").get()
</code></pre>
<p>You're telling the system exactly where to look. But, with AI scraping, you describe the outcome:</p>
<pre><code class="language-plaintext">Extract the product name, price, and availability for each item on this page.
</code></pre>
<p>The system reads the page, identifies what appears to be a product listing, extracts the relevant fields, and returns structured data.</p>
<h3 id="heading-whats-actually-happening-under-the-hood">What's Actually Happening Under the Hood</h3>
<p>AI scraping can feel like magic at first, but it's built on a combination of familiar components.</p>
<p>At the core are <strong>large language models (LLMs)</strong> trained on vast amounts of text, including web content and HTML. Over time, they learn patterns such as what a product listing looks like, how prices are usually presented, or how job listings are structured.</p>
<p>When given a page, the model can recognize these patterns and map them to the fields you asked for.</p>
<p>But the model is only one part of the system. You still need something to load and interact with the page. That is where <strong>browser automation</strong> comes in. Most AI scraping tools rely on headless browsers like Chromium or frameworks like Playwright to render pages, execute JavaScript, and handle real-world behavior such as scrolling or clicking.</p>
<p>On top of that, there's a layer that interprets your input. When you write a <strong>prompt</strong> describing the data you want, the system translates that into an extraction task. It decides what parts of the page are relevant and how to structure the output.</p>
<p>Finally, the system formats the results into clean data, typically as JSON or CSV, so you can use them directly with minimal post-processing.</p>
<p><strong>Note:</strong> Tools like ChatGPT can interpret content, but they're not scraping systems. They don't crawl pages, handle workflows, or run repeatable data extraction. AI scraping tools combine this intelligence with the infrastructure required to collect data reliably.</p>
<h3 id="heading-popular-tools-behind-ai-scraping">Popular Tools Behind AI Scraping</h3>
<p>As AI scraping has grown more popular, a number of tools have emerged that make this approach accessible without requiring you to build everything from scratch.</p>
<p>For example:</p>
<ul>
<li><p><a href="https://spidra.io/"><strong>Spidra</strong></a> takes a pretty direct approach to extraction. You describe the data you want, and it handles loading the page, interpreting the content, and returning structured results. It also manages things like navigation and interactions behind the scenes, which makes it useful when you want to extract data without worrying about selectors or maintaining scraping logic.</p>
</li>
<li><p><a href="https://www.firecrawl.dev/"><strong>Firecrawl</strong></a> focuses on turning web pages into clean, structured content. Instead of extracting specific fields like price or title, it converts entire pages into formats like markdown or simplified JSON. This makes it especially useful when you want to feed web content into AI systems or work with it in a readable format without dealing with messy HTML.</p>
</li>
<li><p><a href="https://jina.ai/reader/"><strong>Jina Reader</strong></a> is designed to simplify web pages into clean text. It strips away layout noise such as navigation, ads, and styling, and focuses on the actual content. This is helpful when your goal is to understand or process the information on a page rather than extract structured fields.</p>
</li>
<li><p><a href="https://brightdata.com/products/web-scraper/ai"><strong>Bright Data AI scrapers</strong></a> combine AI-based extraction with a strong scraping infrastructure. They allow you to request structured data without writing selectors, while also handling challenges like blocking and scaling. This makes them more suitable for larger or more demanding scraping tasks.</p>
</li>
<li><p><a href="https://apify.com/"><strong>Apify</strong></a> sits somewhere in between traditional and AI-driven scraping. It provides a full platform for building and running scrapers, and allows you to introduce AI where it makes sense, whether for extraction or post-processing. This makes it useful when you need more control over the entire pipeline.</p>
</li>
</ul>
<p>In practice, these tools aren't trying to solve the exact same problem. Some focus on extracting structured data, others on cleaning content, and others on building full scraping workflows. The right choice depends on what you're trying to achieve, not just the tool itself.</p>
<h2 id="heading-ai-scraping-in-practice">AI Scraping in Practice</h2>
<p>Let's run the same data collection task of extracting books from <code>books.toscrape.com</code> using an AI scraping tool. We'll use Spidra's API so you can see exactly what changes.</p>
<h3 id="heading-step-1-get-an-api-key">Step 1: Get an API Key</h3>
<p>Sign up at <a href="http://spidra.io">spidra.io</a> and create an API key from your dashboard. You'll use this key to authenticate every request.</p>
<img src="https://cdn.hashnode.com/uploads/covers/5e33f66ffc003cfb0c64069e/b4dd4103-d9ee-4193-b8df-b62cd815bb16.png" alt="Getting Spidra API key" style="display:block;margin:0 auto" width="3024" height="1656" loading="lazy">

<h3 id="heading-step-2-understand-the-api-structure">Step 2: Understand the API Structure</h3>
<p>Spidra's scrape endpoint accepts a JSON payload. The two most important fields are <code>url</code> (where to scrape) and <code>prompt</code> (what to extract, written in plain English). You can optionally specify the <code>output</code> format — JSON works best for structured data.</p>
<pre><code class="language-bash">POST https://api.spidra.io/scrape
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
</code></pre>
<p>You see, we don't need selectors or HTML inspection. Just a URL and a description.</p>
<h3 id="heading-step-3-write-a-single-page-extraction">Step 3: Write a Single-Page Extraction</h3>
<p>Here's the equivalent of our traditional scraper, written as an API call:</p>
<pre><code class="language-python">import requests
import json

API_KEY = "your_api_key_here"

payload = {
    "urls": [{"url": "https://books.toscrape.com/"}],
    "prompt": "Extract all books on this page. For each book, return the title, price, and star rating as a number from 1 to 5.",
    "output": "json"
}

response = requests.post(
    "https://api.spidra.io/scrape",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json"
    },
    json=payload
)

data = response.json()
print(json.dumps(data, indent=2))
</code></pre>
<p>That's the entire scraper. No <code>BeautifulSoup</code>, no selector logic, and no HTML parsing.</p>
<h3 id="heading-step-4-understand-the-output">Step 4: Understand the Output</h3>
<p>The API returns a structured JSON response. Each book is represented as an object with the fields you described:</p>
<pre><code class="language-json">{
  "results": [
    {
      "title": "A Light in the Attic",
      "price": "£51.77",
      "rating": 3
    },
    {
      "title": "Tipping the Velvet",
      "price": "£53.74",
      "rating": 1
    },
    {
      "title": "Soumission",
      "price": "£50.10",
      "rating": 1
    }
    ...
  ]
}
</code></pre>
<p>The model identified the star rating encoding (<code>star-rating Three</code> → 3) without being told how ratings are represented. It understood the intent of "star rating as a number from 1 to 5" and handled the mapping itself.</p>
<h3 id="heading-step-5-use-actions-for-multi-step-workflows">Step 5: Use Actions for Multi-Step Workflows</h3>
<p>Where AI scraping starts to show its real advantages is with workflows that would require significant engineering in a traditional scraper.</p>
<p>Suppose you want to visit each book's detail page and extract the full description and availability status (not just what's visible on the listing page).</p>
<p>In a traditional scraper, this means building a follow-link loop, managing state, handling errors on each detail page, and maintaining separate selectors for the detail page's different structure. In an AI scraper like Spidra, you can mimic a real human interaction with <a href="https://docs.spidra.io/features/actions">browser actions</a>:</p>
<pre><code class="language-python">{
  "urls": [{
    "url": "https://books.toscrape.com/catalogue/category/books/mystery_3/index.html",
    "actions": [{
      "type":            "forEach",
      "observe":         "Find all book cards in the product grid",
      "mode":            "inline",
      "captureSelector": "article.product_pod",
      "maxItems":        10,
      "itemPrompt":      "Extract the book title, price, and star rating (One/Two/Three/Four/Five). Return as JSON: {title, price, star_rating}"
    }]
  }]
}
</code></pre>
<p>The system navigates to each book's page, reads the new content, extracts the additional fields, and returns them as part of the same result set.</p>
<p>You can also configure how you want your data to be:</p>
<pre><code class="language-python">{
  "urls": [{ "url": "https://jobs.example.com/senior-engineer" }],
  "prompt": "Extract the job details",
  "schema": {
    "type": "object",
    "required": ["title", "company", "remote", "employment_type"],
    "properties": {
      "title":           { "type": "string" },
      "company":         { "type": "string" },
      "location":        { "type": ["string", "null"] },
      "remote":          { "type": ["boolean", "null"] },
      "salary_min":      { "type": ["number", "null"] },
      "salary_max":      { "type": ["number", "null"] },
      "employment_type": {
        "type": ["string", "null"],
        "enum": ["full_time", "part_time", "contract", null]
      },
      "skills": {
        "type": "array",
        "items": { "type": "string" }
      }
    }
  }
}
</code></pre>
<p>There is more to these AI scrapers, like <a href="https://docs.spidra.io/features/batch-scraping">batch scraping</a>, AI crawling, and lots more.</p>
<h3 id="heading-where-ai-scraping-earns-its-keep">Where AI Scraping Earns Its Keep</h3>
<p>Now suppose the site updates its frontend. The class <code>product_pod</code> gets renamed to <code>book-card</code>. The price moves into a different element.</p>
<p>In the traditional scraper, you get zero results and no error until you notice the data is missing. You then re-inspect the page, update the selectors, test, and redeploy.</p>
<p>In the AI scraper, you run the same prompt. The model isn't looking for <code>product_pod</code> or <code>price_color</code>. It's looking for content that resembles a product listing with pricing information. The layout change is invisible to the extraction logic.</p>
<p>This is the core operational advantage of the AI approach: <strong>structural changes to a page don't automatically break your extraction.</strong></p>
<h2 id="heading-traditional-scraping-vs-ai-scraping-when-to-use-each">Traditional Scraping vs AI Scraping: When to Use Each</h2>
<p>At this point, the difference between the two approaches is clear. The more important question is when each one actually makes sense in practice.</p>
<p>A simple way to think about it is this:</p>
<table>
<thead>
<tr>
<th><strong>Scenario</strong></th>
<th><strong>Traditional Scraping</strong></th>
<th><strong>AI Scraping</strong></th>
</tr>
</thead>
<tbody><tr>
<td>Stable websites</td>
<td>✅ Best choice</td>
<td>✅ Works but may sometimes become an overkill</td>
</tr>
<tr>
<td>Frequently changing layouts</td>
<td>❌ Breaks often</td>
<td>✅ More resilient</td>
</tr>
<tr>
<td>Large-scale crawling</td>
<td>✅ More cost-efficient</td>
<td>✅ Efficient but can get expensive</td>
</tr>
<tr>
<td>Fast prototyping</td>
<td>❌ Slower setup</td>
<td>✅ Very fast</td>
</tr>
<tr>
<td>Non-technical users</td>
<td>❌ Requires coding</td>
<td>✅ More accessible</td>
</tr>
<tr>
<td>Full control &amp; transparency</td>
<td>✅ High control</td>
<td>❌ Less transparent</td>
</tr>
<tr>
<td>Messy or inconsistent data</td>
<td>❌ Hard to maintain</td>
<td>✅ Easier to handle</td>
</tr>
<tr>
<td>Complex workflows (login, steps)</td>
<td>⚠️ Possible but manual</td>
<td>✅ Often built-in</td>
</tr>
</tbody></table>
<p>In practice, it's not a cut-and-dry choice between the two. Traditional scraping works best when everything is predictable and stable. AI scraping becomes useful when things are messy, dynamic, or time-sensitive. Most real-world systems combine both approaches rather than relying on one alone.</p>
<h2 id="heading-wrapping-up">Wrapping up</h2>
<p>Web scraping is not going away. What's changing is how we approach it.</p>
<p>Traditional scraping gives you control and precision, but it can be fragile and time-consuming to maintain. AI scraping makes things faster and more flexible, especially when dealing with messy or constantly changing pages, but it comes with less transparency.</p>
<p>In practice, most real-world workflows are starting to combine both.</p>
<p>We're also beginning to see AI scraping tools integrate into larger systems, especially with AI agents and MCP-style setups, where scraping becomes something that can be triggered on demand rather than built from scratch each time.</p>
<p>The key takeaway is simple. Traditional scraping tells the system where the data is. AI scraping tells the system what the data means.</p>
<p>Knowing when to use each is what actually matters.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Data Quality Handbook: Data Errors, the Developer's Role, and Validation Layers Explained. ]]>
                </title>
                <description>
                    <![CDATA[ In August 2012, Knight Capital, a major trading firm in the United States, deployed faulty trading software to its production system. The system used this incorrect configuration data and it triggered ]]>
                </description>
                <link>https://www.freecodecamp.org/news/data-quality-handbook-data-errors-the-developer-s-role-validation-layers/</link>
                <guid isPermaLink="false">69dea3b491716f3cfb75fd9d</guid>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Data Science ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Validation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Testing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Great John ]]>
                </dc:creator>
                <pubDate>Tue, 14 Apr 2026 20:29:40 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/4f0c9085-cb4f-4255-b7a0-e146eafc32c9.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In August 2012, Knight Capital, a major trading firm in the United States, deployed faulty trading software to its production system. The system used this incorrect configuration data and it triggered millions of unintended stock trades.</p>
<p>The company lost about $440 million in just 45 minutes. Knight Capital nearly collapsed and had to be rescued by investors. It was later acquired by another firm.</p>
<p>When Target expanded into Canada, the company relied on a new supply chain system that contained incorrect product and inventory data. Product information in the database was incomplete and inaccurate. Prices, sizes, and product descriptions were entered incorrectly.</p>
<p>Inventory systems reported items in stock that were actually unavailable. Customers found empty shelves in stores despite the system showing stock. The company lost over $2 billion in the Canadian market. Target eventually shut down all Canadian stores in 2015.</p>
<p>One employee made the statement “Even though we had a great supply chain system on paper, we didn’t have accurate data. Bad data leads to bad decisions’’</p>
<p>Another famous example of data-related engineering failures involves the Mars Climate Orbiter spacecraft. One engineering team used metric units (newtons). Another team used imperial units (pounds-force). The system failed to convert the data correctly. The spacecraft entered Mars' atmosphere at the wrong altitude. The mission failed and the spacecraft was destroyed. The loss was about $125 million.</p>
<p>In this article, we'll delve deep into what data quality truly means, the types of data errors that silently break systems, the developer’s responsibility in preventing them, and the validation layers that work together to keep bad data out of production.</p>
<h3 id="heading-what-well-cover">What We'll Cover:</h3>
<ul>
<li><p><a href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a href="#heading-the-importance-of-data-quality">The Importance of Data Quality</a></p>
<ul>
<li><p><a href="#heading-how-does-bad-data-happen-in-the-first-place">How Does Bad Data Happen in the First Place?</a></p>
</li>
<li><p><a href="#heading-the-cost-of-bad-data">The Cost of Bad Data</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-types-of-data-errors">Types of Data Errors</a></p>
<ul>
<li><p><a href="#heading-required-field-errors">Required Field Errors</a></p>
</li>
<li><p><a href="#heading-format-validation-errors">Format Validation Errors</a></p>
</li>
<li><p><a href="#heading-range-and-limit-errors">Range and Limit Errors</a></p>
</li>
<li><p><a href="#heading-logical-consistency-errors">Logical Consistency Errors</a></p>
</li>
<li><p><a href="#heading-duplicate-and-data-integrity-errors">Duplicate and Data Integrity Errors</a></p>
</li>
<li><p><a href="#heading-relational-errors-reference-integrity">Relational Errors (Reference Integrity)</a></p>
</li>
<li><p><a href="#heading-structural-errors-dropdowns-radio-buttons-enums">Structural Errors (Dropdowns, Radio Buttons, Enums)</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-what-makes-good-data">What Makes Good Data?</a></p>
<ul>
<li><p><a href="#heading-completeness">Completeness:</a></p>
</li>
<li><p><a href="#heading-uniqueness">Uniqueness:</a></p>
</li>
<li><p><a href="#heading-validity">Validity:</a></p>
</li>
<li><p><a href="#heading-timeliness">Timeliness:</a></p>
</li>
<li><p><a href="#heading-accuracy">Accuracy:</a></p>
</li>
<li><p><a href="#heading-consistency">Consistency:</a></p>
</li>
<li><p><a href="#heading-fitness-for-purpose">Fitness for Purpose:</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-data-validation-layers">Data Validation Layers</a></p>
<ul>
<li><p><a href="#heading-frontend-layer-protect-the-user-not-the-system">Frontend Layer — “Protect the User, Not the System”</a></p>
</li>
<li><p><a href="#heading-backend-validation-the-real-gatekeeper">Backend Validation — “The Real Gatekeeper”</a></p>
</li>
<li><p><a href="#heading-database-layer-protect-the-data-at-rest">Database Layer — “Protect the Data at Rest”</a></p>
</li>
<li><p><a href="#heading-service-layer-business-logic-validate-real-world-rules">Service Layer / Business Logic — “Validate Real-World Rules”</a></p>
</li>
<li><p><a href="#heading-jobs-queues-data-ingestion-validate-external-data">Jobs / Queues / Data Ingestion — “Validate External Data”</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-testing-strategies-to-protect-data-quality">Testing Strategies to Protect Data Quality</a></p>
<ul>
<li><p><a href="#heading-unit-testing-the-schema-amp-constraint-check">Unit Testing: The Schema &amp; Constraint Check</a></p>
</li>
<li><p><a href="#heading-integration-testing-the-flow-amp-lineage-check">Integration Testing: The Flow &amp; Lineage Check</a></p>
</li>
<li><p><a href="#heading-functional-testing-the-business-rule-check">Functional Testing: The Business Rule Check</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h3 id="heading-prerequisites">Prerequisites</h3>
<ul>
<li><p>A basic understanding of what data is</p>
</li>
<li><p>A basic understanding of data structures</p>
</li>
<li><p>An understanding of what an API is</p>
</li>
<li><p>An understanding of what a database is and what it does</p>
</li>
</ul>
<h2 id="heading-the-importance-of-data-quality">The Importance of Data Quality</h2>
<p>As you can see from just these few examples, the quality of the data you're working with really matters.</p>
<p>Gartner reports that organisations attribute <a href="https://www.forbes.com/councils/forbestechcouncil/2021/10/14/flying-blind-how-bad-data-undermines-business/"><strong>around $15 million in annual losses</strong></a> to poor‑quality data. The same research also shows that <a href="https://www.forbes.com/councils/forbestechcouncil/2021/10/14/flying-blind-how-bad-data-undermines-business/"><strong>nearly 60% of companies have no clear idea what bad data actually costs them</strong></a>, largely because they don’t track or measure data‑quality issues at all.</p>
<p>A 2016 study by IBM is even more eye-popping. IBM found that <a href="https://community.sap.com/t5/technology-blog-posts-by-sap/bad-data-costs-the-u-s-3-trillion-per-year/ba-p/13575387">poor data quality strips $3.1 trillion from the U.S. economy annually</a> due to lower productivity, system outages, and higher maintenance costs.</p>
<p>Bad data is, and will continue to be, the kryptonite of any organisation. This is even more concerning as more organisations now depend on data for strategy execution than ever before.</p>
<p>When data is wrong, incomplete, duplicated, or inconsistent, the consequences ripple outward: Incorrect dashboards mislead teams, which leads to making incorrect decisions. Implementing these decisions can lead to faulty strategy and policy implementation.</p>
<p>Eventually, the organisation pays the price, financially, operationally, and reputationally. And while money can be recovered, reputation rarely bounces back so easily.</p>
<h3 id="heading-how-does-bad-data-happen-in-the-first-place">How Does Bad Data Happen in the First Place?</h3>
<p>Form fields are usually the first place where data enters an application, so they’re often where bad data begins. This is why the developer’s role is so critical.</p>
<p>Many of the most damaging data errors don’t originate from malicious users or complex edge cases – they come from simple oversights that the system should never have allowed in the first place.</p>
<p>But it's equally important to recognise that data quality issues often originate <em>before</em> the data ever reaches an application. Upstream processes — how data is collected, measured, recorded, or pre‑validated — can introduce inaccuracies long before the system receives it.</p>
<p>For example, a nurse might weigh a patient using an uncalibrated mechanical scale, record the incorrect value on a paper form, and later have that value transcribed into the hospital system. By the time the data enters the application, the error is already embedded.</p>
<p>This means that maintaining data quality requires attention both to upstream data collection practices and to the system-level validation that developers control.</p>
<p>When the UI, backend, or API layer permits invalid, incomplete, inconsistent, or logically impossible data to enter the pipeline, the organisation inherits a long‑term liability. Even small choices — such as allowing empty fields, ignoring duplicates, or failing to enforce validation rules — can introduce errors that may only surface months later in reports or dashboards, leading to confusion and inaccurate insights.</p>
<h3 id="heading-the-cost-of-bad-data">The Cost of Bad Data</h3>
<p>Data quality can also be impacted at any stage of the data pipeline: before ingestion, in production, or even during analysis.</p>
<p>If bad data is caught in the UI, it's almost free, if we're thinking in terms of cost. If it's caught at the API layer, that's still pretty cheap. If it's caught in the database, the cost is moderate. And if it's caught in a report or ML model months later, that's expensive, and sometimes irreversible.</p>
<p>A key principle in modern data management is: the cheapest and safest place to catch bad data is at the source, and that is before ingestion. <a href="https://www.matillion.com/blog/the-1-10-100-rule-of-data-quality-a-critical-review-for-data-professionals">The well-known 1-10-100 Rule</a>, introduced by George Labovitz and Yu Sang Chang in 1992, clearly illustrates this idea.</p>
<p>According to the rule, it costs about \(1 to validate data at the point of entry, \)10 to correct it after it has entered the system, and $100 per record if the error goes unnoticed and causes problems further down the line.</p>
<p>As the saying goes, an ounce of prevention is worth a pound of cure – and this is especially true when it comes to maintaining high-quality data.</p>
<p>To help buttress my point, I’ve categorised the different types of errors and oversights that developers should never allow that can and should be prevented before they ever reach the database, analytics layer, or reporting systems.</p>
<h2 id="heading-types-of-data-errors">Types of Data Errors</h2>
<h3 id="heading-required-field-errors">Required Field Errors</h3>
<p>If you build a form that allows a user to submit a registration form with important fields left empty (like first name, last name, email address, phone number, date of birth, or address), you're directly letting incomplete data enter the system.</p>
<p>I remember a scenario from my time as a data analyst where I was analysing a dataset containing different types of alarms triggered across several buildings. These alarms fell into categories such as aquarium alarms, intruder alarms, fire alarms, and maintenance alarms.</p>
<p>The purpose of the analysis was simple: identify which buildings had the highest frequency of alarms so that maintenance, resources, or investigations could be allocated appropriately.</p>
<p>Whenever an alarm went off, the security team recorded it using a software system. By the end of each month, we could view the cumulative alarms and generate insights.</p>
<p>But I encountered a major data quality issue. The security officers often selected the alarm category but failed to submit the building where the alarm occurred — and the system allowed this incomplete record to be saved into the database.</p>
<p>Every alarm had to occur in a specific building. Yet during analysis, I would see entries like “20 fire alarms” with no building information attached. Since I couldn’t determine where these alarms happened, the data became unusable. I had no choice but to delete those records because they provided no actionable value.</p>
<p>This is a classic example of poor data validation. If the developer had implemented proper constraints, the system would never allow an alarm to be submitted without a building name.</p>
<p>Required fields should be enforced at the UI and backend levels to prevent missing data from entering the system in the first place. These gaps lead to missing or unusable data in the database, often forcing teams to delete or manually repair records later.</p>
<p>To prevent these errors, you can use required‑field validation, disable the submit button until all mandatory fields are completed, and visually highlight missing fields with inline error messages.</p>
<p>Here's a practical code example of some bad code (no required checks):</p>
<pre><code class="language-plaintext">&lt;form id="signup"&gt;
  &lt;input type="text" id="name" placeholder="Full name"&gt;
  &lt;input type="email" id="email" placeholder="Email"&gt;
  &lt;button type="submit"&gt;Sign up&lt;/button&gt;
&lt;/form&gt;

&lt;script&gt;
document.getElementById("signup").addEventListener("submit", e =&gt; {
  const name = document.getElementById("name").value;
  const email = document.getElementById("email").value;
  console.log("Submitted:", { name, email });
});
&lt;/script&gt;
</code></pre>
<p>From the above code snippet, the core problem is that the form doesn't enforce required input. Neither HTML‑level validation (using the <code>required</code> attribute) nor JavaScript‑based checks are implemented. This omission allows users to submit the form without providing necessary information, making the form unreliable for collecting valid and complete user data.</p>
<p>From a usability and data quality perspective, this is problematic. Forms are typically designed to collect meaningful and complete information, and fields such as “Full name” and “Email” are usually essential. Without marking these inputs as required or validating them programmatically, we risk receiving blank or invalid submissions, which can compromise the quality of stored data and any processes that depend on it.</p>
<p>Here's an example of a better version (UI prevents empty submission):</p>
<pre><code class="language-plaintext">&lt;form id="signup"&gt;
  &lt;input type="text" id="name" placeholder="Full name" required&gt;
  &lt;input type="email" id="email" placeholder="Email" required&gt;
  &lt;button type="submit"&gt;Sign up&lt;/button&gt;
&lt;/form&gt;

&lt;script&gt;
document.getElementById("signup").addEventListener("submit", e =&gt; {
  if (!e.target.checkValidity()) {
    e.preventDefault();
    alert("Please fill in all required fields.");
  }
});
&lt;/script&gt;
</code></pre>
<p>In this revised version of the code, the addition of the <code>required</code> attribute to both the name and email input elements ensures that the browser won't allow the form to be submitted unless these fields are filled. This is an important step toward maintaining data completeness and improving the overall reliability of the form.</p>
<p>Also, by checking <code>e.target.checkValidity()</code>, we now ensure that the form is evaluated before submission proceeds.</p>
<p>Another positive aspect is the conditional use of <code>e.preventDefault()</code>. When the form is invalid, the default submission behavior is stopped, preventing incomplete or incorrect data from being sent.</p>
<h3 id="heading-format-validation-errors">Format Validation Errors</h3>
<p>If you have a form that allows a user to enter an email without an @ symbol, an email without a domain, a phone number containing letters, or a postcode/ZIP code in the wrong format, that allows invalid data to enter the system.</p>
<p>The same applies when you allow a user to submit an impossible date (32/15/2025) or a credit card number with the wrong length.</p>
<p>These issues will cause the data analyst to spend more time cleaning the data, if it's even cleanable. And such incorrect inputs create unreliable data that breaks downstream processes and increases cleanup costs.</p>
<p>To prevent these types of errors, you can use regex validation, input masks, and field‑type restrictions (for example, numeric‑only fields for phone numbers) to enforce correct formats before submission.</p>
<p>Here's a bad example of allowing format validation errors:</p>
<pre><code class="language-plaintext">&lt;input id="phone" placeholder="Phone number"&gt;
&lt;button onclick="save()"&gt;Save&lt;/button&gt;

&lt;script&gt;
function save() {
  const phone = document.getElementById("phone").value;
  console.log("Saving phone:", phone);
}
&lt;/script&gt;
</code></pre>
<p>This code doesn't perform any checks on the format or structure of the phone number. The function simply retrieves whatever value exists –&nbsp;whether valid, invalid, or blank –&nbsp;and logs it to the console without any condition.</p>
<p>Here's the fixed version:</p>
<pre><code class="language-plaintext">&lt;input id="phone" placeholder="Phone number" required&gt;
&lt;button onclick="save()"&gt;Save&lt;/button&gt;

&lt;script&gt;
function save() {
  const phone = document.getElementById("phone").value;

  if (!/^\d+$/.test(phone)) {
    alert("Phone number must contain digits only.");
    return;
  }

  console.log("Saving phone:", phone);
}
&lt;/script&gt;
</code></pre>
<p>This version fixes the earlier mistake by introducing a clear validation rule. Before the system accepts the phone number, it checks whether the input contains only digits. The regular expression <code>^\d+$</code> ensures that the value is made up entirely of numbers, with no letters or symbols allowed. If the user enters anything invalid, the function stops and displays an error message instead of saving bad data.</p>
<p>This approach prevents the format error that occurred in the previous example. Instead of blindly trusting whatever the user types, the code now enforces a rule that matches the expected format of a phone number. This is what a responsible developer should do: verify the input before using it.</p>
<h3 id="heading-range-and-limit-errors">Range and Limit Errors</h3>
<p>Allowing users to enter values outside acceptable limits – such as negative ages, quantities below zero, discounts above 100%, or measurements far beyond realistic ranges – that enables the ingestion of data that violates business rules. These errors distort analytics, break calculations, and create operational inconsistencies.</p>
<p>To mitigate these errors, you can apply min/max constraints, sliders, steppers, and numeric boundaries to ensure values fall within valid ranges.</p>
<p>Here's a bad example of allowing range and limit errors:</p>
<pre><code class="language-plaintext">&lt;input id="age" type="number"&gt;
&lt;button onclick="submitAge()"&gt;Submit&lt;/button&gt;

&lt;script&gt;
function submitAge() {
  console.log("Age:", document.getElementById("age").value);
}
&lt;/script&gt;
</code></pre>
<p>As seen above, we've created an input field for age but doesn't specify any limits or constraints. The browser allows the user to type any number — including values that make no sense, such as negative ages, extremely large ages, or decimals. The JavaScript function simply reads the value and logs it without checking whether the age is realistic.</p>
<p>Here's a better version:</p>
<pre><code class="language-plaintext">&lt;input id="age" type="number" min="0" max="120" required&gt;
&lt;button onclick="submitAge()"&gt;Submit&lt;/button&gt;

&lt;script&gt;
function submitAge() {
  const ageInput = document.getElementById("age");
  if (!ageInput.checkValidity()) {
    alert("Age must be between 0 and 120.");
    return;
  }
  console.log("Age:", ageInput.value);
}
&lt;/script&gt;
</code></pre>
<p>Now in this version, the inclusion of the <code>min="0"</code> and <code>max="120"</code> attributes sets clear boundaries for acceptable input values. This ensures that only realistic age values within a defined range are allowed, preventing invalid entries such as negative numbers or excessively large ages.</p>
<p>The JavaScript function further enhances this validation by using the <code>checkValidity()</code> method. This method checks whether the input satisfies all defined constraints, including the required condition and the specified numeric range. If the input doesn't meet these conditions, the function prevents further execution and displays an alert message, informing the user that the entered age must fall within the allowed range.</p>
<h3 id="heading-logical-consistency-errors">Logical Consistency Errors</h3>
<p>If you allow a user to select an end date before the start date, choose a checkout date earlier than check‑in at a hotel, or enter a delivery date before the order date, this will result in logically impossible data. The same applies when you allow a user to enter a graduation year earlier than their admission to a program, or submit working hours that exceed 24 hours in a day.</p>
<p>You can mitigate this by implementing cross‑field validation, business‑rule checks, and conditional logic that ensures related fields remain consistent.</p>
<p>Here's a bad example of a logical consistency error:</p>
<pre><code class="language-plaintext">&lt;input type="date" id="start"&gt;
&lt;input type="date" id="end"&gt;
&lt;button onclick="save()"&gt;Save&lt;/button&gt;

&lt;script&gt;
function save() {
  console.log({
    start: document.getElementById("start").value,
    end: document.getElementById("end").value
  });
}
&lt;/script&gt;
</code></pre>
<p>In the code above, the core issue is the complete absence of validation. Although the inputs use <code>type="date"</code>, which provides a structured way for users to select dates, the code doesn't enforce that either field is required. This means the user can leave one or both date fields empty, and the <code>save()</code> function will still run and log the values. As a result, the system may end up processing incomplete or meaningless data.</p>
<p>Beyond missing required checks, the code also fails to validate the logical relationship between the two dates. In any scenario involving a start date and an end date, it's expected that the start date shouldn't occur after the end date. But this code performs no such comparison.</p>
<p>This means that the user can select a start date that's later than the end date, and the system will accept it without warning. This leads to inconsistent or impossible data being recorded.</p>
<p>Also, the function simply logs the values without providing any feedback to the user. There's no mechanism to alert the user when a field is empty or when the dates are logically incorrect. This reduces usability and makes it difficult for users to understand or correct their mistakes.</p>
<p>Here's the fixed version:</p>
<pre><code class="language-plaintext">&lt;input type="date" id="start" required&gt;
&lt;input type="date" id="end" required&gt;
&lt;button onclick="save()"&gt;Save&lt;/button&gt;

&lt;script&gt;
function save() {
  const startValue = document.getElementById("start").value;
  const endValue = document.getElementById("end").value;

  // Extra safety: check empties (in case required is bypassed)
  if (!startValue || !endValue) {
    alert("Both start and end dates are required.");
    return;
  }

  const start = new Date(startValue);
  const end = new Date(endValue);

  if (end &lt; start) {
    alert("End date cannot be before start date.");
    return;
  }

  console.log({ start, end });
}
&lt;/script&gt;
</code></pre>
<p>In this improved version, first, both date fields now include the <code>required</code> attribute, ensuring that the user can't leave either field empty without triggering validation.</p>
<p>Second, we've added a logical validation check to ensure that the relationship between the two dates is correct. After retrieving the values, the function converts them into <code>Date</code> objects and compares them to verify that the end date doesn't occur before the start date. If this condition is violated, the function stops execution and displays an alert informing the user of the error.</p>
<p>This prevents inconsistent or impossible date ranges from being accepted.</p>
<h3 id="heading-duplicate-and-data-integrity-errors">Duplicate and Data Integrity Errors</h3>
<p>When you let a user submit an email that's already registered, choose a username that's already taken, or enter a duplicate employee ID or student number, this results in identity conflicts and duplicate records. Problems also arise when you allow users to upload unsupported file types, oversized files, or corrupted images.</p>
<p>Security risks can emerge when users are able to enter HTML/script tags (XSS), SQL‑injection patterns, or disallowed special characters. These issues compromise data quality, system integrity, and security.</p>
<p>You can prevent these types of issues by using uniqueness checks, file‑type and size validation, and input sanitization to block duplicates, invalid uploads, and malicious inputs.</p>
<p>Here's an example of a duplicate error:</p>
<pre><code class="language-plaintext">&lt;input id="email" placeholder="Enter email" required&gt;
&lt;button onclick="save()"&gt;Save&lt;/button&gt;

&lt;script&gt;
const savedEmails = [];

function save() {
  const email = document.getElementById("email").value;
  savedEmails.push(email);
  console.log("Saved emails:", savedEmails);
}
&lt;/script&gt;
</code></pre>
<p>This code blindly pushes every email into the <code>savedEmails</code> array without checking whether the email already exists. Because there is no duplicate detection, the user can enter the same email multiple times.</p>
<p>Here is the fixed version:</p>
<pre><code class="language-plaintext">&lt;input id="email" placeholder="Enter email" required&gt;
&lt;button onclick="save()"&gt;Save&lt;/button&gt;

&lt;script&gt;
const savedEmails = [];

function save() {
  const email = document.getElementById("email").value.trim();

  // Check if the field is empty
  if (!email) {
    alert("Please enter an email before saving.");
    return;
  }

  // Check for duplicate
  if (savedEmails.includes(email)) {
    alert("This email has already been saved.");
    return;
  }

  savedEmails.push(email);
  console.log("Saved emails:", savedEmails);
}
&lt;/script&gt;

</code></pre>
<p>In this improved version of the code, we've implemented proper validation steps to prevent duplicate email entries. Before saving the email, the function checks whether the value already exists in the <code>savedEmails</code> array using the <code>includes()</code> method. If the email is found, the function stops execution and displays an alert informing the user that the email has already been saved. This ensures that each email is stored only once, maintaining the uniqueness and integrity of the data.</p>
<h3 id="heading-relational-errors-reference-integrity">Relational Errors (Reference Integrity)</h3>
<p>If you let a user select a city that doesn’t belong to the chosen country, a product ID that no longer exists, a retired SKU, or a shipping method unavailable in the selected region, this can result in broken references.</p>
<p>The same applies when users can select a manager from a different department or choose a fully booked time slot, not setting the right roles and permissions. These errors break relationships between tables and corrupt downstream joins and reports.</p>
<p>Here, you can use dependent dropdowns, real‑time lookups, and foreign‑key validation to help ensure that users can only select valid, existing, and compatible options.</p>
<p>Here's a bad example of a relational error:</p>
<pre><code class="language-plaintext">&lt;select id="country"&gt;
  &lt;option value="uk"&gt;United Kingdom&lt;/option&gt;
  &lt;option value="usa"&gt;United States&lt;/option&gt;
&lt;/select&gt;

&lt;select id="city"&gt;
  &lt;option value="london"&gt;London&lt;/option&gt;
  &lt;option value="manchester"&gt;Manchester&lt;/option&gt;
  &lt;option value="newyork"&gt;New York&lt;/option&gt;
  &lt;option value="losangeles"&gt;Los Angeles&lt;/option&gt;
&lt;/select&gt;

&lt;button onclick="save()"&gt;Save&lt;/button&gt;

&lt;script&gt;
function save() {
  const country = document.getElementById("country").value;
  const city = document.getElementById("city").value;

  console.log("Saving:", { country, city });
}
&lt;/script&gt;
</code></pre>
<p>From the above, the mistake in this code is that we've treated country and city as completely independent fields, even though one is supposed to depend on the other. By presenting all cities regardless of the selected country, the interface allows users to create combinations that make no sense — such as choosing “United Kingdom” with “New York” or “United States” with “Manchester.”</p>
<p>Also, because the <code>save()</code> function performs no validation and simply logs whatever the user selects, the system ends up accepting and storing relationships that should never exist. This breaks the logical link between the two fields and leads to invalid, inconsistent data that can corrupt downstream.</p>
<p>Here's the fixed, production-ready version:</p>
<pre><code class="language-plaintext">&lt;select id="country" onchange="loadCities()" required&gt;
  &lt;option value=""&gt;Select country&lt;/option&gt;
  &lt;option value="uk"&gt;United Kingdom&lt;/option&gt;
  &lt;option value="usa"&gt;United States&lt;/option&gt;
&lt;/select&gt;

&lt;select id="city" required disabled&gt;
  &lt;option value=""&gt;Select city&lt;/option&gt;
&lt;/select&gt;

&lt;button onclick="save()"&gt;Save&lt;/button&gt;

&lt;script&gt;
const citiesByCountry = {
  uk: ["London", "Manchester"],
  usa: ["New York", "Los Angeles"]
};

function loadCities() {
  const country = document.getElementById("country").value;
  const citySelect = document.getElementById("city");

  // Reset city dropdown
  citySelect.innerHTML = '&lt;option value=""&gt;Select city&lt;/option&gt;';

  // Disable if no country selected
  if (!country) {
    citySelect.disabled = true;
    return;
  }

  // Enable dropdown
  citySelect.disabled = false;

  // Load cities safely
  (citiesByCountry[country] || []).forEach(city =&gt; {
    const option = document.createElement("option");
    option.value = city.toLowerCase().replace(/\s+/g, ""); // remove ALL spaces
    option.textContent = city;
    citySelect.appendChild(option);
  });
}

function save() {
  const country = document.getElementById("country").value;
  const city = document.getElementById("city").value;

  // Required validation
  if (!country || !city) {
    alert("Please select both a country and a city.");
    return;
  }

  // Build list of valid cities for this country
  const validCities = (citiesByCountry[country] || [])
    .map(c =&gt; c.toLowerCase().replace(/\s+/g, ""));

  // Relational validation
  if (!validCities.includes(city)) {
    alert("Selected city does not belong to the chosen country.");
    return;
  }

  console.log("Saving:", { country, city });
}
&lt;/script&gt;
</code></pre>
<p>This improved code turns the country–city form into a controlled, relationship‑aware flow instead of two loose dropdowns.</p>
<p>When the user selects a country, the <code>loadCities()</code> function runs. It first clears the city dropdown and, if no country is selected, keeps the city field disabled so the user can't choose a city on its own.</p>
<p>Once a valid country is chosen, the city dropdown is enabled and populated only with the cities that belong to that specific country, using the <code>citiesByCountry</code> mapping. Also, the city values are normalised (lowercased and stripped of spaces) so they’re consistent and safe to compare.</p>
<p>When the user clicks “Save,” the <code>save()</code> function checks that both a country and a city have been selected. If either is missing, it shows an alert and stops. It then rebuilds the list of valid city values for the chosen country and verifies that the selected city is actually in that list.</p>
<h3 id="heading-structural-errors-dropdowns-radio-buttons-enums">Structural Errors (Dropdowns, Radio Buttons, Enums)</h3>
<p>If users can type a country as “U.S.A”, “USA”, “United States”, or “us”, enter gender as “male”, “Male”, “M”, or “man”, or type a department as “Engineering”, “Eng”, or “engineer”, this can result in inconsistent categorical data.</p>
<p>The same applies to currencies typed as “usd”, “USD”, “US Dollars”, product categories spelled differently, status values like “active”, “Active”, “ACT”, “enabled”, or boolean values like “yes”, “Yes”, “Y”, “1”.</p>
<p>These inconsistencies make analytics, grouping, and reporting unreliable, and the analyst will spend time cleaning and standardizing these files.</p>
<p>You should replace free‑text fields with dropdowns, radio buttons, and enums to enforce standardized categorical values.</p>
<p>Bad example of a structural error:</p>
<pre><code class="language-plaintext">&lt;form id="profile"&gt;
  &lt;label&gt;Country&lt;/label&gt;
  &lt;input type="text" id="country" placeholder="Enter country"&gt;
  &lt;button type="submit"&gt;Save&lt;/button&gt;
&lt;/form&gt;

&lt;script&gt;
document.getElementById("profile").addEventListener("submit", e =&gt; {
  e.preventDefault();
  const country = document.getElementById("country").value;
  console.log("Saving:", country);
});
&lt;/script&gt;
</code></pre>
<p>The problem with this code is that it pretends to save a country value without doing any real validation or enforcing any rules, which makes the form unreliable and prone to bad data.</p>
<p>The form uses a plain text input for “country,” meaning the user can type anything they want — misspellings, random characters, invalid countries, or even leave it blank. Because the input isn’t marked as required and the JavaScript doesn’t check whether the field contains a meaningful value, the form will happily “save” an empty string or nonsense text.</p>
<p>The <code>submit</code> handler prevents the default form submission but does nothing beyond logging whatever the user typed, so the system accepts invalid, incomplete, or malformed data without question. In short, the code collects input but doesn't validate it, doesn't enforce correctness, and doesn't protect the system from bad or unusable values.</p>
<p>Here's the fixed version:</p>
<pre><code class="language-plaintext">&lt;form id="profile"&gt;
  &lt;label&gt;Country&lt;/label&gt;
  &lt;select id="country" required&gt;
    &lt;option value=""&gt;Select country&lt;/option&gt;
    &lt;option value="uk"&gt;United Kingdom&lt;/option&gt;
    &lt;option value="usa"&gt;United States&lt;/option&gt;
    &lt;option value="canada"&gt;Canada&lt;/option&gt;
  &lt;/select&gt;

  &lt;button type="submit"&gt;Save&lt;/button&gt;
&lt;/form&gt;

&lt;script&gt;
document.getElementById("profile").addEventListener("submit", e =&gt; {
  e.preventDefault();

  const country = document.getElementById("country").value;

  // Required validation
  if (!country) {
    alert("Please select a country before saving.");
    return;
  }

  console.log("Saving:", country);
});
&lt;/script&gt;
</code></pre>
<p>The biggest improvement is that we're no longer relying on a free‑text field for the country. By switching to a dropdown, the form now limits the user to a controlled set of valid options. This prevents misspellings, random text, or invalid country names from ever entering the system.</p>
<p>These are the main types of data errors you might come across in your work. Now that we've discussed what causes them and some key fixes/preventative measures you can take, let's move on to data quality itself.</p>
<h2 id="heading-what-makes-good-data">What Makes Good Data?</h2>
<p>So what, in fact, is data quality? <a href="https://www.ibm.com/products/tutorials/6-pillars-of-data-quality-and-how-to-improve-your-data">IBM defines it</a> as the degree of accuracy, consistency, completeness, reliability, and relevance of the data collected, stored, and used within an organization or a specific context.</p>
<p>Let's look at each of these features of quality data a bit more closely to understand what they entail.</p>
<h3 id="heading-completeness">Completeness:</h3>
<p>Completeness measures how much of the required data is actually present. When large portions of fields are missing, the dataset stops representing reality and any analysis built on it becomes unreliable.</p>
<p>An example would be a sign‑up form that stores users, but half of them are missing an email address. If you run an analysis on “email engagement,” your results will be skewed because a big chunk of users can’t even receive emails. This means that this data is incomplete.</p>
<h3 id="heading-uniqueness">Uniqueness:</h3>
<p>Uniqueness checks whether each real‑world entity appears only once in the dataset. Duplicate records inflate counts, break joins, and distort metrics.</p>
<p>An example would be a customer table containing two rows for the same person with the same customer ID. When calculating “active customers,” the system counts them twice, inflating revenue projections.</p>
<h3 id="heading-validity">Validity:</h3>
<p>Validity evaluates whether data follows the expected format, type, or business rules. This includes correct data types, allowed ranges, and patterns defined by the system.</p>
<p>An example would be a field meant to store dates contains values like “32/99/2025” or “tomorrow.” These invalid entries break downstream ETL jobs that expect a proper date format.</p>
<h3 id="heading-timeliness">Timeliness:</h3>
<p>Timeliness reflects whether data is available when it’s needed. Even accurate data becomes useless if it arrives too late for the process that depends on it. For example, after a customer places an order, the system should generate an order ID instantly.</p>
<h3 id="heading-accuracy">Accuracy:</h3>
<p>Accuracy measures how closely data matches the real‑world truth. When multiple systems report the same metric, one must be designated as the authoritative source to avoid conflicting values.</p>
<h3 id="heading-consistency">Consistency:</h3>
<p>Consistency checks whether data aligns across different datasets or within related fields. If two systems describe the same concept, their values shouldn't contradict each other.</p>
<p>For example, a company’s HR system reports 50 employees in Engineering, but the payroll system lists only 42. Since both describe the same group, the mismatch signals a data quality issue.</p>
<h3 id="heading-fitness-for-purpose">Fitness for Purpose:</h3>
<p>Fitness for purpose assesses whether the data is suitable for the specific business task at hand. Even complete, accurate, and timely data may be unhelpful if it doesn’t answer the intended question.</p>
<p>A dataset of website clicks might be perfect for analysing user engagement, for example, but it’s useless for forecasting revenue because it contains no purchase or pricing information.</p>
<h2 id="heading-data-validation-layers">Data Validation Layers</h2>
<p>Now that we've highlighted the characteristics that ensure quality data, it's important to discuss the layers of data validation.</p>
<p>There are five layers you'll need to check to enforce data quality.</p>
<h3 id="heading-frontend-layer-protect-the-user-not-the-system">Frontend Layer — “Protect the User, Not the System”</h3>
<p>Frontend validation plays an important role in enhancing the user experience – but it doesn't provide real protection for a system.</p>
<p>Since frontend logic operates within the user’s environment, we can't trust it as a mechanism for enforcing data quality. Any code executed in the browser is ultimately under the user’s control, meaning it can be disabled, modified, intercepted, or bypassed entirely.</p>
<p>For instance, a user can simply open browser developer tools, remove validation rules, and submit invalid or malicious data without restriction.</p>
<p>Frontend validation is incapable of enforcing complex business rules. Constraints such as ensuring that a discounted price is lower than the original price, validating that a start date precedes an end date, preventing stock levels from becoming negative, or confirming that a product belongs to a valid category within the database require deeper system-level checks.</p>
<p>At the frontend level, what is being validated is: required fields, email format, password strength, address fields, and payment input format.</p>
<p>So frontend validation doesn't guarantee data quality or security, as it can be bypassed through API tools (like Postman), disabled JavaScript, malicious bots, and third-party integrations.</p>
<p>Because of this, it's best to treat the front-end as a usability layer, not a trust layer.</p>
<h3 id="heading-backend-validation-the-real-gatekeeper">Backend Validation — “The Real Gatekeeper”</h3>
<p>You can only guarantee true data quality and system integrity at the backend and database layers.</p>
<p>The backend is responsible for enforcing request validation, implementing business logic, and managing authentication and authorization.</p>
<p>If validation fails here, invalid data is rejected before it can propagate. Without this layer, data corruption begins at ingestion.</p>
<p>For example:</p>
<pre><code class="language-plaintext">$request-&gt;validate([
   'name' =&gt; 'required|string|max:255',
   'price' =&gt; 'required|numeric|min:0',
   'stock' =&gt; 'required|integer|min:0',
   'category_id' =&gt; 'required|exists:categories,id',
]);
</code></pre>
<p>The code snippet above demonstrates how you can use request validation in Laravel to ensure that incoming data meets specific requirements before it's processed or stored in the database. This is an essential practice in web development, as it helps maintain data integrity, prevents errors, and enhances application security.</p>
<p>In this example, we're using the <code>$request-&gt;validate()</code> method to define a set of validation rules for four input fields: <code>name</code>, <code>price</code>, <code>stock</code>, and <code>category_id</code>. Each field is assigned a series of constraints that the incoming data must satisfy.</p>
<p>The name field is marked as required, meaning it must be included in the request and can't be empty. It must also be a string, ensuring that only textual data is accepted, and it's limited to a maximum length of 255 characters using <code>max:255</code>. This prevents excessively long inputs that could potentially cause issues in the database or user interface.</p>
<p>Similarly, the price field is required and must be numeric, allowing only numbers such as integers or decimal values. The rule <code>min:0</code> ensures that the price can't be negative, which is logically consistent for most product pricing scenarios.</p>
<p>The stock field is also required and must be an integer, meaning it can only accept whole numbers. This is appropriate for counting physical items. Like the price field, it includes a <code>min:0</code> rule to prevent negative stock values, which would not make sense in an inventory system.</p>
<p>Finally, the category_id field is validated to ensure it is both present and valid. The <code>required</code> rule ensures that a category is selected, while the <code>exists:categories,id</code> rule checks that the provided value corresponds to an existing id in the categories database table. This prevents invalid or non-existent category references, thereby preserving relational integrity within the database.</p>
<p>This layer validates null values, data types and formats, allowed ranges, and referential integrity (exists).</p>
<h3 id="heading-database-layer-protect-the-data-at-rest">Database Layer — “Protect the Data at Rest”</h3>
<p>Validation at the application level is insufficient on its own. You'll also need to enforce database-level constraints like NOT NULL constraints, UNIQUE constraints (email, SKU, order number), foreign keys (orders.user_id → users.id), and check constraints (for example, price &gt;= 0).</p>
<p>This layer is critical because application bugs may bypass validation, background jobs and imports may skip controllers, and malicious actors may attempt direct access.</p>
<p>The database layer acts as the final line of defense, ensuring structural integrity regardless of application failures. Database constraints are the last hard stop: they enforce correctness even when code is bypassed.</p>
<h3 id="heading-service-layer-business-logic-validate-real-world-rules">Service Layer / Business Logic — “Validate Real-World Rules”</h3>
<p>This layer enforces domain-specific logic that can't be captured by simple validation rules. The service layer is where the application stops asking “Is this data shaped correctly?” and starts asking “Is this allowed to happen in the real world?”.</p>
<p>This layer enforces domain‑specific rules that can't be captured by simple request validation or database constraints. These rules reflect business truth, not structural correctness.</p>
<p><strong>Example:</strong></p>
<pre><code class="language-plaintext">if (\(product-&gt;stock &lt; \)quantity) {
   throw new OutOfStockException();
}
</code></pre>
<p>This prevents overselling and ensures the system reflects physical reality.</p>
<pre><code class="language-plaintext">if (\(cartTotal !== \)calculatedTotal) {
   throw new PriceMismatchException();
}
</code></pre>
<p>This protects revenue and prevents tampering.</p>
<p>In this layer, you enforce real‑world business rules by ensuring inventory correctness, recalculating totals, applying discount logic, and checking user‑specific limits.</p>
<h3 id="heading-jobs-queues-data-ingestion-validate-external-data">Jobs / Queues / Data Ingestion — “Validate External Data”</h3>
<p>When importing or processing external data (for example, supplier feeds), validation must occur before processing. You'll need to ensure schema conformity, that the required columns are present, that you have the correct data types, that the JSON structure is valid, and that you're detecting duplicate batches.</p>
<p>This is because external data sources are a major source of data quality issues. Without validation here, corrupted data can silently enter the system at scale.</p>
<p>Now that we've discussed the layers of a modern application stack, it should be clear that data quality isn't something you “check once” at the UI.</p>
<p>It must be enforced repeatedly, at multiple depths of the system. Each layer catches a different class of defects, and together they form a defensive wall that prevents bad data from ever reaching storage, analytics, or downstream consumers.</p>
<h2 id="heading-testing-strategies-to-protect-data-quality">Testing Strategies to Protect Data Quality</h2>
<p>To wrap up, here are the three foundational testing strategy every developer should apply to protect data quality.</p>
<h3 id="heading-unit-testing">Unit Testing</h3>
<p>Unit tests are the first line of defense in data quality. In this context, a “unit” refers to a single column, a single transformation, or a single validation rule.</p>
<p>The purpose is straightforward: verify that the smallest building blocks of your data logic behave exactly as intended. This matters because if these low‑level rules are not tested and validated, incorrect or inconsistent data will flow into the database and contaminate everything built on top of it.</p>
<p>By isolating each rule or transformation, you can guarantee that schema constraints, field‑level assumptions, and low‑level logic remain correct before data ever flows into larger pipelines or business processes.</p>
<p>Typical questions answered at this layer include:</p>
<ol>
<li><p>Does this column allow nulls?</p>
</li>
<li><p>Does this regex correctly strip whitespace from email strings?</p>
</li>
<li><p>Does this transformation produce the expected output for a single row?</p>
</li>
</ol>
<p>This is where you can verify that the data contract is sound. If a column must be non‑null, unique, or follow a specific pattern, the unit test enforces it. When these rules fail here, they fail cheaply – before they can corrupt a table or mislead a dashboard.</p>
<p>To make this concrete, here’s what a unit test looks like in a real codebase. Even though this example comes from Laravel, the testing principle is identical to data‑quality unit tests: one rule, one expectation, isolated from everything else.</p>
<h4 id="heading-example-testing-a-discount-calculation-rule">Example: Testing a Discount Calculation Rule</h4>
<p>Imagine your e‑commerce shop has this rule:</p>
<ul>
<li><p>If a product costs more than £100, apply a 10% discount.</p>
</li>
<li><p>Otherwise, apply no discount.</p>
</li>
</ul>
<p>Let's say this is your discount logic:</p>
<pre><code class="language-plaintext">&lt;?php

namespace App\Services;

class DiscountService
{
    public function calculate(float $price): float
    {
        if ($price &gt; 100) {
            return $price * 0.10; // 10% discount
        }

        return 0;
    }
}
</code></pre>
<p>The unit test for this logic will be:</p>
<pre><code class="language-plaintext">&lt;?php

namespace Tests\Unit;

use Tests\TestCase;
use App\Services\DiscountService;

class DiscountServiceTest extends TestCase
{
    /** @test */
    public function it_applies_10_percent_discount_when_price_is_above_100()
    {
        $service = new DiscountService();

        \(discount = \)service-&gt;calculate(200);

        \(this-&gt;assertEquals(20, \)discount);
    }

    /** @test */
    public function it_applies_no_discount_when_price_is_100_or_below()
    {
        $service = new DiscountService();

        \(discount = \)service-&gt;calculate(100);

        \(this-&gt;assertEquals(0, \)discount);
    }
}
</code></pre>
<p>The <code>DiscountService</code> contains a simple rule: if a price is greater than 100, a 10% discount is applied. Otherwise, no discount is applied. The unit test verifies this rule in isolation, without involving controllers, databases, or HTTP requests. By testing the service directly, the developer ensures that the core calculation behaves exactly as intended.</p>
<p>The first test checks the positive case — a price of 200 should produce a discount of 20. The second test checks the boundary condition — a price of 100 should produce no discount. Together, these tests confirm both sides of the rule and protect against regressions if the logic changes in the future.</p>
<p>Now, since this is Laravel example, Laravel tests help you verify both your logic (unit tests) and your full application behaviour (feature tests). You can run them using <code>php artisan test</code>, which executes tests in a separate testing environment, ensuring your real database and main codebase remain safe and unaffected.</p>
<h3 id="heading-integration-testing-the-flow-amp-lineage-check">Integration Testing: The Flow &amp; Lineage Check</h3>
<p>While unit tests validate the correctness of individual rules, integration tests validate the movement of data across components. Integration testing verifies that multiple layers work together as a single data flow.</p>
<p>In this example, the controller receives an order, calls the discount service, applies the transformation, and persists the result to the database. That interaction across layers is what elevates this from a unit test to an integration test. This is where you test the real‑world flow:</p>
<ol>
<li><p>Controller → Service → Repository → MySQL</p>
</li>
<li><p>Check if MySQL migrations run correctly</p>
</li>
<li><p>Check foreign keys enforce relationships</p>
</li>
<li><p>Check to ensure services interact with the database as expected</p>
</li>
<li><p>Check to ensure models and repositories behave consistently</p>
</li>
</ol>
<p>Integration tests reveal issues that only appear when components interact: incorrect joins, broken migrations, mismatched field names, or subtle type mismatches that unit tests cannot detect.</p>
<p>This is the layer where you catch the bugs that would otherwise silently corrupt data lineage.</p>
<p><strong>Here's an example:</strong></p>
<pre><code class="language-plaintext">&lt;?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\Order;
use Illuminate\Foundation\Testing\RefreshDatabase;

class ApplyDiscountTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function check_it_persists_the_correct_discounted_total_to_the_database()
    {
        $order = Order::factory()-&gt;create(['subtotal' =&gt; 150]);

        \(response = \)this-&gt;postJson("/orders/{$order-&gt;id}/apply-discount");

        $response-&gt;assertStatus(200);

        $this-&gt;assertDatabaseHas('orders', [
            'id' =&gt; $order-&gt;id,
            'grand_total' =&gt; 135, // 150 - 10% discount
            'discount_total' =&gt; 15
        ]);
    }
}
</code></pre>
<p>This represents a full flow rather than a single rule:</p>
<ul>
<li><p>Controller → Service</p>
</li>
<li><p>Service → Calculation</p>
</li>
<li><p>Controller → Database write</p>
</li>
<li><p>Database → Final state</p>
</li>
</ul>
<p>This test begins by creating an order using an Eloquent factory. It immediately steps beyond the boundaries of a unit test, since it interacts with the database and relies on Laravel’s model layer to persist real data.</p>
<p>From there, the test sends an actual HTTP POST request to the <code>/orders/{id}/apply-discount</code> endpoint, which means it's not calling a method directly, but instead it's traveling through Laravel’s routing layer, invoking the controller responsible for handling the request, and triggering whatever business logic is responsible for calculating and applying the discount.</p>
<p>This movement through multiple layers (routing, controller, service logic, and model persistence) is precisely what defines integration testing: the goal is to verify that these components work together correctly as a system.</p>
<p>Once the request is processed, the test asserts that the response returns a successful status code, which confirms that the HTTP layer behaved as expected.</p>
<p>But the most important part comes afterward, when the test checks the database to ensure that the correct <code>grand_total</code> and <code>discount_total</code> were saved. This final assertion proves that the discount logic was executed, the model was updated, and the changes were successfully written to the database.</p>
<p>In other words, the test isn't merely checking whether a calculation is correct. It's also checking whether the entire pipeline –&nbsp;from receiving the request to updating the database –&nbsp;functions as a coherent whole.</p>
<h3 id="heading-functional-testing-the-business-rule-check">Functional Testing: The Business Rule Check</h3>
<p>Functional tests validate the entire user experience, from the moment a request enters the system to the moment a response is returned. This includes:</p>
<ul>
<li><p>HTTP requests</p>
</li>
<li><p>Controller logic</p>
</li>
<li><p>Validation rules</p>
</li>
<li><p>Service operations</p>
</li>
<li><p>Database writes</p>
</li>
<li><p>Redirects or rendered views</p>
</li>
</ul>
<p>This is where you test the business rules that govern real‑world behaviour:</p>
<p>“A student can't register for two exams at the same time.”</p>
<p>“A cart can't have negative quantities.”</p>
<p>“A user can't update their profile without a valid email.”</p>
<p>Functional tests ensure that the system behaves correctly from the perspective of the user and the business, not just the code.</p>
<h4 id="heading-heres-an-example-functional-test">Here's an example: Functional Test</h4>
<pre><code class="language-plaintext">&lt;?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\Product;
use Illuminate\Foundation\Testing\RefreshDatabase;

class CartQuantityFunctionalTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function a_user_cannot_set_a_negative_cart_quantity()
    {
        // Arrange: create a product
        $product = Product::factory()-&gt;create(['price' =&gt; 40]);

        // Simulate existing cart
        $this-&gt;withSession([
            'cart' =&gt; [
                $product-&gt;id =&gt; ['quantity' =&gt; 2]
            ]
        ]);

        // Act: user tries to update quantity to a negative number
        \(response = \)this-&gt;post('/cart/update', [
            'product_id' =&gt; $product-&gt;id,
            'quantity' =&gt; -5
        ]);

        // Assert: system rejects invalid business behaviour
        $response-&gt;assertStatus(302); // redirect back with errors
        $response-&gt;assertSessionHasErrors(['quantity']);

        // Assert: cart remains unchanged (business rule preserved)
        \(this-&gt;assertEquals(2, session('cart')[\)product-&gt;id]['quantity']);
    }
}
</code></pre>
<p>The test begins by creating a realistic environment in which a user interacts with a shopping cart. This is essential for understanding the behaviour the system is meant to enforce.</p>
<p>First, it generates a real product in the database using a factory, giving the product a price so that it resembles an item a customer might genuinely add to their cart.</p>
<p>Once the product exists, the test manually seeds the session with a cart containing that product and a quantity of two. This simulates a user who has already added the item to their cart in a previous interaction, and it establishes the baseline state the system must preserve if the user attempts an invalid update.</p>
<p>With the environment prepared, the test then imitates a user action by sending a POST request to the <code>/cart/update</code> endpoint. Instead of calling a method directly, it uses Laravel’s HTTP layer to reproduce the exact behaviour of a browser submitting a form. The request includes the product ID and a deliberately invalid quantity of negative five.</p>
<p>This is the heart of the scenario: the user is attempting something that violates the business rules of the application, and the test is designed to confirm that the system responds appropriately.</p>
<p>Now, when the request is processed, the test expects the application to reject the input, redirect the user back, and attach validation errors to the session. The assertion that the response has a 302 status code and contains validation errors confirms that the validation layer is functioning correctly and that the controller is enforcing the rule that quantities can't be negative.</p>
<p>The final part of the test is where the business rule is truly verified. After the failed update attempt, the test inspects the session to ensure that the cart remains unchanged. This is crucial because rejecting invalid input is only half of the requirement: the system must also protect the integrity of the existing cart data.</p>
<p>Functional tests answer questions like:</p>
<ul>
<li><p>Does the system prevent invalid real‑world behaviour?</p>
</li>
<li><p>Does the user get the correct feedback?</p>
</li>
<li><p>Does the data remain consistent after the request?</p>
</li>
<li><p>Does the final output match the business expectation?</p>
</li>
</ul>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Data quality is never the result of a single check or a single team. It emerges from a disciplined, layered approach where each testing level catches a different category of defects.</p>
<p>Unit tests safeguard the smallest rules, integration tests validate the flow of data across components, and functional tests enforce the business logic that governs real‑world behaviour.</p>
<p>When these layers operate together, bad data has nowhere to hide. When they don’t, even a minor oversight can slip through the cracks and escalate into a costly downstream failure.</p>
<p>So as you can see, your role in data quality is fundamentally proactive, not reactive. By designing systems with validation, integrity, and monitoring in mind, you ensure that data flowing through the pipeline is accurate, timely, complete, unique, and fit for purpose – supporting reliable analytics, reporting, and intelligent systems.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Modern React Data Fetching Handbook: Suspense, use(), and ErrorBoundary Explained ]]>
                </title>
                <description>
                    <![CDATA[ Most React developers don’t break the data fetching process all at once. It usually degrades gradually, slowly. Traditionally, you may have used a useEffect here, a loading flag there, and an error state along with it to tackle data fetching. Moving ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-modern-react-data-fetching-handbook-suspense-use-and-errorboundary-explained/</link>
                <guid isPermaLink="false">698def824dcd2f8caf2d36ef</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tapas Adhikary ]]>
                </dc:creator>
                <pubDate>Thu, 12 Feb 2026 15:19:30 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1770847474747/df826db8-4d18-45f5-a4aa-bfafa9c3aa80.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Most React developers don’t break the data fetching process all at once. It usually degrades gradually, slowly.</p>
<p>Traditionally, you may have used a <code>useEffect</code> here, a loading flag there, and an error state along with it to tackle data fetching. Moving forward, another fetch depended on the first one, then a second useEffect, and another loading and error state.</p>
<p>This likely continued until you started feeling like you were writing code that you yourself could’t even maintain in the future.</p>
<p>Requests that should run in parallel started running sequentially. Components re-rendered unnecessarily just to satisfy another data fetch request-response. Loading spinners appeared when nothing meaningfully changed. Error states got scattered inside the component.</p>
<p>Well, none of these things are React’s problem. These are core design problems you should be aware of while coding your React Apps.</p>
<p>In this handbook, we’ll walk through one React Pattern that fixes data fetching at the architecture level without ignoring real data dependencies, and without introducing any new magic. If data fetching in React has ever felt harder than it should be, this pattern will make even more sense to you.</p>
<p>You’ll learn how to use React’s <code>Suspense</code> with the recently introduced <code>use()</code> API to handle data fetching smoothly. In case of errors, you’ll learn how an <code>Error Boundary</code> can help handle them gracefully.</p>
<p>Give this one a read, and code along to get a better grip on this pattern’s mental model.</p>
<p>This handbook is also available as a video tutorial as part of the <a target="_blank" href="https://www.youtube.com/playlist?list=PLIJrr73KDmRyQVT__uFZvaVfWPdfyMFHC">15 Days of React Design Patterns</a> <a target="_blank" href="https://www.youtube.com/playlist?list=PLIJrr73KDmRyQVT__uFZvaVfWPdfyMFHC">initiative</a>. You can check it out if you’d like:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/tY8rhkLdr2A" 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>We’ll use a lot of source code to demonstrate the problems with the traditional data-fetching approach and how the Suspense Pattern can improve things. I would suggest that you try the code as you read. But if you want to take a look at the source code ahead of time, you can find it on the <a target="_blank" href="https://github.com/tapascript/15-days-of-react-design-patterns/tree/main/day-16">tapaScript GitHub</a>.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-the-traditional-way-of-data-fetching-in-react">The Traditional Way of Data Fetching in React</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-the-problem-with-the-traditional-way">The Problem with the Traditional Way</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-lets-build-a-dashboard-with-the-traditional-data-fetching-approach">Let’s Build a Dashboard with the Traditional Data Fetching Approach</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-suspense">What is Suspense?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-the-use-api-in-react">What is the <code>use()</code> API in React?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-suspense-and-the-use-api-for-data-fetching">How to Use Suspense and the <code>use()</code> API for Data Fetching</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-lets-build-the-dashboard-with-suspense-and-the-use-api">Let’s Build the Dashboard with Suspense and the <code>use()</code> API</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-project-setup">Project Setup</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-api-services">API Services</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-create-a-centralised-user-resource">Create a Centralised User Resource</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-create-individual-components">Create Individual Components</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-create-the-fallback-ui">Create the Fallback UI</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-create-the-dashboard-component-with-suspense">Create the Dashboard Component with Suspense</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-run-the-dashboard-app">Run the Dashboard App</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-handle-error-scenarios-with-error-boundaries">How to Handle Error Scenarios with Error Boundaries?</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-error-boundary">Error Boundary</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-suspense-and-error-boundary">Suspense and Error Boundary</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-learn-from-the-15-days-of-react-design-patterns">Learn from the 15 Days of React Design Patterns</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-before-we-end">Before We End…</a></p>
</li>
</ol>
<h2 id="heading-the-traditional-way-of-data-fetching-in-react">The Traditional Way of Data Fetching in React</h2>
<p>To understand why data fetching can become painful in React, we first need to understand how React works under the hood.</p>
<p>React works in phases. It doesn’t do everything at once. At a high level, every update in React goes through three distinct phases:</p>
<ul>
<li><p><strong>Render phase</strong> – React figures out <em>what</em> the UI should look like</p>
</li>
<li><p><strong>Commit phase</strong> – React applies those changes to the DOM</p>
</li>
<li><p><strong>Effect phase</strong> – React synchronises with the outside world</p>
</li>
</ul>
<p>This separation is intentional. It’s what allows React to be predictable, interruptible, and efficient.</p>
<p>Now, let’s see where data fetching with <code>useEffect</code> fits into this picture:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770089281941/9a0dbc5d-6b45-4813-9e62-8bc4cbad82ea.png" alt="The useEffect Phases" class="image--center mx-auto" width="1642" height="781" loading="lazy"></p>
<p>Where does <code>useEffect</code> actually run? It doesn’t run during rendering. It runs after React has already committed the UI to the DOM.</p>
<p>That means the flow looks like this:</p>
<ol>
<li><p>React renders the component (without data)</p>
</li>
<li><p>React commits the UI</p>
</li>
<li><p>useEffect runs</p>
</li>
<li><p>Data fetching starts</p>
</li>
<li><p>State updates when the data arrives</p>
</li>
<li><p>React renders again</p>
</li>
</ol>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
  fetchData().then(setData);
}, []);
</code></pre>
<p>Hence, the fetch only starts after the UI has already rendered.</p>
<h3 id="heading-the-problem-with-the-traditional-way">The Problem with the Traditional Way</h3>
<p>Consider a very common scenario: you fetch a user, and then fetch related data using the user ID.</p>
<p>The traditional React data fetching solution would look like this:</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
  fetchUser().then(setUser);
}, []);

useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">if</span> (!user) <span class="hljs-keyword">return</span>;
  fetchOrders(user.id).then(setOrders);
}, [user]);
</code></pre>
<p>What actually happens is:</p>
<ul>
<li><p>The component renders</p>
</li>
<li><p>React commits the UI</p>
</li>
<li><p>The first effect runs and fetches the user</p>
</li>
<li><p>React re-renders</p>
</li>
<li><p>The second effect runs and fetches orders</p>
</li>
</ul>
<p>Even if the network is fast, the requests are forced to start one after another, because each fetch is triggered by a render that only happens after the previous fetch completes.</p>
<p>This paradigm of data fetching is called <code>Fetch-On-Render</code>. The fetching logic is no longer controlled by data dependencies – it’s controlled by render timing. But that’s not all. There are other problems with this approach: you create and maintain unnecessary states.</p>
<p>Now, let’s see both these problems in action by building something practical.</p>
<h2 id="heading-lets-build-a-dashboard-with-the-traditional-data-fetching-approach">Let’s Build a Dashboard with the Traditional Data Fetching Approach</h2>
<p>Let’s build a simple dashboard with the traditional data fetching approach using the <code>useEffect</code> hook at the center. The dashboard will have four primary sections:</p>
<ul>
<li><p>A Static heading.</p>
</li>
<li><p>A <code>Profile</code> section welcoming the user with their name.</p>
</li>
<li><p>An <code>Order</code> section listing the items ordered by the user.</p>
</li>
<li><p>An <code>Analytics</code> section showing a few metrics for the same user.</p>
</li>
</ul>
<p>You can visualise it like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770184122812/d8cd8d82-9f38-4ab6-b029-e2e68dbbd66a.png" alt="Dashboard" class="image--center mx-auto" width="806" height="919" loading="lazy"></p>
<p>The profile, order, and analytics sections should show the dynamic data of a user and their order and analytics. Hence, we’ll simulate three API calls to get the user details, order details, and the analytics data.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// API to fetch User</span>
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchUser</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> {
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      resolve({ <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">"Tapas"</span> });
    }, <span class="hljs-number">1500</span>);
  });
}

<span class="hljs-comment">// API to fetch the Orders of a User</span>
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchOrders</span>(<span class="hljs-params">userId</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      resolve([
          <span class="hljs-string">`Order A for user <span class="hljs-subst">${userId}</span>`</span>,
          <span class="hljs-string">`Order B for user <span class="hljs-subst">${userId}</span>`</span>
      ]);
    }, <span class="hljs-number">1500</span>);
  });
}

<span class="hljs-comment">// API to fetch the Analytics of a User</span>
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchAnalytics</span>(<span class="hljs-params">userId</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> {
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      resolve({
        <span class="hljs-attr">revenue</span>: <span class="hljs-string">"$12,000"</span>,
        <span class="hljs-attr">growth</span>: <span class="hljs-string">"18%"</span>,
        userId
      });
    }, <span class="hljs-number">1500</span>);
  });
}
</code></pre>
<p>As you can see in this code:</p>
<ul>
<li><p>Each of the API functions returns a promise.</p>
</li>
<li><p>There is an intentional delay of 1.5 seconds using setTimeout to simulate the feel of a network call. The promise resolves after the delay passes.</p>
</li>
<li><p>Once the promise gets resolved, we get the data.</p>
</li>
</ul>
<p>Now, let’s create the Dashboard component:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { fetchAnalytics, fetchOrders, fetchUser } <span class="hljs-keyword">from</span> <span class="hljs-string">"../api"</span>;

<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">Dashboard</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [user, setUser] = useState(<span class="hljs-literal">null</span>);
    <span class="hljs-keyword">const</span> [orders, setOrders] = useState(<span class="hljs-literal">null</span>);
    <span class="hljs-keyword">const</span> [analytics, setAnalytics] = useState(<span class="hljs-literal">null</span>);

    <span class="hljs-comment">// Step 1: Fetch user</span>
    useEffect(<span class="hljs-function">() =&gt;</span> {
        fetchUser().then(setUser);
    }, []);

    <span class="hljs-comment">// Step 2: Fetch orders (depends on user)</span>
    useEffect(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-keyword">if</span> (!user) <span class="hljs-keyword">return</span>;
        fetchOrders(user.id).then(setOrders);
    }, [user]);

    <span class="hljs-comment">// Step 3: Fetch analytics (depends on user)</span>
    useEffect(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-keyword">if</span> (!user) <span class="hljs-keyword">return</span>;
        fetchAnalytics(user.id).then(setAnalytics);
    }, [user]);

    <span class="hljs-comment">// Logic to ensure that user, orders, and analytics data </span>
    <span class="hljs-comment">// loaded before we render them on JSX</span>
    <span class="hljs-keyword">if</span> (!user || !orders || !analytics) {
        <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl m-3"</span>&gt;</span>Loading dashboard...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>;
    }

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"m-2"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-5xl mb-12"</span>&gt;</span>📊 Dashboard<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-3xl"</span>&gt;</span>Welcome, {user.name}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-3xl mt-3"</span>&gt;</span>Orders<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
                {orders.map((o) =&gt; (
                    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl"</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{o}</span>&gt;</span>
                        {o}
                    <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
                ))}
            <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-3xl mt-3"</span>&gt;</span>Analytics<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl"</span>&gt;</span>Revenue: {analytics.revenue}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl"</span>&gt;</span>Growth: {analytics.growth}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
}
</code></pre>
<p>Let’s break it down:</p>
<ul>
<li><p>The first thing you’ll notice is that we have three states for holding the data of users, orders, and analytics.</p>
</li>
<li><p>Then we have three <code>useEffect</code>s to manage the fetching of data and updating the states.</p>
</li>
<li><p>Then we show the data values in the JSX.</p>
</li>
<li><p>We’re using a <code>Fetch-On-Render</code> methodology.</p>
</li>
</ul>
<p>However, in between, there’s an explicit logic to check if the user data, order data, or analytics data has been loaded. If the data are not loaded, then we don’t even process the JSX – rather, we show a loading message.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Logic to ensure that user, orders, and analytics data </span>
<span class="hljs-comment">// loaded before we render them on JSX</span>
<span class="hljs-keyword">if</span> (!user || !orders || !analytics) {
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl m-3"</span>&gt;</span>Loading dashboard...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>;
}
</code></pre>
<p>This is good as a measure so that the UI doesn’t crash at runtime. But this is not a declarative approach. Since React is declarative, it would make more sense if we could handle this scenario in a declarative way as well.</p>
<p>In <code>Declarative programming</code>, you as a programmer don’t specify how to to solve certain problems. You declare what you want to achieve, and the programming language/framework takes care of the “how” part for you. When you specify the “how” part, it becomes <code>imperative</code>, not declarative.</p>
<p>React is declarative because you don’t specify how to update the browser DOM to render the UI changes. You declare them using JSX, and React takes care of it under the hood.</p>
<p>As an alternative to the explicit imperative logic like the above, you could also handle it using loading states. You could have loading states for profile, orders, and analytics. The loading states could decide when to show the data conditionally. But this approach needs additional state management and conditional rendering of JSX.</p>
<p>Along with these issues, think of handling errors! Again, you would need states for error handling and the conditional logic to show and hide the error messages. That’s too much to manage.</p>
<p>So, with the <code>useEffect</code> strategy, data fetching in React is not that effective. We need a better pattern to handle data along with loading states and errors.</p>
<p>But before we move on, I want to clarify that <code>useEffect</code> isn’t bad. It has a purpose, but sometimes we don’t use it as intended. If you’re someone who wants to learn the effective usages of this hook and how to debug it properly, you can <a target="_blank" href="https://www.youtube.com/watch?v=z2VnpJ6st-4">check out this session</a>.</p>
<h2 id="heading-what-is-suspense">What is Suspense?</h2>
<p>At its core, React <code>Suspense</code> is not a loading feature. It’s a rendering coordination mechanism. Suspense allows a component to tell React, “I’m not ready to be rendered, yet”. When that happens, React pauses rendering for that part of the tree and shows a fallback UI until the required data becomes available.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770193224537/fb10d206-11f0-4cdf-b984-bfcf07b19ae8.png" alt="Suspense Mechanism" class="image--center mx-auto" width="1296" height="1043" loading="lazy"></p>
<p>This is fundamentally different from how data fetching works with useEffect.</p>
<p>With the traditional <code>Fetch-On-Render</code> approach, React must first render a component before it’s allowed to start fetching data. Effects run after the commit phase, which means data fetching is always a reaction to rendering, never a prerequisite for it. As applications grow, this creates render-fetch-re-render loops, hidden waterfalls, and loading logic spread across components.</p>
<p>Suspense flips that model.</p>
<p>Instead of rendering first and fetching later, Suspense enables <code>Render-as-you-Fetch</code>. Data fetching can begin before React attempts to commit the UI, and rendering simply waits until the data is ready. The UI doesn’t guess when to show loading states. React coordinates it declaratively through Suspense boundaries.</p>
<p>With Suspense, you need to wrap the component that handles the asynchronous call.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770195686150/1160a43a-6be0-488a-aa19-315ac9f33985.png" alt="Suspense as Wrapper" class="image--center mx-auto" width="1137" height="472" loading="lazy"></p>
<p>Suspense can pause the rendering while the wrapped component is dealing with the promise. Suspense can show a fallback UI (it could be a loader, UI skeleton, and so on) until the promise is resolved (or rejected). Once the promise is resolved, Suspense replaces the fallback UI with the actual wrapped component baked with the data. No hard-coded logic, no extra state management is needed.</p>
<h2 id="heading-what-is-the-use-api-in-react">What is the <code>use()</code> API in React?</h2>
<p><code>use()</code> is an API introduced in React 19 that accepts a promise and returns its resolved value. If the promise hasn’t resolved yet, React doesn’t continue rendering. It suspends. If the promise fails, React throws an error. Both cases are handled declaratively by Suspense and Error Boundaries.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { use } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchUser</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> fetch(<span class="hljs-string">"/api/user"</span>).then(<span class="hljs-function"><span class="hljs-params">res</span> =&gt;</span> res.json());
}

<span class="hljs-keyword">const</span> userPromise = fetchUser();

<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">Profile</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> user = use(userPromise);
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Welcome, {user.name}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span>;
}
</code></pre>
<p><strong>What’s important here:</strong></p>
<ul>
<li><p><code>use()</code> is called during render</p>
</li>
<li><p>If the promise is unresolved, rendering pauses</p>
</li>
<li><p>No <code>useEffect</code>, no loading state</p>
</li>
</ul>
<p><code>use()</code> is very powerful. It can read promises that depend on other promises.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> userPromise = fetch(<span class="hljs-string">"/api/user"</span>).then(<span class="hljs-function"><span class="hljs-params">r</span> =&gt;</span> r.json());

<span class="hljs-keyword">const</span> ordersPromise = userPromise.then(<span class="hljs-function"><span class="hljs-params">user</span> =&gt;</span>
  fetch(<span class="hljs-string">`/api/orders?userId=<span class="hljs-subst">${user.id}</span>`</span>).then(<span class="hljs-function"><span class="hljs-params">r</span> =&gt;</span> r.json())
);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Orders</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> orders = use(ordersPromise);
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
      {orders.map(o =&gt; <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{o.id}</span>&gt;</span>{o.title}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>)}
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span>
  );
}
</code></pre>
<p>Here:</p>
<ul>
<li><p>Dependencies are expressed in data, not effects</p>
</li>
<li><p>Rendering is coordinated automatically (declaratively)</p>
</li>
</ul>
<p>The primary mental model is: this render is not allowed to complete without this data. It suspends.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> data = use(promise);
</code></pre>
<p>We need to use Suspense to handle this gap (when the promise hasn’t resolved yet) using a fallback UI, and then to continue rendering once the promise is resolved.</p>
<h2 id="heading-how-to-use-suspense-and-the-use-api-for-data-fetching">How to Use Suspense and the <code>use()</code> API for Data Fetching</h2>
<p>The <code>use()</code> API is what finally makes Suspense practical for data fetching. Before <code>use()</code>, Suspense could pause rendering, but React didn’t have a clean way to consume asynchronous data during render without hacks. Most examples relied on custom abstractions or libraries to bridge that gap. <code>use()</code> changed that by allowing React components to read async values directly during rendering.</p>
<p>When a component reads data using <code>use(promise)</code>, React treats that promise as a render dependency. If the promise hasn’t resolved yet, React pauses rendering at the nearest Suspense boundary. When it resolves, React retries rendering automatically, without manual state updates, effects, or conditional logic.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { Suspense, use } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> userPromise = fetch(<span class="hljs-string">"/api/user"</span>).then(<span class="hljs-function"><span class="hljs-params">res</span> =&gt;</span> res.json());

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Profile</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> user = use(userPromise);
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Welcome, {user.name}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span>;
}

<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">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Suspense</span> <span class="hljs-attr">fallback</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">p</span>&gt;</span>Loading profile...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>}&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">Profile</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Suspense</span>&gt;</span></span>
  );
}
</code></pre>
<p><strong>What happens here:</strong></p>
<ul>
<li><p>Profile tries to read userPromise</p>
</li>
<li><p>If the promise is unresolved, React pauses rendering</p>
</li>
<li><p>React renders the nearest Suspense fallback</p>
</li>
<li><p>When the promise resolves, React retries rendering automatically</p>
</li>
</ul>
<p>Here, there are no effects, no loading flags, and no manual re-rendering.</p>
<p>Now, let’s see all these in action together by rebuilding the same Dashboard app.</p>
<h2 id="heading-lets-build-the-dashboard-with-suspense-and-the-use-api">Let’s Build the Dashboard with Suspense and the <code>use()</code> API</h2>
<p>Now that we have a better understanding of Suspense and <code>use()</code>, let’s rewrite the same Dashboard application with it.</p>
<h3 id="heading-project-setup">Project Setup</h3>
<p>First, you’ll need to create a React project scaffolding using <a target="_blank" href="https://vite.dev/guide/#scaffolding-your-first-vite-project">Vite</a>. You can use the following command to create a Vite-based React project with modern toolings:</p>
<pre><code class="lang-bash">npx degit atapas/code-in-react-19<span class="hljs-comment">#main suspense-patterns</span>
</code></pre>
<p>This will create a React 19 project with TailwindCSS configured.</p>
<p>Now use the <code>npm install</code> command to install the dependencies. This will create the node_modules folder for you. At this point, the directory structure should look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770281531136/c34dcf94-7142-4033-9445-53b08d010a5e.png" alt="React 19 Project Directory Structure" class="image--center mx-auto" width="384" height="752" loading="lazy"></p>
<h3 id="heading-api-services">API Services</h3>
<p>Now under <code>src/</code>, create a new folder called <code>api/</code>. Then create an <code>index.js</code> file under <code>src/app/</code> with the following code snippet:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchUser</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> {
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      resolve({ <span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">"Tapas"</span> });
    }, <span class="hljs-number">1500</span>);
  });
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchOrders</span>(<span class="hljs-params">userId</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      resolve([
          <span class="hljs-string">`Order A for user <span class="hljs-subst">${userId}</span>`</span>,
          <span class="hljs-string">`Order B for user <span class="hljs-subst">${userId}</span>`</span>
      ]);
    }, <span class="hljs-number">1500</span>);
  });
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchAnalytics</span>(<span class="hljs-params">userId</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> {
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      resolve({
        <span class="hljs-attr">revenue</span>: <span class="hljs-string">"$12,000"</span>,
        <span class="hljs-attr">growth</span>: <span class="hljs-string">"18%"</span>,
        userId
      });
    }, <span class="hljs-number">1500</span>);
  });
}
</code></pre>
<p>These are the same APIs we used before when constructing the dashboard with <code>useEffect</code>.</p>
<ul>
<li><p><code>fetchUser</code>: For fetching the user’s profile</p>
</li>
<li><p><code>fetchOrders</code>: For fetching the orders made by a user</p>
</li>
<li><p><code>fetchAnalytics</code>: For fetching the analytics data of a user</p>
</li>
</ul>
<h3 id="heading-create-a-centralised-user-resource">Create a Centralised User Resource</h3>
<p>Now, let’s create a centralised JavaScript utility file where we can create each of the promises by calling their respective fetch methods. It’s a good practice to handle all the fetch APIs and their promises from a single place, rather than keeping them scattered. The same utility can export the promises so that we can consume them in the components.</p>
<p>Create a <code>resources/</code> folder under <code>src/</code>. Create a file <code>userResource.js</code> file under <code>src/resources/</code> with the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { fetchAnalytics, fetchOrders, fetchUser } <span class="hljs-keyword">from</span> <span class="hljs-string">"../api"</span>;

<span class="hljs-keyword">let</span> userPromise;
<span class="hljs-keyword">let</span> ordersPromise;
<span class="hljs-keyword">let</span> analyticsPromise;

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createUserResources</span>(<span class="hljs-params"></span>) </span>{
  userPromise = fetchUser();

  ordersPromise = userPromise.then(<span class="hljs-function"><span class="hljs-params">user</span> =&gt;</span>
    fetchOrders(user.id)
  );

  analyticsPromise = userPromise.then(<span class="hljs-function"><span class="hljs-params">user</span> =&gt;</span>
    fetchAnalytics(user.id)
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUserResources</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> {
    userPromise,
    ordersPromise,
    analyticsPromise
  };
}
</code></pre>
<p>Here, we export two functions:</p>
<ol>
<li><p>The <code>createUserResources()</code> creates all the promises and keeps them ready.</p>
</li>
<li><p>The <code>getUserResources()</code> returns all the promises we can consume later.</p>
</li>
</ol>
<p>Now, the question is, when will we create these promises? That is, where we will call the <code>createUserResources()</code> function? We should create these promises when the application starts up, and the <code>main.jsx</code> file would be the perfect place for that.</p>
<p>Open the main.jsx file, import <code>{createUserResources}</code>, and invoke it immediately.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">"react-dom/client"</span>;
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">"./App.jsx"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"./index.css"</span>;

<span class="hljs-keyword">import</span> { createUserResources } <span class="hljs-keyword">from</span> <span class="hljs-string">"./resources/userResource.js"</span>;

createUserResources();

ReactDOM.createRoot(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>)).render(
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">React.StrictMode</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">React.StrictMode</span>&gt;</span></span>,
);
</code></pre>
<p>Great! Our data fetching APIs and the promises are ready. Let’s create the components where we’ll be using these promises.</p>
<h3 id="heading-create-individual-components">Create Individual Components</h3>
<p>We’ll create three components to compose the dashboard: Profile, Orders, and Analytics.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770297241100/91d9c21b-afcb-40ee-a73d-34a2be0f8cad.png" alt="Component Hierarchy" class="image--center mx-auto" width="1291" height="582" loading="lazy"></p>
<p>Let’s start with the Profile component. Create a folder <code>components/</code> under the <code>src/</code>. Now, create a <code>Profile.jsx</code> with the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { use } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { getUserResources } <span class="hljs-keyword">from</span> <span class="hljs-string">"../resources/userResource"</span>;

<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">Profile</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> { userPromise } = getUserResources();
    <span class="hljs-keyword">const</span> user = use(userPromise);
    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-3xl"</span>&gt;</span>Welcome, {user.name}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span>;
}
</code></pre>
<p>Let’s break it down:</p>
<ul>
<li><p>We imported the <code>use()</code> from React, as we’ll be dealing with the use promise here to handle it and get the user name to render.</p>
</li>
<li><p>Next, we need the user promise. We have the <code>getUserResources()</code> function to get that, so we imported it.</p>
</li>
<li><p>Then, inside the Profile component, we destructured <code>userPromise</code> from the <code>getUserResources()</code> function.</p>
</li>
<li><p>After that, we passed the promise to the <code>use()</code>. We have learned that the <code>use()</code> API accepts a promise and returns the result when it is resolved. Until then, the passed-in promise itself will be returned.</p>
</li>
<li><p>Finally, we used the resolved <code>user</code> to extract the name property and render it.</p>
</li>
</ul>
<p>Simple, right? Let’s quickly create the Orders and Analytics components.</p>
<p>The Orders component:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { use } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { getUserResources } <span class="hljs-keyword">from</span> <span class="hljs-string">"../resources/userResource"</span>;

<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">Orders</span>(<span class="hljs-params"></span>) </span>{
   <span class="hljs-keyword">const</span> { ordersPromise } = getUserResources();
  <span class="hljs-keyword">const</span> orders = use(ordersPromise);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-3xl mt-2"</span>&gt;</span>Orders<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
        {orders.map((o) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl"</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{o}</span>&gt;</span>{o}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/&gt;</span></span>
  );
}
</code></pre>
<p>It has the same flow as the Profile component.</p>
<p>Now, let’s do the Analytics component:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { use } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { getUserResources } <span class="hljs-keyword">from</span> <span class="hljs-string">"../resources/userResource"</span>;

<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">Analytics</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> { analyticsPromise } = getUserResources();
    <span class="hljs-keyword">const</span> analytics = use(analyticsPromise);

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-3xl mt-2"</span>&gt;</span>Analytics<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl"</span>&gt;</span>Revenue: {analytics.revenue}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl"</span>&gt;</span>Growth: {analytics.growth}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/&gt;</span></span>
    );
}
</code></pre>
<p>All three components are ready. Before we move further, let’s reflect once more on what we learned about <code>Suspense</code>.</p>
<p>Suspense wraps a component that deals with promises (async operations). Until the promise gets resolved, the Suspense holds the rendering and can show a fallback UI in the meantime. Once the promise gets resolved and we have the value, the fallback UI gets swapped with the actual component Suspense wrapped.</p>
<p>So, we have the ideal case now: wrapping the <code>&lt;Profile /&gt;</code>, <code>&lt;Orders/&gt;</code>, and <code>&lt;Analytics/&gt;</code> with the <code>&lt;Suspense&gt;…&lt;/Suspense&gt;</code> boundary to handle the promises and resolved data for each of the components.</p>
<p>Let’s do that, but aren’t we missing something? Yeah we are: the fallback UI. Let’s create it.</p>
<h3 id="heading-create-the-fallback-ui">Create the Fallback UI</h3>
<p>Now we’ll create three different fallback UI components. Create a file <code>Skeletons.jsx</code> under the <code>src/components/</code> with the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> ProfileSkeleton = <span class="hljs-function">() =&gt;</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-3xl m-2"</span>&gt;</span>Loading user...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> OrdersSkeleton = <span class="hljs-function">() =&gt;</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-3xl m-2"</span>&gt;</span>Loading orders...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> AnalyticsSkeleton = <span class="hljs-function">() =&gt;</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-3xl m-2"</span>&gt;</span>Loading analytics...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>;
</code></pre>
<p>We now have a fallback skeleton UI for each of our components. These are very simple components that just render loading messages.</p>
<h3 id="heading-create-the-dashboard-component-with-suspense">Create the Dashboard Component with Suspense</h3>
<p>Now we have everything to make our Dashboard work. Create a <code>suspense/</code> folder under <code>src/</code>. Then create a <code>Dashboard.jsx</code> file under <code>src/suspense/</code> with the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { Suspense } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">import</span> Analytics <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/Analytics"</span>;
<span class="hljs-keyword">import</span> Orders <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/Orders"</span>;
<span class="hljs-keyword">import</span> Profile <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/Profile"</span>;

<span class="hljs-keyword">import</span> {
    AnalyticsSkeleton,
    OrdersSkeleton,
    ProfileSkeleton,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/Skeletons"</span>;

<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">Dashboard</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"m-2"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-5xl mb-12"</span>&gt;</span>📊 Dashboard<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">Suspense</span> <span class="hljs-attr">fallback</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">ProfileSkeleton</span> /&gt;</span>}&gt;
               <span class="hljs-tag">&lt;<span class="hljs-name">Profile</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">Suspense</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Suspense</span> <span class="hljs-attr">fallback</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">OrdersSkeleton</span> /&gt;</span>}&gt;
               <span class="hljs-tag">&lt;<span class="hljs-name">Orders</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">Suspense</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Suspense</span> <span class="hljs-attr">fallback</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">AnalyticsSkeleton</span> /&gt;</span>}&gt;
               <span class="hljs-tag">&lt;<span class="hljs-name">Analytics</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">Suspense</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
}
</code></pre>
<p>First, let me explain the code:</p>
<ul>
<li><p>We imported Suspense from React, all the components, and all the fallback UI components.</p>
</li>
<li><p>Then we rendered a static header and three suspense boundaries for each of the components. We wrapped Profile, Orders, and Analytics with Suspense, respectively. To handle the pending promise state, we have passed the individual skeleton component as the fallback to the suspense.</p>
</li>
</ul>
<p>How clean is this? If you scroll up and recheck our old implementation of the dashboard using useEffect and compare it with the one we created with suspense, the positive differences are clear.</p>
<ul>
<li><p>It’s declarative.</p>
</li>
<li><p>There’s less code, with the chance of fewer bugs</p>
</li>
<li><p>There’s no effect management and synchronisations</p>
</li>
<li><p>There’s no conditional JSX</p>
</li>
</ul>
<p>It’s a huge win 🏆.</p>
<h3 id="heading-run-the-dashboard-app">Run the Dashboard App</h3>
<p>To run the dashboard app, import the dashboard component in the <code>App.jsx</code> file and use it like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Dashboard <span class="hljs-keyword">from</span> <span class="hljs-string">"./suspense/Dashboard"</span>;
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex items-center justify-center gap-12"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">Dashboard</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>Next, open the terminal. Run the app using the <code>npm run dev</code> command. You get the same dashboard back, but it’s much improved:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770184122812/d8cd8d82-9f38-4ab6-b029-e2e68dbbd66a.png" alt="New dashboard" class="image--center mx-auto" width="806" height="919" loading="lazy"></p>
<ul>
<li><p>It loads the data of each of the sections independently.</p>
</li>
<li><p>Each of the sections shows the data loading indicator when the promise is pending.</p>
</li>
<li><p>It doesn’t block the entire UI.</p>
</li>
</ul>
<p>Suspense and <code>use()</code> together are very powerful. Now you have learned that powerful pattern end-to-end.</p>
<h2 id="heading-how-to-handle-error-scenarios-with-error-boundaries">How to Handle Error Scenarios with Error Boundaries</h2>
<p>This data fetching handbook wouldn’t be complete without talking about error scenarios and how to handle them. So far, we’ve spoken about only the happy path. But what if any of the promises are rejected? How do we handle that?</p>
<p>To understand this in depth, let’s reject one of the promises – say the Order promise. Open the <code>index.js</code> file under the <code>src/api/</code> folder and replace the <code>fetchOrder()</code> function with this updated code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchOrders</span>(<span class="hljs-params">userId</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-comment">// Simulate failure</span>
      <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Math</span>.random() &lt; <span class="hljs-number">0.5</span>) {
        reject(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Failed to fetch orders"</span>));
      } <span class="hljs-keyword">else</span> {
        resolve([
          <span class="hljs-string">`Order A for user <span class="hljs-subst">${userId}</span>`</span>,
          <span class="hljs-string">`Order B for user <span class="hljs-subst">${userId}</span>`</span>
        ]);
      }
    }, <span class="hljs-number">1500</span>);
  });
}
</code></pre>
<p>Here, the changes are:</p>
<ul>
<li><p>We have simulated a failure by rejecting a promise.</p>
</li>
<li><p>The promise gets rejected randomly and throws an error with an error message.</p>
</li>
</ul>
<p>At this point, if you refresh the UI a few times, you’ll randomly get a blank broken UI with the error message logged into the browser console. This isn’t ideal. It kills the UX of the app.</p>
<p>A better way of handling would be to show the error message on the UI and provide a way to retry and check if the user can recover from the error.</p>
<p>This is where <code>Error Boundary</code> comes in.</p>
<h3 id="heading-error-boundary">Error Boundary</h3>
<p>Error Boundaries in React exist for a simple reason: Errors are inevitable, and we must handle them gracefully. There could be:</p>
<ul>
<li><p>Network requests fail</p>
</li>
<li><p>Data is malformed</p>
</li>
<li><p>The assumptions break</p>
</li>
</ul>
<p>Without boundaries, a single tiny rendering error can crash the entire React tree. Error Boundaries provide React with a structured way to handle failures.</p>
<p>Technically, an Error Boundary is a component that catches errors thrown during rendering. When an error occurs, React stops rendering the subtree and renders a fallback UI instead.</p>
<p>Let’s now create an Error Boundary. Create a file called <code>ErrorBoundary.jsx</code> under <code>src/components</code> with the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { Component } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { createUserResources } <span class="hljs-keyword">from</span> <span class="hljs-string">"../resources/userResource"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ErrorBoundary</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span> </span>{
  state = { <span class="hljs-attr">error</span>: <span class="hljs-literal">null</span> };

  <span class="hljs-keyword">static</span> getDerivedStateFromError(error) {
    <span class="hljs-keyword">return</span> { error };
  }

  handleRetry = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">this</span>.setState({ <span class="hljs-attr">error</span>: <span class="hljs-literal">null</span> });
    createUserResources();
  };

  render() {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.state.error) {
      <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"border border-red-700 rounded p-1"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl"</span>&gt;</span>{this.state.error.message}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span> 
                <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-orange-400 rounded-xl p-1 text-black cursor-pointer"</span> 
                <span class="hljs-attr">onClick</span>=<span class="hljs-string">{this.handleRetry}</span>&gt;</span>
            Retry
          <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
      );
    }

    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.props.children;
  }
}
</code></pre>
<p>Now, let’s understand what’s going on in the code above:</p>
<ul>
<li><p>This is a class component that inherits from <code>React.Component</code>. That’s because Error Boundaries must use class lifecycle methods, which are not available in function components.</p>
</li>
<li><p>The component keeps track of whether an error has occurred. <code>state = { error: null }</code> means everything is rendering normally. When an error happens, this state will store the error object.</p>
</li>
<li><p>The <code>static getDerivedStateFromError()</code> is a special lifecycle method. React automatically calls it when a child component throws an error during render.</p>
</li>
<li><p>The <code>handleRetry()</code> method resets the error state back to null. It calls the <code>createUserResources()</code> to reinitialise the async resources.</p>
</li>
<li><p>In the <code>render()</code> method, if an error exists, render a fallback UI, show the error message, and provide an ability to retry the error using a retry button. If no error exists, render the <code>children</code> normally. The Error Boundary becomes invisible when everything works without an error. The fallback UI also can be an external component that we can pass as a prop to the Error Boundary.</p>
</li>
</ul>
<p>If you’re interested in diving deep into the <code>Error Boundary</code> pattern and want to learn various use cases of it, <a target="_blank" href="https://www.youtube.com/watch?v=0qxF4jb-eUg">here is a dedicated video</a> you can check out.</p>
<h3 id="heading-suspense-and-error-boundary">Suspense and Error Boundary</h3>
<p>Next, we’ll now use the Error Boundary to wrap each of the Suspense boundaries so that if an error originated from any of those, it can be managed. Open the <code>Dashboard.jsx</code> file and wrap each of the Suspense boundaries with the <code>ErrorBoundary</code> component as shown below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { Suspense } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> Analytics <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/Analytics"</span>;
<span class="hljs-keyword">import</span> ErrorBoundary <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/ErrorBoundary"</span>;
<span class="hljs-keyword">import</span> Orders <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/Orders"</span>;
<span class="hljs-keyword">import</span> Profile <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/Profile"</span>;
<span class="hljs-keyword">import</span> {
    AnalyticsSkeleton,
    OrdersSkeleton,
    ProfileSkeleton,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/Skeletons"</span>;

<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">Dashboard</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"m-2"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-5xl mb-12"</span>&gt;</span>📊 Dashboard<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">ErrorBoundary</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">Suspense</span> <span class="hljs-attr">fallback</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">ProfileSkeleton</span> /&gt;</span>}&gt;
                    <span class="hljs-tag">&lt;<span class="hljs-name">Profile</span> /&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">Suspense</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">ErrorBoundary</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">ErrorBoundary</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">Suspense</span> <span class="hljs-attr">fallback</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">OrdersSkeleton</span> /&gt;</span>}&gt;
                    <span class="hljs-tag">&lt;<span class="hljs-name">Orders</span> /&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">Suspense</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">ErrorBoundary</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">ErrorBoundary</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">Suspense</span> <span class="hljs-attr">fallback</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">AnalyticsSkeleton</span> /&gt;</span>}&gt;
                    <span class="hljs-tag">&lt;<span class="hljs-name">Analytics</span> /&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">Suspense</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">ErrorBoundary</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
    );
}
</code></pre>
<p>That’s it. Now, access the dashboard on the browser. Whenever the order promise rejects, we’ll get the fallback error UI from the error boundary. Note, the remaining UI isn’t broken and rendered successfully. The partial failure of the UI is also recoverable, as we have provided a retry button to attempt to revive that portion. It provides a great UX.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770301723655/36fbba52-805b-4a23-8d18-9516a413160e.png" alt="Error Boundary with Suspense" class="image--center mx-auto" width="644" height="689" loading="lazy"></p>
<p>This is how the Suspense boundary, the <code>use()</code> API, and the Error Boundary work together to help you write scalable React code that can be maintained very easily in the future. I hope you found it helpful. All the source code used in this handbook is in the <a target="_blank" href="https://github.com/tapascript/15-days-of-react-design-patterns/tree/main/day-16">tapaScript GitHub Repository</a>.</p>
<h2 id="heading-learn-from-the-15-days-of-react-design-patterns">Learn from the 15 Days of React Design Patterns</h2>
<p>I have some great news for you: after my 40 days of JavaScript initiative, I have now completed a brand new initiative called <a target="_blank" href="https://www.youtube.com/playlist?list=PLIJrr73KDmRyQVT__uFZvaVfWPdfyMFHC">15 Days of React Design Patterns</a> (with Bonus Episodes).</p>
<p>If you enjoyed learning from this handbook, I’m sure you’ll love this series, featuring the 15+ most important React design patterns. Check it out, subscribe, and get it for free:</p>
<p><a target="_blank" href="https://www.youtube.com/playlist?list=PLIJrr73KDmRyQVT__uFZvaVfWPdfyMFHC"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770087890778/c89e0666-898d-448c-9d2c-443788fd4413.png" alt="15 days of React Design Patterns" class="image--center mx-auto" width="1562" height="894" loading="lazy"></a></p>
<h2 id="heading-before-we-end">Before We End…</h2>
<p>That’s all! I hope you found this insightful.</p>
<p><a target="_blank" href="https://github.com/tapascript/15-days-of-react-design-patterns/tree/main/day-03/compound-components-patterns">Let’s connect:</a></p>
<ul>
<li><p>Subscribe to my <a target="_blank" href="https://www.youtube.com/tapasadhikary?sub_confirmation=1">YouTube Channel</a>.</p>
</li>
<li><p>Check out my courses, <a target="_blank" href="https://www.youtube.com/playlist?list=PLIJrr73KDmRw2Fwwjt6cPC_tk5vcSICCu">40 Days of JavaScript</a>, <a target="_blank" href="https://www.youtube.com/playlist?list=PLIJrr73KDmRyQVT__uFZvaVfWPdfyMFHC">15 Days of React Design Patterns</a>, and <a target="_blank" href="https://www.youtube.com/playlist?list=PLIJrr73KDmRwT8Msc4H3_CP5Tf8MqqqVZ">Thinking in Debugging</a>.</p>
</li>
<li><p>Follow on <a target="_blank" href="https://www.linkedin.com/in/tapasadhikary/">LinkedIn</a> if you don't want to miss the daily dose of up-skilling tips.</p>
</li>
<li><p>Join my <a target="_blank" href="https://discord.gg/zHHXx4vc2H">Discord Server</a>, and let’s learn together.</p>
</li>
<li><p>Follow my work on <a target="_blank" href="https://github.com/tapascript">GitHub</a>.</p>
</li>
</ul>
<p>See you soon with my next article. Until then, please take care of yourself and keep learning.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Data Communication and Networking Handbook ]]>
                </title>
                <description>
                    <![CDATA[ When I was beginning to learn about networks, I didn't know how many things in my daily life depended on them – from texting on WhatsApp to watching YouTube. I still vividly remember when I learned that computers communicate with one another. It was ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-data-communication-and-networking-handbook/</link>
                <guid isPermaLink="false">6853059aed5a0659bcde37e5</guid>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data communication ]]>
                    </category>
                
                    <category>
                        <![CDATA[ networking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ communication ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                    <category>
                        <![CDATA[ MathJax ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ valentine Gatwiri ]]>
                </dc:creator>
                <pubDate>Wed, 18 Jun 2025 18:29:46 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1750178451091/adea6449-2daf-405b-80f0-e23a356fa45b.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When I was beginning to learn about networks, I didn't know how many things in my daily life depended on them – from texting on WhatsApp to watching YouTube.</p>
<p>I still vividly remember when I learned that computers communicate with one another. It was magic – telepathy, nearly. But there is a systematic, logical process behind the magic: computer networking. And I’m excited to help you discover how computers communicate and why it’s possible.</p>
<p>Essentially, data communication is all about exchanging information between two or more machines. But it's not just a question of sending – it's a matter of sending the right data, to the right machine, in the right format. And that's the brilliance of networking basics.</p>
<p>This handbook will teach you the fundamentals of the language of computers. You'll discover how data is passed from machine to machine, how operations are carried out on information, and how networks – from tiny home arrangements to massive worldwide networks – are constructed and managed.</p>
<p>We’ll start with the absolute basics: what a network is, what the hardware is, and how devices know each other and talk to each other. Next, we’ll examine crucial networking models like OSI and TCP/IP stacks that segment communication into layers in order to make it easier to understand and troubleshoot. You'll learn about IP addresses, DNS, routing, switching, and firewalls and security's involvement in keeping networks safe.</p>
<p>Whether you are a complete beginner starting from the ground up or a seasoned dev looking to solidify your foundation, this handbook will walk you through linking the dots. When you're finished, you won't only understand how your favorite sites and apps really function behind the scenes – you'll be able to speak networks in your sleep.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-chapter-1-data-and-communication-fundamentals">Chapter 1: Data and Communication Fundamentals</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-2-signals-the-language-of-communication">Chapter 2: Signals — The Language of Communication</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-3-bandwidth-understanding-how-much-we-can-transmit">Chapter 3: Bandwidth — Understanding How Much We Can Transmit</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-4-transmission-media-the-highways-of-communication">Chapter 4: Transmission Media — The Highways of Communication</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-5-network-topologies-how-we-structure-our-connections">Chapter 5: Network Topologies — How We Structure Our Connections</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-6-the-osi-model-understanding-layers-of-communication">Chapter 6: The OSI Model — Understanding Layers of Communication</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-7-protocols-and-ports-how-rules-and-doors-guide-communication">Chapter 7: Protocols and Ports — How Rules and Doors Guide Communication</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-8-ip-addressing-and-subnetting-naming-and-organizing-the-network">Chapter 8: IP Addressing and Subnetting — Naming and Organizing the Network</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-9-routing-and-switching-directing-data-on-the-network">Chapter 9: Routing and Switching — Directing Data on the Network</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-10-network-infrastructure-devices-security-and-the-modern-internet">Chapter 10: Network Infrastructure — Devices, Security, and the Modern Internet</a></p>
</li>
</ol>
<h2 id="heading-chapter-1-data-and-communication-fundamentals"><strong>Chapter 1: Data and Communication Fundamentals</strong></h2>
<p>This introductory section lays the groundwork for the rest of the handbook. You’ll learn what data communication is, how it's different from "sending a message," and what's required for two computers (or phones, or servers) to exchange information efficiently.</p>
<p>You'll start to feel at home with fundamental ideas, technical terminology, and the machinery behind the scenes that works quietly in the background to make daily technology appear effortless.</p>
<p>By the end, you will be able to:</p>
<ul>
<li><p>Explain what data communication is and how it works in real life</p>
</li>
<li><p>Identify the components involved in data communication systems</p>
</li>
<li><p>Differentiate between types of data and how they're represented</p>
</li>
<li><p>Understand different types of data flow (simplex, half duplex, full duplex)</p>
</li>
<li><p>Describe what a computer network is and its main categories (LAN, MAN, WAN)</p>
</li>
<li><p>Understand the importance of protocols and how they enable communication</p>
</li>
<li><p>Recognize the role of standards and standard organizations in making networking universal</p>
</li>
</ul>
<h2 id="heading-data-vs-information">Data vs Information</h2>
<p>We throw around the word "data" a lot these days – "big data," "data science," "data plans" – but what does it mean?</p>
<ul>
<li><p><strong>Data</strong> is raw. It's unprocessed, meaningless on its own. Think of numbers on a spreadsheet with no labels.</p>
</li>
<li><p><strong>Information</strong> is processed data – it's meaningful and helps us make decisions.</p>
</li>
</ul>
<p><strong>A personal example:</strong> I once received a CSV file from my school with hundreds of rows of marks. It looked like chaos – just student IDs and scores. But the moment I matched those IDs to names and applied the grading criteria, it became useful <strong>information</strong> about who passed, who failed, and who topped the class.</p>
<p>So, data is the ingredient. Information is the cooked dish.</p>
<h2 id="heading-so-what-exactly-is-data-communication">So, What Exactly is Data Communication?</h2>
<p>Imagine you're texting your friend. Your phone sends data to their phone using signals through cables, Wi-Fi, or even satellites. This entire process is called <strong>data communication</strong>, moving data from one place (you!) to another (your friend).</p>
<p>But it’s not as random as it sounds. It follows a set of agreed rules called <strong>protocols</strong>. Think of them as social etiquette for devices – how to talk, when to talk, and what to say.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748435887792/a607b06f-ffe6-47c1-8e18-a79ab4f0b068.png" alt="Explanation of protocols" class="image--center mx-auto" width="530" height="360" loading="lazy"></p>
<p>This process involves:</p>
<ul>
<li><p>Devices (sender and receiver)</p>
</li>
<li><p>A transmission medium (like cables or wireless)</p>
</li>
<li><p>A set of rules (protocols)</p>
</li>
</ul>
<p>Let’s break it down further.</p>
<h3 id="heading-characteristics-of-data-communication">Characteristics of Data Communication</h3>
<p>To be considered effective, data communication must exhibit the following characteristics:</p>
<ol>
<li><p><strong>Delivery</strong>: Data must reach the correct destination. If I send a message to John, it shouldn't land in Sarah's inbox.</p>
</li>
<li><p><strong>Accuracy</strong>: No one wants a corrupted file. Data must be accurate, free from errors.</p>
</li>
<li><p><strong>Timeliness</strong>: Some data, like live video, must arrive on time. Lag ruins the experience.</p>
</li>
<li><p><strong>Jitter</strong>: Inconsistent arrival times of data packets (especially in audio/video) create disruption. A good system keeps jitter low.</p>
</li>
</ol>
<p>I once experienced a video call where the sound lagged by 5 seconds. It turned into a game of "Guess what I said." That's jitter in action.</p>
<h3 id="heading-meet-the-cast-the-components-of-data-communication">Meet the Cast: The Components of Data Communication</h3>
<p>In every data conversation, five key players show up:</p>
<ol>
<li><p><strong>Sender</strong> – The device that starts the chat (like your phone).</p>
</li>
<li><p><strong>Receiver</strong> – The one getting the message (your friend’s phone).</p>
</li>
<li><p><strong>Message</strong> – The actual info, whether it’s "hi" or a TikTok.</p>
</li>
<li><p><strong>Transmission Medium</strong> – The path your message travels (Wi-Fi, cables, and so on).</p>
</li>
<li><p><strong>Protocol</strong> – The language they agree to speak (like TCP/IP).</p>
</li>
</ol>
<p>Pretty cool, right?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748436008530/14d2e296-b999-4790-a4fd-26a7026e8810.png" alt="Essentials of Networking" class="image--center mx-auto" width="557" height="391" loading="lazy"></p>
<h2 id="heading-data-representation">Data Representation</h2>
<p>Computers are not humans. They don’t understand language, pictures, or music – unless these are converted into a format they can process: <strong>bits</strong> (0s and 1s).</p>
<p>Let’s walk through the different types of data representation:</p>
<h3 id="heading-1-text">1. Text</h3>
<p>Text is stored as a sequence of characters using encoding schemes like ASCII and Unicode. For example, the letter "A" in ASCII is 65, which in binary is <code>01000001</code>.</p>
<h3 id="heading-2-numbers">2. Numbers</h3>
<p>Similarly, numeric data is stored as bit patterns. Computers can perform calculations using binary logic.</p>
<h3 id="heading-3-images">3. Images</h3>
<p>An image is a matrix of pixels. Each pixel is represented by bits. A black-and-white image might only need 1 bit per pixel, while a full-color photo could use 24 bits per pixel or more.</p>
<p><strong>Example:</strong> A 10x10 black and white image = 100 pixels = 100 bits.</p>
<h3 id="heading-4-audio">4. Audio</h3>
<p>Audio is analog, but we digitize it for storage and transmission. For instance, voice notes are sampled at certain intervals and stored as bits.</p>
<h3 id="heading-5-video">5. Video</h3>
<p>Video is a sequence of images (frames) along with synchronized audio. It’s high in data volume and needs compression techniques like MP4 to be practical.</p>
<h3 id="heading-how-does-the-data-flow">How Does the Data Flow?</h3>
<p>You might think data just zips across in one go – but it has <em>modes</em>, just like moods:</p>
<ul>
<li><p><strong>Simplex:</strong> One-way only (like a radio broadcast).</p>
</li>
<li><p><strong>Half Duplex:</strong> You take turns – like walkie-talkies.</p>
</li>
<li><p><strong>Full Duplex:</strong> Both sides talk at once – think phone calls.</p>
</li>
</ul>
<p>Each has its own vibe depending on the situation.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748436167157/a8e8d277-16f8-4891-8bfd-8b63ac468bda.png" alt="Data flow – simplex, half duplex, full duplex" class="image--center mx-auto" width="574" height="220" loading="lazy"></p>
<h2 id="heading-what-is-a-computer-network">What is a Computer Network?</h2>
<p>A computer network is a system that allows devices to share data. These connected devices (nodes) use communication links to interact.</p>
<p>The main goals of a network are:</p>
<ul>
<li><p><strong>Reliability</strong>: Data should get there.</p>
</li>
<li><p><strong>Security</strong>: Unwanted access should be blocked.</p>
</li>
<li><p><strong>Performance</strong>: High speed, low delay.</p>
</li>
</ul>
<p>When you connect your laptop at a café, for example, you’re part of a <strong>network</strong>. But networks come in all shapes:</p>
<ul>
<li><strong>PAN (A personal area network)</strong>: connects electronic devices within a user's immediate area.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748933101198/29cc06ed-cf79-44b8-bf6b-4691729c80c7.png" alt="Personal Area Network – downloadzone" class="image--center mx-auto" width="251" height="220" loading="lazy"></p>
<ul>
<li><strong>LAN (Local Area Network):</strong> Small – like your home Wi-Fi.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748933264502/fad55c68-0170-4fee-8a6c-cc7463f697be.png" alt="Local Area Network – IT Release" class="image--center mx-auto" width="396" height="233" loading="lazy"></p>
<ul>
<li><strong>MAN (Metropolitan Area Network):</strong> Covers a city – like college campuses.</li>
</ul>
<p><img src="https://cyberhoot.com/wp-content/uploads/2022/01/3d7659f7-2f69-4b14-b851-a84ab85152e0.png" alt="Metropolitan Area Network (MAN) – CyberHoot" width="1993" height="1388" loading="lazy"></p>
<ul>
<li><strong>WAN (Wide Area Network):</strong> Huge – think the <em>entire</em> internet!</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748933893001/aa0343da-2733-447f-98f2-c347a7e964c9.png" alt="Wide Area Network – Vecteezy" class="image--center mx-auto" width="315" height="248" loading="lazy"></p>
<p>The internet isn’t one big net – it’s a net of many, many nets.</p>
<h2 id="heading-what-is-a-protocol">What is a Protocol?</h2>
<p>A protocol is a set of rules that devices follow to communicate. Without a protocol, it’s chaos.</p>
<p><strong>Analogy:</strong> Think of a group project. If everyone agrees to use Google Docs and write in English (or any one language), it works. But if one person uses Word in French, and another emails a PDF in Mandarin, you have a mess.</p>
<p>Protocols define:</p>
<ul>
<li><p><strong>What</strong> data to send</p>
</li>
<li><p><strong>How</strong> to send it</p>
</li>
<li><p><strong>When</strong> to send it</p>
</li>
</ul>
<h3 id="heading-elements-of-a-protocol">Elements of a Protocol</h3>
<ol>
<li><p><strong>Syntax</strong>: Format and structure (like grammar).</p>
</li>
<li><p><strong>Semantics</strong>: Meaning of each section.</p>
</li>
<li><p><strong>Timing</strong>: When to send and at what speed.</p>
</li>
</ol>
<h2 id="heading-standards-in-networking">Standards in Networking</h2>
<p>Standards are agreements to ensure that different systems can work together. Without standards, each manufacturer would create isolated networks that couldn’t talk to others.</p>
<p>There are two types of standards:</p>
<ul>
<li><p><strong>De facto</strong>: By convention (used commonly but not formally approved)</p>
</li>
<li><p><strong>De jure</strong>: By law (formally approved)</p>
</li>
</ul>
<h3 id="heading-standards-organizations">Standards Organizations</h3>
<p>There are a few key organizations that help define these standards:</p>
<ul>
<li><p><strong>ISO</strong> – International Organization for Standardization</p>
</li>
<li><p><strong>ITU-T</strong> – International Telecommunication Union</p>
</li>
<li><p><strong>IEEE</strong> – Institute of Electrical and Electronics Engineers</p>
</li>
<li><p><strong>ANSI</strong> – American National Standards Institute</p>
</li>
<li><p><strong>EIA</strong> – Electronic Industries Association</p>
</li>
</ul>
<h2 id="heading-chapter-2-signals-the-language-of-communication"><strong>Chapter 2: Signals — The Language of Communication</strong></h2>
<p>In this chapter, I’ll teach you about the invisible messengers – signals – that make it all possible. You will:</p>
<ul>
<li><p>Understand what signals are and how they carry data</p>
</li>
<li><p>Distinguish between analog and digital signals, and when each is used</p>
</li>
<li><p>Learn about key signal characteristics like amplitude, frequency, phase, and wavelength</p>
</li>
<li><p>Visualize and compare time domain vs frequency domain representations</p>
</li>
<li><p>Appreciate how real-world signals are composed of multiple waves (composite signals)</p>
</li>
<li><p>Understand digital signal features like bit rate, baud rate, and bit interval</p>
</li>
<li><p>Learn about baseband vs broadband transmission methods</p>
</li>
<li><p>Identify challenges like attenuation, distortion, and noise</p>
</li>
<li><p>Grasp how bandwidth affects data quality and speed</p>
</li>
</ul>
<p>When I was a teenager, I often wondered how my voice traveled through a phone and reached someone else in another town. I imagined tiny versions of myself running through wires with a message in hand. Turns out, while not exactly accurate, the idea of something carrying your message is spot on. That something is called a <strong>signal</strong>.</p>
<p>A signal is the form data takes to move through physical space. Whether it’s your mom calling you, your professor sending an email, or your friend uploading a reel – all of that happens through signals.</p>
<h2 id="heading-data-and-signals">Data and Signals</h2>
<h3 id="heading-what-is-a-signal">What is a Signal?</h3>
<p>I learned that data is like the message I wanted to send, and a signal is the delivery truck. Without the truck, the message goes nowhere.</p>
<p>Here’s where things get a bit science-y, but stay with me. When data travels, it becomes signals, kind of like waves. These waves can be classified in to two common ways, by the nature of the signal, and by their patterns over time. We’ll talk about the nature of the signal first.</p>
<h3 id="heading-the-nature-of-the-signal-analog-vs-digital">The Nature of the Signal: Analog vs Digital</h3>
<ul>
<li><p><strong>Analog</strong> – A signal that varies smoothly over time and can take any value in a range. Like ocean waves, always changing smoothly. Continuous (like voices).</p>
</li>
<li><p><strong>Digital</strong> – A signal that has discrete values, usually 0s and 1s. Like a staircase – clear, sharp steps, either up or down, in bits (1s and 0s, like computers).</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748436311536/db273577-c474-4eca-8396-b9ea7bd0031f.png" alt="Analog and digital signals" class="image--center mx-auto" width="554" height="234" loading="lazy"></p>
<h3 id="heading-analog-signals">Analog Signals</h3>
<p>The first time I visualized an analog signal, it looked like the ripples I saw after tossing a stone in water. Gentle curves moving outwards.</p>
<h4 id="heading-key-features-of-analog-signals">Key features of analog signals:</h4>
<ul>
<li><p><strong>Amplitude</strong>: This reminded me of volume. Louder signals have taller waves.</p>
</li>
<li><p><strong>Frequency</strong>: It’s the beat or rhythm. High frequency = rapid waves = higher pitch.</p>
</li>
<li><p><strong>Period</strong>: Time for one full wave cycle. Shorter periods mean higher frequency.</p>
</li>
<li><p><strong>Phase</strong>: Two waves can start at different points – just like dancers starting a move a second apart.</p>
</li>
<li><p><strong>Wavelength</strong>: How far one wave travels in space. It depends on how fast it moves and its frequency.</p>
</li>
</ul>
<h4 id="heading-time-vs-frequency-domain">Time vs. Frequency Domain</h4>
<ul>
<li><p><strong>Time Domain</strong>: Shows how signals change over time. Like watching a song’s audio waveform.</p>
</li>
<li><p><strong>Frequency Domain</strong>: Shows the ingredients – how much bass, how much treble. It’s like the EQ settings on a music player.</p>
</li>
</ul>
<h4 id="heading-composite-signals-and-fourier">Composite Signals and Fourier</h4>
<p>Real-world signals are messy, made of multiple waves mixed. <a target="_blank" href="https://en.wikipedia.org/wiki/Joseph_Fourier">Fourier’s</a> big idea was: <em>Any messy signal can be broken down into simple sine waves.</em> That insight changed how engineers understand and clean up signals.</p>
<h3 id="heading-digital-signals">Digital Signals</h3>
<p>Digital signals felt familiar to me. My laptop, my phone, even my microwave speaks digital.</p>
<h4 id="heading-key-features-of-digital-signals">Key features of digital signals:</h4>
<ul>
<li><p><strong>Bit Interval</strong>: One bit’s duration. Like how long I hold down a piano key.</p>
</li>
<li><p><strong>Bit Rate</strong>: How many notes (bits) I can play per second.</p>
</li>
<li><p><strong>Baud Rate</strong>: How often the signal actually changes. Not always the same as bit rate.</p>
</li>
<li><p><strong>Levels</strong>: 2-level = 1s and 0s. More levels = more complex encoding.</p>
</li>
</ul>
<h4 id="heading-square-waves">Square Waves</h4>
<p>If analog signals are elegant curves, digital signals are sharp edges. A square wave is a bold, binary shout: ON-OFF-ON-OFF.</p>
<h4 id="heading-digital-advantages-and-struggles">Digital Advantages and Struggles</h4>
<p><strong>Why I love them:</strong></p>
<ul>
<li><p>They’re clean and easy to work with.</p>
</li>
<li><p>Errors are easier to spot and fix.</p>
</li>
</ul>
<p><strong>But they’re not perfect:</strong></p>
<ul>
<li><p>They need more bandwidth.</p>
</li>
<li><p>They don’t travel well over long distances without help.</p>
</li>
</ul>
<h3 id="heading-pattern-over-time-periodic-vs-non-periodic-signals">Pattern Over Time: Periodic vs Non-periodic Signals</h3>
<ul>
<li><p><strong>Periodic Signals</strong>: Repeat at regular intervals over time (for example, sine waves, clock pulses).</p>
</li>
<li><p><strong>Non-periodic Signals</strong>: Do <strong>not</strong> repeat – more random or unique (for example, a burst of data or speech waveform).</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1749818448163/c505ace2-587d-4c50-9111-bda8a902f439.png" alt="Periodic vs non-periodic signals" class="image--center mx-auto" width="609" height="134" loading="lazy"></p>
</li>
</ul>
<h3 id="heading-periodic-signals">Periodic Signals</h3>
<p>These feel like the rhythm of my favorite song. They’re predictable. Repeating. Reliable.</p>
<h4 id="heading-key-features">Key Features</h4>
<ul>
<li><p><strong>Repetition</strong>: The same pattern, again and again. Like waves hitting the shore at steady intervals.</p>
</li>
<li><p><strong>Cycle</strong>: One complete shape of the signal. Think of it as one heartbeat in a steady pulse.</p>
</li>
<li><p><strong>Frequency</strong>: How many cycles per second? Measured in Hertz (Hz).</p>
</li>
</ul>
<h4 id="heading-why-i-like-them">Why I like them</h4>
<ul>
<li><p>Easy to analyze – like having a beat to follow.</p>
</li>
<li><p>Great for systems that need synchronization, like clock signals in my devices.</p>
</li>
</ul>
<h4 id="heading-but-still">But still...</h4>
<ul>
<li>They can’t carry surprise or variety. No space for one-time messages.</li>
</ul>
<h3 id="heading-non-periodic-signals">Non-periodic Signals</h3>
<p>These are the jazz solos of the signal world. Wild. Unique. Unpredictable.</p>
<h4 id="heading-key-features-1">Key Features</h4>
<ul>
<li><p><strong>No repetition</strong>: Each part is different – like my playlist on shuffle.</p>
</li>
<li><p><strong>Spikes and silence</strong>: Sudden changes, long pauses. Perfect for one-off data transmissions.</p>
</li>
<li><p><strong>Used in real-life data</strong>: Emails, videos, and downloads all love this format.</p>
</li>
</ul>
<h4 id="heading-why-theyre-cool">Why they’re cool</h4>
<ul>
<li><p>Great for representing actual information – each burst means something new.</p>
</li>
<li><p>More flexible for transmitting complex messages.</p>
</li>
</ul>
<h4 id="heading-whats-tricky">What’s tricky</h4>
<ul>
<li><p>Harder to analyze and predict.</p>
</li>
<li><p>Tougher to filter or compress efficiently.</p>
</li>
</ul>
<p>Understanding signals helps us know how fast and cleanly information travels.</p>
<h2 id="heading-channels-the-roads-signals-travel-on">Channels: The Roads Signals Travel On</h2>
<p>In the context of signals and communication, <strong>channels</strong> refer to the medium or path through which a signal travels from a sender (transmitter) to a receiver. Channels are like roads. You can’t just send a truck (signal) without knowing if the road (channel) allows it.</p>
<p>We can describe channels in different ways:</p>
<ul>
<li><p><strong>Physically</strong>: What the signal travels through (like a wire or air).</p>
</li>
<li><p><strong>Functionally</strong>: How the signal is allowed to move through (based on frequency).</p>
</li>
<li><p><strong>Logically</strong>: How we organize multiple data streams within the same physical path.</p>
</li>
</ul>
<h3 id="heading-physical-channels-the-road-itself">Physical Channels = The Road Itself</h3>
<p>These are the real, tangible paths for signals:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Example</strong></td><td><strong>Medium</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Ethernet cable</td><td>Copper wire</td></tr>
<tr>
<td>Fiber-optic link</td><td>Glass strand</td></tr>
<tr>
<td>Wi-Fi or Radio</td><td>Air (wireless)</td></tr>
<tr>
<td>Satellite transmission</td><td>Space (electromagnetic waves)</td></tr>
</tbody>
</table>
</div><h3 id="heading-frequency-behavior-of-physical-channels">Frequency Behavior of Physical Channels</h3>
<p>Just like roads are built for certain speeds, physical channels are better at carrying certain frequencies.</p>
<p>Here’s where <strong>low-pass</strong>, <strong>high-pass</strong>, <strong>band-pass</strong>, and <strong>band-stop</strong> come in – they describe how a physical channel behaves.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Channel Type</strong></td><td><strong>Behavior</strong></td><td><strong>Analogy</strong></td><td><strong>Common Use</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Low-pass</td><td>Lets low frequencies pass</td><td>Quiet country road (slow cars only)</td><td>Telephone lines (voice)</td></tr>
<tr>
<td>Band-pass</td><td>Allows a specific frequency band</td><td>Toll road with speed range</td><td>FM radio, Wi-Fi</td></tr>
<tr>
<td>High-pass</td><td>Blocks low, passes high frequencies</td><td>Speedway (fast cars only)</td><td>Audio filtering</td></tr>
<tr>
<td>Band-stop</td><td>Blocks a range but passes others</td><td>Road under construction</td><td>Noise removal (for example, hum filter)</td></tr>
</tbody>
</table>
</div><p>So when we say "low-pass channel," we're talking about <strong>how a physical channel filters signals.</strong></p>
<h3 id="heading-logical-channels-lanes-on-the-road">Logical Channels = Lanes on the Road</h3>
<p>A <strong>logical channel</strong> is a virtual path created within a physical one. It organizes or splits the signal flow so multiple people or devices can use the same channel without crashing into each other.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>Description</strong></td><td><strong>Analogy</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Frequency Division</td><td>Each user gets their own frequency</td><td>FM radio stations</td></tr>
<tr>
<td>Time Division</td><td>Each user gets a time slot</td><td>Taking turns at a speaking table</td></tr>
<tr>
<td>Virtual Circuits</td><td>Custom paths inside networks</td><td>Reserved bus seats</td></tr>
</tbody>
</table>
</div><p>So yes – you can have many logical channels on one physical cable.</p>
<h4 id="heading-how-they-work-together">How They Work Together</h4>
<p>Let’s combine it all:</p>
<p>Imagine a fiber optic cable (physical channel) that’s designed to carry a specific frequency range (band-pass).<br>Within that frequency range, you can create many logical channels using time or frequency division.</p>
<p>Example: FM Radio</p>
<ul>
<li><p><strong>Physical Channel</strong>: Air (radio waves)</p>
</li>
<li><p><strong>Type</strong>: Band-pass (88–108 MHz)</p>
</li>
<li><p><strong>Logical Channels</strong>: Each station (for example, 98.4 FM) is a logical channel inside that band</p>
</li>
</ul>
<p>Example: Internet over DSL</p>
<ul>
<li><p><strong>Physical Channel</strong>: Telephone line (copper wire)</p>
</li>
<li><p><strong>Type</strong>: Low-pass for voice, high-pass for internet</p>
</li>
<li><p><strong>Logical Channels</strong>: Browsing, streaming, and downloads running together via time/frequency division</p>
</li>
</ul>
<h2 id="heading-baseband-vs-broadband-transmission-how-we-use-the-channel">Baseband vs Broadband Transmission: How We Use the Channel</h2>
<p>There are two main types of ways we use the channel: baseband and broadband transmission.</p>
<p>Baseband Transmission is like talking directly to someone across a quiet room. Simple and unaltered. Common in local systems like Ethernet.</p>
<p>Broadband Transmission is a bit different. Here, we dress up the digital message in analog clothing using <strong>modulation</strong>. That’s how we send data over radio or fiber. It’s more complex, but necessary when you’re dealing with wider, noisier roads.</p>
<h3 id="heading-signal-villains-what-goes-wrong-on-the-way">Signal Villains: What Goes Wrong on the Way</h3>
<p>As your signal travels down the channel, it may face <strong>three big problems</strong>.</p>
<ol>
<li><p><strong>Attenuation:</strong> It’s like my voice getting quieter the farther I am from someone. Amplifiers help boost it.</p>
</li>
<li><p><strong>Distortion:</strong> Imagine you and I agree to send square waves, but by the time it reaches you, it looks like mush. That’s distortion, especially bad over long cables.</p>
</li>
<li><p><strong>Noise:</strong> Noise is anything extra that wasn’t supposed to be in the signal. From lightning strikes to microwaves, interference is real.</p>
</li>
</ol>
<p><strong>Types I learned about:</strong></p>
<ul>
<li><p>Thermal (heat-related)</p>
</li>
<li><p>Induced (nearby equipment)</p>
</li>
<li><p>Crosstalk (adjacent wires “talking”)</p>
</li>
<li><p>Impulse (sudden bursts)</p>
</li>
</ul>
<p>We can reduce noise using better cables, filters, and digital corrections.</p>
<h2 id="heading-bandwidth">Bandwidth</h2>
<p>The word ‘bandwidth’ gets thrown around so much. For me, it used to just mean internet speed. But it’s deeper:</p>
<ul>
<li><p><strong>Analog Bandwidth</strong>: Range of frequencies a signal uses.</p>
</li>
<li><p><strong>Digital Bandwidth</strong>: How much data we can push through per second.</p>
</li>
</ul>
<p>More bandwidth = more room = faster, clearer communication.</p>
<p>We’ll talk more about bandwidth in the next chapter.</p>
<p>Learning about signals was like being handed the key to a secret code. Every beep, flash, and wave in our world is part of a language. Once you see it, you can’t unsee it. Signals are not just theory – they are the reason I can write this on a laptop, send it to the cloud, and have you read it anywhere in the world.</p>
<h2 id="heading-chapter-3-bandwidth-understanding-how-much-we-can-transmit">Chapter 3: Bandwidth — Understanding How Much We Can Transmit</h2>
<p>When I first heard the term "bandwidth," I assumed it just meant how fast my internet was. And while that’s not entirely wrong, I came to learn there’s much more to it.</p>
<p>In this chapter, we’ll delve into the concept of bandwidth as the capacity of a communication path, examine its impact on signal quality and speed, and investigate how it's measured in both analog and digital systems.</p>
<p>By the end of this chapter, you will be able to explain:</p>
<ul>
<li><p>What bandwidth means in different contexts</p>
</li>
<li><p>How analog and digital bandwidths are measured</p>
</li>
<li><p>The concept of throughput and how it differs from bandwidth</p>
</li>
<li><p>Factors that affect data transmission performance</p>
</li>
</ul>
<h2 id="heading-what-bandwidth-is-all-about">What Bandwidth is All About</h2>
<p><strong>Bandwidth</strong> is the maximum amount of data that can be transmitted over a communication channel in a given amount of time.</p>
<p>Have you ever streamed a movie and it kept buffering? That frustrating lag led me to one of the most important concepts in networking: bandwidth. Bandwidth is like a highway. The wider the road, the more cars (or data) can pass at once.</p>
<p>I also like to think of it this way: If I’m trying to pour water (data) through a pipe (the communication channel), a narrow pipe limits how much water can flow through at a time. That’s low bandwidth. A wide pipe? Now we’re talking high bandwidth – fast and smooth.</p>
<h3 id="heading-bandwidth-utilization">Bandwidth Utilization</h3>
<h4 id="heading-efficiency">Efficiency</h4>
<p>This is how well we use the available bandwidth. High efficiency means most of the bandwidth is being used for actual data (not overhead).</p>
<h4 id="heading-overhead">Overhead</h4>
<p>Overhead includes headers, acknowledgments, and error-checking codes. It’s necessary, but it eats into our available bandwidth.</p>
<h4 id="heading-idle-time">Idle Time</h4>
<p>Sometimes the channel sits unused, due to waiting for acknowledgment, processing time, and so on. Minimizing idle time improves efficiency.</p>
<h2 id="heading-bandwidth-in-analog-and-digital-terms">Bandwidth in Analog and Digital Terms</h2>
<h3 id="heading-analog-bandwidth">Analog Bandwidth</h3>
<p>Analog bandwidth refers to the <strong>range of frequencies</strong> over which an analog signal can be accurately acquired, processed, or transmitted by a system. Beyond this range, the signal begins to degrade – either being attenuated or distorted, making it unreliable for precise use.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750094089263/3f02c7a4-9652-4162-b258-422e431d94a8.png" alt="Analog Bandwidth - amplitude &amp; frequency graph" class="image--center mx-auto" width="338" height="293" loading="lazy"></p>
<h4 id="heading-key-concepts">Key Concepts</h4>
<ul>
<li><p><strong>Frequency Range:</strong> Analog bandwidth defines the spectrum of frequencies that a system can handle <strong>without significant degradation</strong>. It’s the system’s “comfort zone” for signal fidelity.</p>
</li>
<li><p><strong>3 dB Bandwidth:</strong> One common method of defining analog bandwidth is the <strong>-3 dB point</strong>. At this point, the signal’s amplitude drops to about 70.7% of its original value, meaning almost half its power is lost. Frequencies beyond this threshold experience much more signal loss or distortion.</p>
</li>
<li><p><strong>Importance in Signal Fidelity:</strong> Analog bandwidth directly affects how well a system can reproduce or process real-world signals – especially in audio, video, instrumentation, and telecommunications. A narrow bandwidth results in muffled or distorted outputs, while a wider bandwidth ensures better detail and accuracy.</p>
</li>
</ul>
<h3 id="heading-bandwidth-and-rise-time">Bandwidth and Rise Time</h3>
<p>In instruments like oscilloscopes, analog bandwidth is closely related to <strong>rise time</strong> – the time it takes for a signal to transition from low to high. A wider bandwidth enables faster transitions to be captured accurately, which is essential for analyzing high-speed or fast-changing signals.</p>
<h3 id="heading-real-life-example">Real-Life Example</h3>
<p>Consider old telephone systems: they typically had an analog bandwidth ranging from 300 Hz to 3300 Hz, resulting in a 3000 Hz bandwidth. This range was enough for clear voice transmission, but not wide enough for high-fidelity music or modern audio standards.</p>
<h3 id="heading-applications-of-analog-bandwidth">Applications of Analog Bandwidth</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Application Area</strong></td><td><strong>Role of Analog Bandwidth</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Oscilloscopes</td><td>Determines how accurately signals (especially fast ones) are captured.</td></tr>
<tr>
<td>Amplifiers</td><td>Specifies which frequency ranges can be amplified without distortion.</td></tr>
<tr>
<td>Communication Systems</td><td>Defines signal capacity and transmission quality.</td></tr>
<tr>
<td>Data Acquisition</td><td>Affects how well fast-changing signals are measured and analyzed.</td></tr>
</tbody>
</table>
</div><h3 id="heading-digital-bandwidth">Digital Bandwidth</h3>
<p>Digital bandwidth refers to the <strong>maximum capacity</strong> of a digital channel to transmit data over a specific period, usually measured in <strong>bits per second (bps)</strong>. It’s a measure of how much data can “flow” through a communication path, much like how the width of a pipe controls how much water can pass through.</p>
<p>The wider the digital bandwidth, the more data can be transmitted simultaneously, resulting in faster downloads, smoother video streams, and better overall network performance.</p>
<h4 id="heading-bandwidth-vs-data-rate">Bandwidth vs. Data Rate</h4>
<p>Although they’re often used interchangeably, they aren’t quite the same:</p>
<ul>
<li><p><strong>Bandwidth</strong> is the capacity of the channel – the <em>maximum potential</em>.</p>
</li>
<li><p><strong>Data rate</strong> is the actual speed at which data is transmitted, which can vary based on factors like:</p>
<ul>
<li><p>Network congestion</p>
</li>
<li><p>Hardware limitations</p>
</li>
<li><p>Signal interference</p>
</li>
</ul>
</li>
</ul>
<p>Think of bandwidth as the size of a highway, and data rate as how fast cars are moving on it.</p>
<h4 id="heading-how-digital-bandwidth-is-measured">How Digital Bandwidth is Measured</h4>
<p>Digital bandwidth is expressed in units such as:</p>
<ul>
<li><p><strong>bps</strong> – bits per second</p>
</li>
<li><p><strong>Kbps</strong> – thousands of bits per second</p>
</li>
<li><p><strong>Mbps</strong> – millions of bits per second</p>
</li>
<li><p><strong>Gbps</strong> – billions of bits per second</p>
</li>
</ul>
<p><strong>Example</strong>: A 100 Mbps internet connection can, in theory, transfer 100 million bits of data every second.</p>
<h4 id="heading-why-it-matters">Why It Matters</h4>
<p>Bandwidth plays a central role in modern digital life. Without enough bandwidth:</p>
<ul>
<li><p>Streaming videos buffer</p>
</li>
<li><p>Video calls drop in quality or disconnect</p>
</li>
<li><p>Online games lag or stutter</p>
</li>
<li><p>Large files download painfully slowly</p>
</li>
</ul>
<p>This becomes even more critical when multiple devices share the same network. Each device draws from the available bandwidth, which can quickly get overwhelmed if the demand is too high.</p>
<h3 id="heading-digital-vs-analog-bandwidth">Digital vs. Analog Bandwidth</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Aspect</strong></td><td><strong>Digital Bandwidth</strong></td><td><strong>Analog Bandwidth</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Measured in</td><td>Bits per second (bps, Mbps, Gbps)</td><td>Hertz (Hz)</td></tr>
<tr>
<td>Focus</td><td>Data transmission rate</td><td>Frequency range</td></tr>
<tr>
<td>Example</td><td>Internet connection</td><td>FM radio signal (for example, 88–108 MHz)</td></tr>
</tbody>
</table>
</div><h3 id="heading-bandwidth-in-shared-networks">Bandwidth in Shared Networks</h3>
<p>In shared environments – like home Wi-Fi or public hotspots – everyone taps into the same bandwidth. If bandwidth is limited and several devices are streaming, gaming, or downloading, the network slows down for everyone.</p>
<h2 id="heading-throughput-what-gets-delivered">Throughput – What Gets Delivered</h2>
<p>While <strong>bandwidth</strong> is the <em>potential</em> capacity of a channel (the width of the road), <strong>throughput</strong> is the <em>actual</em> rate at which data travels end‑to‑end under real‑world conditions. It’s the number of cars that make it through the city per minute, after red lights, speed limits, and detours.</p>
<p><strong>Key factors that influence throughput:</strong></p>
<ul>
<li><p><strong>Interference &amp; Noise</strong> (analog) or <strong>packet collisions</strong> (digital)</p>
</li>
<li><p><strong>Hardware Constraints</strong> (CPU, NICs, switches)</p>
</li>
<li><p><strong>Network Congestion</strong> (too many users/devices)</p>
</li>
<li><p><strong>Error Retransmissions</strong> (when packets get lost or corrupted)</p>
</li>
</ul>
<p><strong>Example:</strong> A “100 Mbps” link (bandwidth) might only sustain 80 Mbps of throughput because of TCP overhead, competing traffic, and occasional packet losses.</p>
<h3 id="heading-latency-and-delay-the-time-dimension">Latency and Delay – The Time Dimension</h3>
<p>Latency is the <em>time</em> it takes for a single bit (or packet) to travel from sender to receiver. Think of it as a travel time, whereas bandwidth and throughput are about volume.</p>
<ol>
<li><p><strong>Propagation Delay:</strong> Time for the signal to move through the medium (for example, light in fiber: ~200,000 km/s).</p>
</li>
<li><p><strong>Transmission Delay:</strong> Time to push all the bits of a packet onto the wire:<br> Packet Size (bits)÷Link Bandwidth (bps)\text{Packet Size (bits)} ÷ \text{Link Bandwidth (bps)}Packet Size (bits)÷Link Bandwidth (bps)</p>
</li>
<li><p><strong>Processing Delay:</strong> Time routers or switches spend examining headers, making forwarding decisions.</p>
</li>
<li><p><strong>Queuing Delay:</strong> Time packets wait in buffers when traffic spikes.</p>
</li>
</ol>
<p><strong>Real‑world story:</strong> During a long‑distance video call, even 100 ms of round‑trip latency can feel like talking through molasses – voices overlap, and the conversation feels stilted.</p>
<h3 id="heading-jitter-variability-in-arrival">Jitter – Variability in Arrival</h3>
<p><strong>Jitter</strong> is the inconsistency in packet arrival times. Even if the average latency is low, high jitter disrupts:</p>
<ul>
<li><p><strong>Audio/Video Streams:</strong> Choppy playback when packets clump or arrive too late.</p>
</li>
<li><p><strong>VoIP Calls:</strong> Glitches, echoes, or dropped words.</p>
</li>
</ul>
<p>You can mitigate this through Buffers and Quality of Service (QoS) agreements, which real‑time traffic to smooth out the delivery.</p>
<h3 id="heading-how-to-improve-performance">How to Improve Performance</h3>
<p>If I could go back in time and give myself one tip: Performance isn’t just about speed – it’s about reliability and consistency, too.</p>
<p><strong>Here’s what affects performance:</strong></p>
<ol>
<li><p><strong>Bandwidth:</strong> Think of this as the largest diameter of your internet pipe – how much data can actually move through it per second, usually in Mbps or Gbps.</p>
<p> <strong>Why it matters:</strong> More bandwidth means your connection can handle more data – like downloading big files fast or streaming in 4K. <strong>BUT:</strong> Just because your connection can go fast doesn't necessarily mean that it always does. That's where throughput comes in.</p>
</li>
<li><p><strong>Throughput:</strong> Your actual speed – how much data is really passing through the pipe right now.</p>
<p> <strong>Why it matters:</strong> Your actual internet experience (web page loading, Netflix streaming, gaming) is throughput-dependent, not bandwidth-dependent. If your throughput is bad, your videos buffer, downloads crawl, and games lag – even when you're signed up for a "fast" plan.</p>
</li>
<li><p><strong>Latency &amp; Jitter: Latency</strong> is the lag – how long it takes information to travel from your machine back to the server and vice versa (in milliseconds). <strong>Jitter</strong> is the variation in that lag – how inconsistent the timing gets.</p>
<p> <strong>Why they're significant:</strong> High latency = frustrating delay in video calls, sluggish online gaming, or keyboard lag in remote desktops. High jitter = choppy audio, frozen faces, or desync'd video in live meetings or streams.</p>
</li>
<li><p><strong>Packet Loss:</strong> Sometimes, data just doesn't get to where it’s supposed to go. Packets are tiny chunks of data, and if a few get lost along the way, your device has to ask for them again.</p>
<p> <strong>Why it matters:</strong> Small levels of packet loss can cause buffering, call drops, or rubberbanding during gaming. Greater loss = subpar performance, stuttery audio, or crashed streams.</p>
</li>
<li><p><strong>Utilization &amp; Overhead: Utilization</strong> refers to what ratio of your total bandwidth is being used at any one time. <strong>Overhead</strong> is the extra information that needs to be dealt with to manage your connection – like labels on a package.</p>
<p> <strong>Why they're important:</strong> High utilization is when your connection gets crowded – for example, rush hour. Everything slows down. High overhead absorbs your free bandwidth – less room for what you actually love (video, games, files).</p>
</li>
</ol>
<p>Engineers use <a target="_blank" href="https://www.parkplacetechnologies.com/blog/network-optimization-performance-techniques/">techniques</a> like compression, efficient routing, better cabling, and load balancing to improve performance.</p>
<p>I now see bandwidth everywhere – not just in networks, but in life. Our mental bandwidth, emotional bandwidth – it's all about capacity. Knowing how bandwidth works helped me troubleshoot slow Wi-Fi, plan file transfers, and appreciate what’s going on behind a simple Google search.</p>
<p>Just as in life with mental or emotional bandwidth, we need both ca<em>pacity</em> and <em>consistency</em> to function at our best. Understanding these metrics empowers you to diagnose slow Wi‑Fi, optimize file transfers, and build networks that meet real user demands.</p>
<h2 id="heading-chapter-4-transmission-media-the-highways-of-communication"><strong>Chapter 4: Transmission Media — The Highways of Communication</strong></h2>
<p>How does data move across distances? What path does it take?</p>
<p>This chapter dives into the physical and wireless pathways data takes from one device to another – the <strong>transmission media</strong>. By the end of this chapter, you will understand:</p>
<ul>
<li><p>What transmission media is and why it matters</p>
</li>
<li><p>The difference between guided (wired) and unguided (wireless) media</p>
</li>
<li><p>Various types of cables (twisted pair, coaxial, fiber optics)</p>
</li>
<li><p>Wireless media like radio waves, microwaves, and infrared</p>
</li>
<li><p>The strengths and limitations of each medium</p>
</li>
</ul>
<h2 id="heading-what-are-transmission-media">What are Transmission Media?</h2>
<p>Imagine needing to deliver a letter. Do you send it through a postal truck? Drop it by drone? Deliver it by hand? The method you choose is your <strong>transmission medium</strong>.</p>
<p>In the digital world, transmission media refers to the path data takes from the sender to the receiver. These paths can be <strong>physical (guided)</strong>, like cables, or <strong>wireless (unguided)</strong>, like airwaves.</p>
<p>When I finally understood that even invisible data needs a “road,” I realized how crucial this topic was to building fast, reliable networks.</p>
<h2 id="heading-different-types-of-transmission-media">Different Types of Transmission Media</h2>
<p>Transmission media are classified into two broad categories:</p>
<ol>
<li><p><strong>Guided Media</strong> (Wired): The data follows a specific path (like a road or railway). Common types include a Twisted Pair cable, a Coaxial cable, and a Fiber Optic cable.</p>
</li>
<li><p><strong>Unguided Media</strong> (Wireless): Data floats freely through the atmosphere, like radio signals or Wi-Fi. Types include Radio Waves, Microwaves, and Infrared Waves.</p>
</li>
</ol>
<p>Let’s dive into each of these types of transmission media in a bit more detail.</p>
<h3 id="heading-guided-transmission-media">Guided Transmission Media</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748674489096/fe9c0cfd-6aaf-4746-a129-8c994287a976.png" alt="Guided Transmission media" class="image--center mx-auto" width="634" height="425" loading="lazy"></p>
<h4 id="heading-1-twisted-pair-cable">1. Twisted Pair Cable</h4>
<p>This was the first cable I ever handled – it looked like two wires twisted together. Signals are transmitted as tiny voltage differences between the two copper conductors. By twisting the pair, electromagnetic interference picked up on one wire tends to be canceled out on the other, since each twist reverses their positions relative to the noise source.</p>
<p><strong>Features &amp; Use‑Cases:</strong></p>
<ul>
<li><p><strong>Structure</strong>: Two insulated copper wires twisted to reduce interference.</p>
</li>
<li><p><strong>Types</strong>:</p>
<ul>
<li><p><strong>Unshielded Twisted Pair (UTP)</strong>: Common in LANs, cheaper but more prone to noise.</p>
</li>
<li><p><strong>Shielded Twisted Pair (STP)</strong>: Has shielding for better noise protection.</p>
</li>
</ul>
</li>
<li><p><strong>Usage</strong>: Telephones, Ethernet.</p>
</li>
<li><p><strong>Bandwidth</strong>: Low to medium.</p>
</li>
<li><p><strong>Distance</strong>: Up to 100 meters (for UTP).</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748674630033/34e507b8-4c67-4e47-9275-a37dd48191e4.png" alt="Twisted pair cable" class="image--center mx-auto" width="326" height="191" loading="lazy"></p>
<h4 id="heading-2-coaxial-cable">2. Coaxial Cable</h4>
<p>I remember unscrewing one from the back of our old TV. A single copper core carries the signal; an insulating layer and an outer metal shield form a concentric geometry. The signal propagates as an electromagnetic wave confined between the inner conductor and shield, which also blocks external noise.</p>
<p><strong>Features &amp; Use‑Cases:</strong></p>
<ul>
<li><p><strong>Structure</strong>: A central copper core, surrounded by insulation, a metal shield, and an outer plastic cover.</p>
</li>
<li><p><strong>Advantages</strong>: Better shielding, higher bandwidth than UTP.</p>
</li>
<li><p><strong>Usage</strong>: Cable TV, broadband internet.</p>
</li>
<li><p><strong>Distance</strong>: Up to several kilometers with amplifiers.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748675087884/6a7d9a7c-a0a9-4780-b43d-69dd1d581a26.png" alt="Coaxial Cable" class="image--center mx-auto" width="326" height="191" loading="lazy"></p>
<h4 id="heading-3-fiber-optic-cable">3. Fiber Optic Cable</h4>
<p>This one blew my mind – light carrying data! Data is encoded into light pulses (laser or LED) sent down a glass or plastic core. Total internal reflection at the core–cladding interface traps light, allowing it to travel long distances with almost no loss.</p>
<p><strong>Features &amp; Use‑Cases:</strong></p>
<ul>
<li><p><strong>Structure</strong>: Glass or plastic core surrounded by cladding and a protective sheath.</p>
</li>
<li><p><strong>Types</strong>:</p>
<ul>
<li><p><strong>Single-Mode Fiber</strong>: For long distances, uses a laser.</p>
</li>
<li><p><strong>Multi-Mode Fiber</strong>: For shorter distances, uses LED.</p>
</li>
</ul>
</li>
<li><p><strong>Advantages</strong>:</p>
<ul>
<li><p>Immune to electromagnetic interference</p>
</li>
<li><p>Higher bandwidth and longer distances</p>
</li>
<li><p>More secure and reliable</p>
</li>
</ul>
</li>
<li><p><strong>Usage</strong>: Backbone of the internet, submarine cables, hospitals.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748675141484/627c2f1c-c6bb-4959-ae7e-5d59e427d3ae.png" alt="Fiber-optic Cable" class="image--center mx-auto" width="326" height="191" loading="lazy"></p>
<h3 id="heading-unguided-transmission-media">Unguided Transmission Media</h3>
<p>When you connect to Wi-Fi or use Bluetooth, you are relying on unguided media. These don’t need a cable – just air.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748675235793/0c0f16b4-e96c-4056-9240-c908fba813f8.png" alt="Wireless Communication" class="image--center mx-auto" width="326" height="191" loading="lazy"></p>
<p>There are several different kinds of unguided transmission media. Let’s talk about some of the most common.</p>
<h4 id="heading-1-radio-waves">1. Radio Waves</h4>
<p><strong>How It Works:</strong><br>Antennas convert electrical signals into electromagnetic waves (and vice versa). Radio frequencies (3 kHz–1 GHz) propagate omnidirectionally (or in broad beams) through the air and can diffract around obstacles.</p>
<ul>
<li><p><strong>Pros:</strong> Penetrates walls; easy broadcast to many receivers.</p>
</li>
<li><p><strong>Cons:</strong> Susceptible to interference and eavesdropping.</p>
</li>
<li><p><strong>Applications:</strong> FM/AM radio, Wi‑Fi (2.4 GHz band), Bluetooth, cordless phones.</p>
</li>
</ul>
<h4 id="heading-2-microwaves">2. Microwaves</h4>
<p><strong>How It Works:</strong><br>Highly directional beams (1 GHz–300 GHz) generated by parabolic dishes or waveguide antennas. Because they travel in straight lines (line‑of‑sight), they must be carefully aligned between towers or rooftop dishes.</p>
<ul>
<li><p><strong>Pros:</strong> High data rates, cellular backhaul, satellite links.</p>
</li>
<li><p><strong>Cons:</strong> Rain fade, clear path required, more expensive antennas.</p>
</li>
<li><p><strong>Applications:</strong> Mobile networks, satellite TV, point‑to‑point enterprise links.</p>
</li>
</ul>
<h4 id="heading-3-infrared">3. Infrared</h4>
<p><strong>How It Works:</strong><br>LED or laser diodes emit infrared light pulses, which are detected by photodiodes on the receiver. Because IR light cannot pass through walls, it works only in a confined, line‑of‑sight – or within a reflective “cone.”</p>
<ul>
<li><p><strong>Pros:</strong> Highly secure (confined to room), no RF interference.</p>
</li>
<li><p><strong>Cons:</strong> Very short range; blocked by obstacles; strict alignment.</p>
</li>
<li><p><strong>Applications:</strong> TV remotes, short‑range device pairing, some industrial sensors.</p>
</li>
</ul>
<h3 id="heading-comparison-table">Comparison Table</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Medium</strong></td><td><strong>Speed</strong></td><td><strong>Distance</strong></td><td><strong>Interference</strong></td><td><strong>Cost</strong></td><td><strong>Usage</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Twisted Pair</td><td>Low-Medium</td><td>~100m</td><td>High</td><td>Low</td><td>LAN, telephony</td></tr>
<tr>
<td>Coaxial</td><td>Medium</td><td>~2km (amplified)</td><td>Medium</td><td>Medium</td><td>Cable TV, broadband</td></tr>
<tr>
<td>Fiber Optic</td><td>Very High</td><td>&gt;60km (with repeaters)</td><td>Very Low</td><td>High</td><td>Backbone, high-speed</td></tr>
<tr>
<td>Radio</td><td>Low-Medium</td><td>Long (via towers)</td><td>High</td><td>Low</td><td>Wi-Fi, radio, Bluetooth</td></tr>
<tr>
<td>Microwave</td><td>High</td><td>Long (LOS)</td><td>Medium</td><td>High</td><td>Mobile, satellites</td></tr>
<tr>
<td>Infrared</td><td>Low</td><td>Short</td><td>Very Low</td><td>Low</td><td>Remotes, IR sensors</td></tr>
</tbody>
</table>
</div><hr>
<h3 id="heading-how-to-choose-the-right-transmission-medium">How to Choose the Right Transmission Medium</h3>
<p>When I set up my first home network, I had to think about speed, distance, and cost. That’s what engineers do when designing large networks, too.</p>
<p><strong>Questions to ask yourself or your team:</strong></p>
<ul>
<li><p>How far does the data need to travel?</p>
</li>
<li><p>How fast do I need the connection?</p>
</li>
<li><p>Can I afford high-end cables or equipment?</p>
</li>
<li><p>Is the environment prone to interference?</p>
</li>
</ul>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Scenario</td><td>Best Medium</td><td>Why &amp; How to Decide</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Home LAN &amp; Office Ethernet</strong></td><td>Cat6 UTP</td><td>Affordable, easy to install, handles Gigabit speeds up to 100 m.</td></tr>
<tr>
<td><strong>No‑Cable Wireless Access</strong></td><td>Wi‑Fi (2.4/5 GHz)</td><td>Easy coverage of rooms; choose 5 GHz for less interference, higher speed.</td></tr>
<tr>
<td><strong>Long‑Distance Fiber Backbone</strong></td><td>Single‑Mode Fiber</td><td>Minimal signal loss over tens of kilometers; vital for ISP backbones.</td></tr>
<tr>
<td><strong>Campus/Building Interconnect</strong></td><td>Multi‑Mode Fiber</td><td>Supports 10–100 Gbps across campus; lower cost than single‑mode for short runs.</td></tr>
<tr>
<td><strong>Point‑to‑Point Enterprise Link</strong></td><td>Microwave Link</td><td>Rapid deployment between buildings; ensure clear LOS and proper dish alignment.</td></tr>
<tr>
<td><strong>Industrial/Noisy Environments</strong></td><td>Shielded Twisted‑Pair or Fiber</td><td>STP resists EMI ; fiber is immune but costlier.</td></tr>
<tr>
<td><strong>Room‑Confined, Secure Control Signals</strong></td><td>Infrared</td><td>Perfect for IR‑controlled lighting or remote‑only devices in one room.</td></tr>
<tr>
<td><strong>Broad Wireless Broadcast</strong></td><td>Radio Waves</td><td>For wide‑area IoT sensors or broadcast audio; simple omnidirectional antennas.</td></tr>
</tbody>
</table>
</div><ol>
<li><p><strong>Define Distance &amp; Speed:</strong></p>
<ul>
<li><p>Short run (&lt;100 m) + moderate speed → UTP.</p>
</li>
<li><p>Long haul → fiber or microwave.</p>
</li>
</ul>
</li>
<li><p><strong>Assess Environment:</strong></p>
<ul>
<li><p>High EMI (factories) → fiber or STP.</p>
</li>
<li><p>Indoor home/office → UTP or Wi‑Fi.</p>
</li>
</ul>
</li>
<li><p><strong>Consider Mobility:</strong></p>
<ul>
<li>Devices moving around → wireless (Wi‑Fi, cellular).</li>
</ul>
</li>
<li><p><strong>Weigh Cost vs. Performance:</strong></p>
<ul>
<li><p>Budget LAN → UTP</p>
</li>
<li><p>Critical backbone → fiber</p>
</li>
</ul>
</li>
<li><p><strong>Security Needs:</strong></p>
<ul>
<li><p>Room‑confined control → infrared</p>
</li>
<li><p>Open campus → directional microwave or encrypted Wi‑Fi</p>
</li>
</ul>
</li>
</ol>
<p>By matching distance, throughput requirements, environmental constraints, and budget, you can select the transmission medium that delivers optimal real‑world performance, just as engineers do when designing networks that power everything from our smartphones to submarine data cables.</p>
<p>Learning about transmission media made me realize how much effort goes into a simple text message. Whether it’s a copper wire under the road or a beam of light under the ocean, there’s always a path connecting us.</p>
<p>I now see cables and antennas not just as hardware, but as lifelines of human connection. They are the highways of our digital lives.</p>
<h2 id="heading-chapter-5-network-topologies-how-we-structure-our-connections"><strong>Chapter 5: Network Topologies — How We Structure Our Connections</strong></h2>
<p>The word “topology”, in the context of networking, refers to how devices are arranged and connected. This chapter helps you see that the structure of a network is just as important as the technology it uses.</p>
<p>By the end of this chapter, you will:</p>
<ul>
<li><p>Understand what a network topology is and why it matters</p>
</li>
<li><p>Explore different types of physical and logical topologies</p>
</li>
<li><p>Learn the pros and cons of each layout (bus, ring, star, mesh, hybrid)</p>
</li>
<li><p>Recognize how topology affects performance, scalability, and fault tolerance</p>
</li>
</ul>
<h2 id="heading-what-is-topology">What is Topology?</h2>
<p>If you’ve ever arranged chairs in a room for a meeting, you’ve thought about topology. Should everyone face forward? Sit in a circle? Group up in clusters?</p>
<p>Networking topology is the same idea – it’s about the <strong>layout of devices and how they connect</strong>. Whether you're designing a small home LAN or a vast corporate network, choosing the right topology affects everything: speed, cost, troubleshooting, and scalability.</p>
<h2 id="heading-physical-vs-logical-topology">Physical vs Logical Topology</h2>
<h3 id="heading-physical-topology">Physical Topology</h3>
<p>This is what you can see – the actual layout of wires and devices.</p>
<p><strong>Example:</strong> You see computers in a classroom connected by cables to a central switch. That’s the physical topology.</p>
<h3 id="heading-logical-topology">Logical Topology</h3>
<p>This is how data flows, regardless of how devices are physically connected.</p>
<p><strong>Example:</strong> Even if computers are wired to a switch (star), the data may travel like a bus – this makes it a logical bus topology (more on this below).</p>
<p>It’s like a subway map vs. the actual underground tunnels – one shows the concept, the other shows the reality.</p>
<h2 id="heading-types-of-network-topologies">Types of Network Topologies</h2>
<p>Let’s go through the main types of network topologies. Each has strengths, weaknesses, and ideal use cases.</p>
<h3 id="heading-bus-topology">Bus Topology</h3>
<p>Imagine one long cable – all devices “tap into” it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748937876952/03749b9f-55a9-4864-8727-c82d5f8f7df6.png" alt="Bus Topology – Shiksha" class="image--center mx-auto" width="408" height="227" loading="lazy"></p>
<p>In a bus topology, a single backbone cable connects all devices.</p>
<ul>
<li><p><strong>Pros</strong>:</p>
<ul>
<li><p>Simple and cheap</p>
</li>
<li><p>Uses less cable</p>
</li>
</ul>
</li>
<li><p><strong>Cons</strong>:</p>
<ul>
<li><p>If the backbone fails, the whole network goes down</p>
</li>
<li><p>Difficult to troubleshoot</p>
</li>
<li><p>Performance degrades with more devices</p>
</li>
</ul>
</li>
<li><p><strong>Use case</strong>: Small temporary networks</p>
</li>
</ul>
<h3 id="heading-ring-topology">Ring Topology</h3>
<p>Here, each device connects to exactly two others, forming a circle.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748938093608/fbdd3460-1631-4959-abac-145c7ead69a1.png" alt="Ring Topology – Shiksha" class="image--center mx-auto" width="433" height="285" loading="lazy"></p>
<p>In this case, data travels in one direction, passing through each node.</p>
<ul>
<li><p><strong>Pros</strong>:</p>
<ul>
<li><p>Easy to install</p>
</li>
<li><p>Better than bus for managing traffic</p>
</li>
</ul>
</li>
<li><p><strong>Cons</strong>:</p>
<ul>
<li><p>Failure in one node can break the ring</p>
</li>
<li><p>Adding/removing nodes is disruptive</p>
</li>
</ul>
</li>
<li><p><strong>Use case</strong>: Token Ring networks (rare today)</p>
</li>
</ul>
<h3 id="heading-star-topology">Star Topology</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748938238120/78f568ef-4d7c-493a-a574-be59551f2bbf.png" alt="Star Topology – Shiksha" class="image--center mx-auto" width="288" height="230" loading="lazy"></p>
<p>This is what I used when setting up a LAN in my home. All devices connect to a central hub or switch.</p>
<ul>
<li><p><strong>Pros</strong>:</p>
<ul>
<li><p>Easy to install and manage</p>
</li>
<li><p>Failure of one device doesn’t affect the rest</p>
</li>
</ul>
</li>
<li><p><strong>Cons</strong>:</p>
<ul>
<li><p>If the central device fails, everything goes down</p>
</li>
<li><p>Requires more cable</p>
</li>
</ul>
</li>
<li><p><strong>Use case</strong>: Modern Ethernet networks</p>
</li>
</ul>
<h3 id="heading-mesh-topology">Mesh Topology</h3>
<p>This one fascinated me because of its complexity.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748938980213/81eb109a-1acb-4932-a8c0-17445591d660.png" alt="Mesh Topology – Shiksha" class="image--center mx-auto" width="468" height="263" loading="lazy"></p>
<p>In a mesh topology, every device is connected to every other device.</p>
<ul>
<li><p><strong>Pros</strong>:</p>
<ul>
<li><p>Redundant paths ensure reliability</p>
</li>
<li><p>Excellent fault tolerance</p>
</li>
</ul>
</li>
<li><p><strong>Cons</strong>:</p>
<ul>
<li><p>Expensive and complex to install</p>
</li>
<li><p>Requires lots of cabling</p>
</li>
</ul>
</li>
<li><p><strong>Use case</strong>: Military, critical systems, backbone networks</p>
</li>
</ul>
<h3 id="heading-hybrid-topology">Hybrid Topology</h3>
<p>Like a recipe with ingredients from different cuisines.</p>
<p><img src="https://images.shiksha.com/mediadata/images/articles/1709021924phpTqwiOP.jpeg" alt="What is Hybrid Topology – Shiksha" width="600" height="400" loading="lazy"></p>
<p>A hybrid topology works by combining two or more topologies.</p>
<ul>
<li><p><strong>Pros</strong>:</p>
<ul>
<li><p>Flexible and scalable</p>
</li>
<li><p>Can be tailored to specific needs</p>
</li>
</ul>
</li>
<li><p><strong>Cons</strong>:</p>
<ul>
<li>Complex design and management</li>
</ul>
</li>
<li><p><strong>Use case</strong>: Large organizations with diverse requirements</p>
</li>
</ul>
<h3 id="heading-comparison-table-1">Comparison Table</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Topology</strong></td><td><strong>Cost</strong></td><td><strong>Reliability</strong></td><td><strong>Scalability</strong></td><td><strong>Complexity</strong></td><td><strong>Use Case</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Bus</td><td>Low</td><td>Low</td><td>Low</td><td>Low</td><td>Small LANs</td></tr>
<tr>
<td>Ring</td><td>Medium</td><td>Medium</td><td>Low</td><td>Medium</td><td>Outdated systems</td></tr>
<tr>
<td>Star</td><td>Medium</td><td>Medium-High</td><td>High</td><td>Low</td><td>Homes, offices</td></tr>
<tr>
<td>Mesh</td><td>High</td><td>Very High</td><td>Medium</td><td>Very High</td><td>Data centers, military</td></tr>
<tr>
<td>Hybrid</td><td>High</td><td>High</td><td>Very High</td><td>High</td><td>Enterprises</td></tr>
</tbody>
</table>
</div><hr>
<h3 id="heading-how-to-choose-the-right-topology">How to Choose the Right Topology</h3>
<p>When I built my first network for a class project, I went with a <strong>star topology</strong>. Why? Because it was easy to set up and troubleshoot, and it matched our desk layout, with all PCs around a central switch. That hands-on experience taught me that the right topology isn’t just about wiring – it’s about reliability, cost, and how people use the network.</p>
<p>Think of it like planning a city:</p>
<ul>
<li><p>Where are the busiest hubs?</p>
</li>
<li><p>Do you need alternate routes in case one fails?</p>
</li>
<li><p>Can you maintain all the connections?</p>
</li>
</ul>
<h3 id="heading-common-network-topologies-and-when-to-use-them">Common Network Topologies and When to Use Them</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Topology</td><td>How It Works</td><td>When to Use It</td><td>Pros</td><td>Cons</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Bus</strong></td><td>All devices share a single backbone cable</td><td>Very small networks, temporary setups, or budget constraints</td><td>Cheap, minimal cabling</td><td>Hard to troubleshoot, poor scalability, one break = network down</td></tr>
<tr>
<td><strong>Star</strong></td><td>Devices connect to a central hub or switch</td><td>Home networks, classrooms, offices</td><td>Easy to manage, isolate issues, scalable</td><td>Hub is single point of failure</td></tr>
<tr>
<td><strong>Ring</strong></td><td>Each device connects to two others forming a closed loop</td><td>Legacy systems or specialized industrial networks</td><td>Predictable data flow, fair traffic management</td><td>Break in loop can halt the network unless dual ring used</td></tr>
<tr>
<td><strong>Mesh</strong></td><td>Every device connects to multiple others</td><td>Critical systems (e.g. military, finance), where uptime is vital</td><td>Highly fault-tolerant, redundant paths</td><td>Expensive, complex, heavy cabling</td></tr>
<tr>
<td><strong>Hybrid</strong></td><td>Mix of two or more topologies</td><td>Large enterprises or campuses</td><td>Flexible, optimized for different departments</td><td>Can be complex and costly to manage</td></tr>
</tbody>
</table>
</div><hr>
<h3 id="heading-how-to-actually-choose-a-topology-real-life-scenarios">How to Actually Choose a Topology (Real-Life Scenarios)</h3>
<p>Let’s move beyond theory. Here’s how you'd pick a topology depending on your network goals and constraints:</p>
<h4 id="heading-1-need-a-simple-setup-with-a-tight-budget">1. Need a simple setup with a tight budget?</h4>
<ul>
<li><p><strong>Choose:</strong> Bus or Star</p>
</li>
<li><p><strong>Why:</strong> Bus requires minimal cabling (but be warned—it’s fragile); Star uses affordable switches and is easy to expand.</p>
</li>
<li><p><strong>Example:</strong> Setting up a temporary lab or a network for a rural clinic.</p>
</li>
</ul>
<h4 id="heading-2-setting-up-a-home-or-small-office">2. Setting up a home or small office?</h4>
<ul>
<li><p><strong>Choose:</strong> Star</p>
</li>
<li><p><strong>Why:</strong> It mirrors how devices are physically placed. One faulty PC won’t crash the whole network.</p>
</li>
<li><p><strong>Example:</strong> Wi-Fi router (the central node) with laptops, smart TVs, and printers.</p>
</li>
</ul>
<h4 id="heading-3-running-a-business-with-multiple-departments">3. Running a business with multiple departments?</h4>
<ul>
<li><p><strong>Choose:</strong> Hybrid (Star + Mesh or Star + Ring)</p>
</li>
<li><p><strong>Why:</strong> Combine flexibility with reliability. Use star for offices, mesh for server interconnects.</p>
</li>
<li><p><strong>Example:</strong> A university with classrooms (star) and data centers (mesh).</p>
</li>
</ul>
<h4 id="heading-4-downtime-is-a-dealbreaker">4. Downtime is a dealbreaker?</h4>
<ul>
<li><p><strong>Choose:</strong> Mesh</p>
</li>
<li><p><strong>Why:</strong> Redundant paths keep communication alive even if several links fail.</p>
</li>
<li><p><strong>Example:</strong> Military control center or emergency dispatch system.</p>
</li>
</ul>
<h4 id="heading-5-working-with-legacy-systems">5. Working with legacy systems?</h4>
<ul>
<li><p><strong>Choose:</strong> Ring</p>
</li>
<li><p><strong>Why:</strong> Some older systems (like token ring networks or SONET) require ring layouts.</p>
</li>
<li><p><strong>Example:</strong> Legacy manufacturing networks that still run on ring-based designs.</p>
</li>
</ul>
<h4 id="heading-6-expecting-rapid-growth">6. Expecting rapid growth?</h4>
<ul>
<li><p><strong>Choose:</strong> Star or Hybrid</p>
</li>
<li><p><strong>Why:</strong> You can easily add more nodes to the central hub or integrate new segments.</p>
</li>
<li><p><strong>Example:</strong> A startup anticipating more staff and devices within 6–12 months.</p>
</li>
</ul>
<h3 id="heading-tips-from-experience">Tips from Experience</h3>
<ul>
<li><p><strong>Think long-term</strong>: Design for tomorrow’s load, not just today’s.</p>
</li>
<li><p><strong>Plan for failures</strong>: Even if you don’t need full mesh, maybe add backup links for your star’s hub.</p>
</li>
<li><p><strong>Sketch the layout</strong>: Visualizing devices and data flow helps you pick the best design.</p>
</li>
<li><p><strong>Consider wireless topologies too</strong>: For mobile or flexible environments, wireless mesh or infrastructure-based topologies might be better than wired ones.</p>
</li>
</ul>
<p>Just like roads and power lines shape how a city grows, your network topology shapes how your digital systems evolve. The best layout isn’t the one with the fanciest name – it’s the one that fits your users, your budget, and your goals.</p>
<p>Choose thoughtfully, and your network becomes more than wires – it becomes infrastructure for productivity, connection, and growth.</p>
<p>Network topology is the blueprint for that digital city. When done right, everything flows. When it’s messy, things get congested, slow, or fail. And that’s why I now look at every network not just as wires and switches, but as architecture, with a purpose and design.</p>
<h2 id="heading-chapter-6-the-osi-model-understanding-layers-of-communication"><strong>Chapter 6: The OSI Model — Understanding Layers of Communication</strong></h2>
<p>The OSI model is like a translator – it helps all types of systems speak the same language. And it’s everywhere.</p>
<p>In this chapter, you will:</p>
<ul>
<li><p>Understand what the OSI model is and why it was created</p>
</li>
<li><p>Learn what each of the 7 layers does</p>
</li>
<li><p>Discover how the layers work together during communication</p>
</li>
<li><p>Apply real-life analogies to remember each layer’s role</p>
</li>
</ul>
<h2 id="heading-what-is-the-osi-model">What is the OSI Model?</h2>
<p>Picture this: you want to send a letter. You write it 📝 → put it in an envelope ✉️ → mail it 📮 → it goes to your friend’s house 🏠 → they open it 👐 → and read it 👀.</p>
<p>That’s basically how the <strong>OSI Model</strong> works. The OSI (Open Systems Interconnection) model is a conceptual framework that describes <strong>how data moves from one device to another</strong> in a network. Instead of all systems operating differently, the OSI model helps break down communication into 7 distinct layers.</p>
<p>Each layer has a specific task, and together they make communication structured, understandable, and interoperable.</p>
<p>Developed by the <strong>International Organization for Standardization (ISO)</strong>, the OSI model was created to provide a universal standard for different systems to communicate.</p>
<p>Think of it like this: You’re building a house. You wouldn’t put the roof before the walls. Similarly, data follows an order, moving through each of these layers – from sender to receiver.</p>
<p>The 7 layers of the OSI model are:</p>
<ol>
<li><p><strong>Application</strong> (your browser or app)</p>
</li>
<li><p><strong>Presentation</strong> (formatting, encrypting)</p>
</li>
<li><p><strong>Session</strong> (starting/ending chats)</p>
</li>
<li><p><strong>Transport</strong> (reliable delivery)</p>
</li>
<li><p><strong>Network</strong> (finding the route)</p>
</li>
<li><p><strong>Data Link</strong> (organizing the data)</p>
</li>
<li><p><strong>Physical</strong> (the actual wires or Wi-Fi)</p>
</li>
</ol>
<p>It’s teamwork that makes the stream work!</p>
<p>An easy mnemonic I used to memorize them (from top to bottom): <strong>“All People Seem To Need Data Processing.”</strong></p>
<p>Let’s explore each layer from the bottom (Layer 1) to the top (Layer 7):</p>
<h3 id="heading-layer-1-physical-layer">Layer 1 – Physical Layer</h3>
<p>This is the <strong>hardware level</strong>.</p>
<ul>
<li><p>Handles: cables, switches, voltages, pins</p>
</li>
<li><p>Responsible for: physically transmitting raw bits (0s and 1s)</p>
</li>
<li><p>Example: Ethernet cables, fiber optics</p>
</li>
</ul>
<p><strong>Analogy</strong>: The roads on which data travels.</p>
<h3 id="heading-layer-2-data-link-layer">Layer 2 – Data Link Layer</h3>
<p>Ensures reliable transfer across the physical link.</p>
<ul>
<li><p>Handles: MAC addresses, framing, error detection</p>
</li>
<li><p>Divided into:</p>
<ul>
<li><p><strong>Logical Link Control (LLC)</strong></p>
</li>
<li><p><strong>Media Access Control (MAC)</strong></p>
</li>
</ul>
</li>
<li><p>Example: Switches, MAC addressing</p>
</li>
</ul>
<p><strong>Analogy</strong>: Street signs and traffic signals managing who goes when.</p>
<h3 id="heading-layer-3-network-layer">Layer 3 – Network Layer</h3>
<p>This is about <strong>routing</strong> – finding the best path to the destination.</p>
<ul>
<li><p>Handles: IP addresses, packet forwarding</p>
</li>
<li><p>Devices: Routers</p>
</li>
<li><p>Protocols: IP, ICMP</p>
</li>
</ul>
<p><strong>Analogy</strong>: Google Maps calculating the best route.</p>
<h3 id="heading-layer-4-transport-layer">Layer 4 – Transport Layer</h3>
<p>Responsible for <strong>end-to-end communication</strong> and reliability.</p>
<ul>
<li><p>Handles: segmentation, flow control, error correction</p>
</li>
<li><p>Protocols: TCP (reliable), UDP (fast but no guarantee)</p>
</li>
</ul>
<p><strong>Analogy</strong>: Your personal driver, making sure you arrive safely.</p>
<h3 id="heading-layer-5-session-layer">Layer 5 – Session Layer</h3>
<p>This layer manages <strong>dialogues</strong> (sessions) between systems.</p>
<ul>
<li>Handles: session setup, management, and termination</li>
</ul>
<p><strong>Analogy</strong>: A host managing who gets to speak in a Zoom meeting.</p>
<h3 id="heading-layer-6-presentation-layer">Layer 6 – Presentation Layer</h3>
<p>Responsible for <strong>data formatting and translation</strong>.</p>
<ul>
<li><p>Handles: encryption, compression, data conversion</p>
</li>
<li><p>Example: JPEG, MP3, SSL, ASCII, EBCDIC</p>
</li>
</ul>
<p><strong>Analogy</strong>: A translator ensuring the data is understood.</p>
<h3 id="heading-layer-7-application-layer">Layer 7 – Application Layer</h3>
<p>The layer closest to the <strong>user</strong>.</p>
<ul>
<li><p>Handles: user interfaces, network services</p>
</li>
<li><p>Protocols: HTTP, FTP, SMTP, DNS</p>
</li>
</ul>
<p><strong>Analogy</strong>: The app you open – browser, email client, and so on.</p>
<h3 id="heading-communication-flow">Communication Flow</h3>
<p>When I send a message:</p>
<ul>
<li><p>It <strong>starts at Layer 7</strong> and goes down to Layer 1 at my device</p>
</li>
<li><p>Then <strong>travels</strong> across the medium</p>
</li>
<li><p>And <strong>climbs back up</strong> from Layer 1 to Layer 7 on the receiving device</p>
</li>
</ul>
<p>Each layer talks to its “peer” on the other device using a protocol.</p>
<h3 id="heading-why-the-osi-model-matters">Why the OSI Model Matters</h3>
<p>The OSI model is more than theory. It’s a <strong>map of the journey your data takes</strong> that helped give structure to the chaos. It’s also helped me think systematically about problems, identify where things break down, and appreciate the complexity behind “just sending a message.” When debugging a network problem, I ask:</p>
<ul>
<li><p>Is the cable plugged in? (Layer 1)</p>
</li>
<li><p>Is the MAC address correct? (Layer 2)</p>
</li>
<li><p>Can I ping the destination? (Layer 3)</p>
</li>
<li><p>Is the application service running? (Layer 7)</p>
</li>
</ul>
<p>It gave me a checklist to go through, along with some clarity.</p>
<p>Whether you’re a student or a network pro, these 7 layers are your best friends.</p>
<h2 id="heading-tcpip-the-real-mvp-of-the-internet"><strong>TCP/IP: The Real MVP of the Internet</strong></h2>
<p>While the OSI model is an ideal learning tool, the <strong>TCP/IP model</strong> is what the internet actually uses. It has only four layers, combining some of the OSI layers for simplicity and practicality:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>TCP/IP Layer</strong></td><td><strong>Corresponds to OSI Layers</strong></td><td><strong>Examples</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Application</td><td>Layers 5–7 (Application to Session)</td><td>HTTP, FTP, DNS, SMTP</td></tr>
<tr>
<td>Transport</td><td>Layer 4 (Transport)</td><td>TCP, UDP</td></tr>
<tr>
<td>Internet</td><td>Layer 3 (Network)</td><td>IP, ICMP</td></tr>
<tr>
<td>Network Access / Link</td><td>Layers 1–2 (Physical + Data Link)</td><td>Ethernet, Wi-Fi, MAC addresses</td></tr>
</tbody>
</table>
</div><p><strong>Why TCP/IP Matters:</strong></p>
<ul>
<li><p><strong>Scalable</strong>: It powers everything from home routers to global telecom infrastructure.</p>
</li>
<li><p><strong>Interoperable</strong>: Works across all hardware, operating systems, and devices.</p>
</li>
<li><p><strong>Fault-tolerant</strong>: TCP handles dropped packets, reordering, and error checking.</p>
</li>
<li><p><strong>Backbone of the Internet</strong>: Every website, email, or Zoom call runs over TCP/IP.</p>
</li>
</ul>
<h3 id="heading-how-tcpip-works-simplified-walkthrough">How TCP/IP Works (Simplified Walkthrough)</h3>
<p>Let’s say you open your browser and type in <code>www.example.com</code>.</p>
<ol>
<li><p><strong>Application Layer</strong> (HTTP): Your browser sends a request for a web page.</p>
</li>
<li><p><strong>Transport Layer</strong> (TCP): The request is broken into segments, with each piece numbered and prepared for reliable delivery.</p>
</li>
<li><p><strong>Internet Layer</strong> (IP): Each segment gets an IP address and is routed across networks.</p>
</li>
<li><p><strong>Network Access Layer</strong>: The data is turned into frames and signals, then physically transmitted over the internet (via cables or wireless).</p>
</li>
</ol>
<p>At the other end, the process reverses, and you see the web page appear on your screen.</p>
<h3 id="heading-osi-vs-tcpip-why-learn-both">OSI vs. TCP/IP: Why Learn Both?</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>OSI</strong></td><td><strong>TCP/IP</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Conceptual, educational model</td><td>Practical, real-world protocol suite</td></tr>
<tr>
<td>7 distinct layers</td><td>4 simplified layers</td></tr>
<tr>
<td>Rarely used directly in implementation</td><td>Foundation of the internet</td></tr>
</tbody>
</table>
</div><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750099098223/f767b099-c0db-4810-ab48-eacd95d8cf08.png" alt="OSI Model vs TCP/IP Model" class="image--center mx-auto" width="598" height="405" loading="lazy"></p>
<p>Think of the OSI model as a textbook diagram – helpful for troubleshooting and interviews. TCP/IP is the actual engine – streamlined and optimized for real-world communication.</p>
<h2 id="heading-chapter-7-protocols-and-ports-how-rules-and-doors-guide-communication"><strong>Chapter 7: Protocols and Ports — How Rules and Doors Guide Communication</strong></h2>
<p>Protocols and ports are the rules and gates that make it all happen smoothly. This chapter helps you appreciate how structured communication actually is.</p>
<p>By the end of this chapter, you will:</p>
<ul>
<li><p>Understand what protocols are and why they’re essential</p>
</li>
<li><p>Learn about standard protocols used in networking</p>
</li>
<li><p>Explore the concept of ports and their numbers</p>
</li>
<li><p>Discover how protocols and ports work together to manage communication</p>
</li>
</ul>
<h2 id="heading-the-importance-of-protocols-and-ports">The Importance of Protocols and Ports</h2>
<p>When I tried setting up a local web server for the first time, nothing loaded. It took me a while to realize I hadn’t opened the right port or used the correct protocol.</p>
<p><strong>Protocols</strong> are the rules that devices follow when talking to each other. <strong>Ports</strong> are like doors that allow specific types of data to come in and go out.</p>
<p>Without protocols and ports, communication would be total chaos.</p>
<h2 id="heading-what-is-a-protocol-1">What is a Protocol?</h2>
<p>A <strong>protocol</strong> is an agreed-upon set of rules for sending and receiving data.</p>
<p>Think of it like:</p>
<ul>
<li><p>A language: both sides must understand it</p>
</li>
<li><p>A traffic system: everyone follows the same rules to avoid crashes</p>
</li>
</ul>
<h3 id="heading-characteristics-of-good-protocols">Characteristics of Good Protocols</h3>
<p>For a protocol to be effective in communication, it must clearly define how data is structured, understood, and managed in time. Let’s break that down:</p>
<h4 id="heading-1-syntax-the-format-and-structure-of-the-data">1. Syntax – The Format and Structure of the Data</h4>
<p>Think of syntax like grammar in language. It defines:</p>
<ul>
<li><p><strong>Data format</strong> (for example, header, payload, footer)</p>
</li>
<li><p><strong>Order of fields</strong> in a message</p>
</li>
<li><p><strong>Encoding rules</strong> (for example, binary, ASCII, JSON, XML)</p>
</li>
</ul>
<p><strong>Example:</strong> In an email protocol like SMTP, the syntax might require that the sender and recipient addresses come in a specific format like <code>MAIL FROM:</code> and <code>RCPT TO:</code>.</p>
<p>A good protocol syntax is:</p>
<ul>
<li><p><strong>Consistent</strong> and <strong>unambiguous</strong></p>
</li>
<li><p>Easy to <strong>parse</strong> by machines</p>
</li>
<li><p>Designed to <strong>minimize errors</strong> in interpretation</p>
</li>
</ul>
<h4 id="heading-2-semantics-the-meaning-of-each-field">2. Semantics – The Meaning of Each Field</h4>
<p>Semantics defines what each piece of data means – what should be done with it.</p>
<ul>
<li><p><strong>What does a "200 OK" response mean in HTTP?</strong> (It means the request was successful.)</p>
</li>
<li><p><strong>What does a SYN flag mean in TCP?</strong> (It initiates a new connection.)</p>
</li>
</ul>
<p>Good protocol semantics:</p>
<ul>
<li><p>Ensure that both sender and receiver interpret the data in the same way</p>
</li>
<li><p>Clearly define error codes, commands, and responses</p>
</li>
<li><p>Support meaningful actions tied to each instruction</p>
</li>
</ul>
<h4 id="heading-3-timing-when-and-how-fast-to-communicate">3. Timing – When and How Fast to Communicate</h4>
<p>Timing refers to:</p>
<ul>
<li><p><strong>When messages are sent</strong> (synchronization)</p>
</li>
<li><p><strong>How fast</strong> messages should arrive (data rate)</p>
</li>
<li><p><strong>How long</strong> to wait before assuming failure (timeouts)</p>
</li>
</ul>
<p>A good protocol timing design:</p>
<ul>
<li><p>Prevents collisions (two devices sending at the same time)</p>
</li>
<li><p>Supports flow control to avoid overwhelming slower devices</p>
</li>
<li><p>Includes retransmission logic in case of delay or loss</p>
</li>
</ul>
<h3 id="heading-common-networking-protocols">Common Networking Protocols</h3>
<p>Before diving into details, here’s some context: A networking protocol is like a shared language for computers. It ensures that devices can communicate, share data, and coordinate actions reliably and securely.</p>
<h4 id="heading-tcp-transmission-control-protocol">TCP – Transmission Control Protocol</h4>
<p>TCP is the backbone of reliable internet communication.</p>
<p>It is:</p>
<ul>
<li><p><strong>Connection-oriented</strong>: A session is established before data is sent.</p>
</li>
<li><p><strong>Reliable</strong>: It ensures all data arrives correctly and in order using acknowledgments and retransmission.</p>
</li>
<li><p><strong>Error-checked</strong>: Includes checksums to detect and correct corruption.</p>
</li>
</ul>
<p>You use TCP in Web browsing (HTTP/HTTPS), email (SMTP), and file transfers (FTP). It’s like mailing a package with tracking and a required signature on delivery.</p>
<h4 id="heading-udp-user-datagram-protocol">UDP – User Datagram Protocol</h4>
<p>UDP is lightweight, fast, and doesn’t worry about delivery guarantees.</p>
<p>It is:</p>
<ul>
<li><p><strong>Connectionless</strong>: No handshake or setup, just send and forget.</p>
</li>
<li><p><strong>Low overhead</strong>: No acknowledgments or retransmission.</p>
</li>
<li><p><strong>Faster</strong> than TCP, but riskier for data loss.</p>
</li>
</ul>
<p>You use it in online gaming, voice calls (VoIP), and live video streaming. It’s like shouting a message across a noisy room – quick, but no guarantee it’ll be heard.</p>
<h4 id="heading-http-https-hypertext-transfer-protocol">HTTP / HTTPS – HyperText Transfer Protocol</h4>
<p>HTTP is the protocol of the web – it enables your browser to request and display web pages.</p>
<p>It is:</p>
<ul>
<li><p><strong>Stateless</strong>: Each request is independent.</p>
</li>
<li><p><strong>Based on the request-response model</strong>: Client sends a request; server responds.</p>
</li>
</ul>
<p>HTTPS adds encryption via SSL/TLS, making it secure for sensitive data (for example, online banking, logins).</p>
<p>It’s used for activities like browsing websites and in REST APIs.</p>
<h4 id="heading-ftp-file-transfer-protocol">FTP – File Transfer Protocol</h4>
<p>FTP is a classic protocol for transferring files between devices on a network.</p>
<p>It:</p>
<ul>
<li><p>Works in client-server mode</p>
</li>
<li><p>Requires authentication (username/password)</p>
</li>
<li><p>Is not secure on its own – can be enhanced with FTPS or replaced by SFTP (uses SSH)</p>
</li>
</ul>
<p>You can use it for website hosting and file backup systems.</p>
<h4 id="heading-smtp-pop3-imap-email-protocols">SMTP, POP3, IMAP – Email Protocols</h4>
<p>These are the three common email protocols, and each has its own features:</p>
<ul>
<li><p><strong>SMTP</strong> (Simple Mail Transfer Protocol): Used to send email from clients to servers or between servers.</p>
</li>
<li><p><strong>POP3</strong> (Post Office Protocol v3): Downloads emails to the device and usually deletes them from the server.</p>
</li>
<li><p><strong>IMAP</strong> (Internet Message Access Protocol): Keeps email on the server and synchronizes across devices.</p>
</li>
</ul>
<p>These are used in email clients like Outlook, Thunderbird, and Apple Mail.</p>
<h4 id="heading-dns-domain-name-system"><strong>DNS – Domain Name System</strong></h4>
<p>DNS is the internet’s phonebook – it converts human-readable names (like <code>google.com</code>) into IP addresses.</p>
<ul>
<li><p>Hierarchical and distributed system</p>
</li>
<li><p>Uses caching to speed up lookups</p>
</li>
<li><p>Works behind the scenes of every website visit</p>
</li>
</ul>
<p>It’s used in every internet-connected application that uses domain names.</p>
<h3 id="heading-what-is-a-port">What is a Port?</h3>
<p>A <strong>port</strong> is a virtual door on a device that allows certain kinds of data through.</p>
<p>Each application or service uses a specific <strong>port number</strong>, which ranges from 0 to 65535.</p>
<h4 id="heading-port-ranges">Port Ranges</h4>
<ul>
<li><p><strong>Well-known ports</strong>: 0–1023 (assigned to common services)</p>
</li>
<li><p><strong>Registered ports</strong>: 1024–49151 (used by user processes)</p>
</li>
<li><p><strong>Dynamic/Private ports</strong>: 49152–65535 (temporary or private use)</p>
</li>
</ul>
<h4 id="heading-common-port-numbers">Common Port Numbers</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Service</td><td>Protocol</td><td>Port</td></tr>
</thead>
<tbody>
<tr>
<td>HTTP</td><td>TCP</td><td>80</td></tr>
<tr>
<td>HTTPS</td><td>TCP</td><td>443</td></tr>
<tr>
<td>FTP</td><td>TCP</td><td>21</td></tr>
<tr>
<td>SSH</td><td>TCP</td><td>22</td></tr>
<tr>
<td>DNS</td><td>UDP/TCP</td><td>53</td></tr>
<tr>
<td>SMTP</td><td>TCP</td><td>25</td></tr>
<tr>
<td>POP3</td><td>TCP</td><td>110</td></tr>
<tr>
<td>IMAP</td><td>TCP</td><td>143</td></tr>
</tbody>
</table>
</div><h3 id="heading-how-protocols-and-ports-work-together">How Protocols and Ports Work Together</h3>
<p>Imagine you’re throwing a party:</p>
<ul>
<li><p><strong>Protocol</strong>: The invitation format – RSVP, dress code, rules.</p>
</li>
<li><p><strong>Port</strong>: The door your friends enter through.</p>
</li>
</ul>
<p>A web browser knows to use <strong>HTTP (protocol)</strong> on <strong>port 80</strong>. A secure connection will use <strong>HTTPS</strong> on <strong>port 443</strong>.</p>
<p>Your computer and servers use these pairings to know what type of data to expect.</p>
<p>Once I understood protocols and ports, troubleshooting network issues got easier. Suddenly, firewall rules, web server configs, and error messages started to make sense.</p>
<p>Protocols ensure everyone speaks the same language. Ports ensure everyone enters through the correct door.</p>
<p>They are the silent heroes of every network conversation.</p>
<h2 id="heading-chapter-8-ip-addressing-and-subnetting-naming-and-organizing-the-network"><strong>Chapter 8: IP Addressing and Subnetting — Naming and Organizing the Network</strong></h2>
<p>When I first saw an IP address like 192.168.0.1, I didn’t think much of it. But now I see it for what it is, the digital address that tells data where to go. In this chapter, you will learn:</p>
<ul>
<li><p>What an IP address is and why it's necessary</p>
</li>
<li><p>The difference between IPv4 and IPv6</p>
</li>
<li><p>How subnetting works and why it's useful</p>
</li>
<li><p>How to calculate and interpret IP ranges, subnet masks, and CIDR notation</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748436668531/8e7330cf-35f0-4c3d-a628-46261698b331.png" alt="IP Adress" class="image--center mx-auto" width="549" height="358" loading="lazy"></p>
<p>Imagine trying to mail a letter without an address – it would be lost forever. The same applies to data on a network. Every device needs a unique identifier called an <strong>IP address</strong> to send and receive information correctly.</p>
<p>IP addressing ensures that when I request a webpage, my data comes back to <strong>me</strong>, not someone else on the network.</p>
<h2 id="heading-what-is-an-ip-address">What is an IP Address?</h2>
<p>An IP address (Internet Protocol address) is a unique number assigned to every device on a network.</p>
<p>Every device on a network needs an IP address to identify it – like a phone number for computers. There are two main versions of IP addresses: <strong>IPv4</strong> and <strong>IPv6</strong>.</p>
<h3 id="heading-ipv4-vs-ipv6">IPv4 vs. IPv6</h3>
<p><strong>IPv4 (Internet Protocol version 4)</strong> is the older, more widely used system. It uses a <strong>32-bit address format</strong>, written as four numbers (each 0–255) separated by dots—for example: <code>192.168.1.1</code>. This format allows for about <strong>4.3 billion</strong> unique addresses.</p>
<p>But with the explosion of internet-connected devices, we quickly ran out of IPv4 addresses. That’s why <strong>IPv6 (Internet Protocol version 6)</strong> was introduced.IPv6 uses a <strong>128-bit address format</strong>, written in hexadecimal and separated by colons: <code>2001:0db8:85a3:0000:0000:8a2e:0370:7334</code>. This allows for a virtually unlimited number of addresses – <strong>over 340 undecillion</strong> (that’s 340 followed by 36 zeros)!</p>
<p>Let’s see a quick breakdown of the key details of each protocol:</p>
<h4 id="heading-ipv4-address-format">IPv4 Address Format</h4>
<ul>
<li><p>Composed of four numbers separated by dots</p>
</li>
<li><p>Each number ranges from 0 to 255 (i.e., 8 bits per number)</p>
</li>
<li><p>Total: 32 bits (4 x 8)</p>
</li>
<li><p>Example: <code>192.168.1.1</code></p>
</li>
</ul>
<h4 id="heading-ipv6-address-format">IPv6 Address Format</h4>
<ul>
<li><p>Created to solve the address shortage in IPv4</p>
</li>
<li><p>Composed of eight blocks of hexadecimal values</p>
</li>
<li><p>Total: 128 bits</p>
</li>
<li><p>Example: <code>2001:0db8:85a3:0000:0000:8a2e:0370:7334</code></p>
</li>
</ul>
<h3 id="heading-the-old-ipv4-class-system">The Old IPv4 Class System</h3>
<p>Originally, IPv4 addresses were grouped into <strong>classes</strong> to simplify allocation:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Class</td><td>Range</td><td>Default Subnet Mask</td><td>Use</td></tr>
</thead>
<tbody>
<tr>
<td>A</td><td>1.0.0.0 – 126.0.0.0</td><td>255.0.0.0</td><td>Large networks</td></tr>
<tr>
<td>B</td><td>128.0.0.0 – 191.255.0.0</td><td>255.255.0.0</td><td>Medium networks</td></tr>
<tr>
<td>C</td><td>192.0.0.0 – 223.255.255.0</td><td>255.255.255.0</td><td>Small networks</td></tr>
<tr>
<td>D</td><td>224.0.0.0 – 239.255.255.255</td><td>N/A</td><td>Multicasting</td></tr>
<tr>
<td>E</td><td>240.0.0.0 – 255.255.255.255</td><td>N/A</td><td>Reserved for future use</td></tr>
</tbody>
</table>
</div><p>But this system was too rigid. It wasted address space by assigning fixed block sizes, even when a network didn’t need that much.</p>
<h3 id="heading-enter-cidr-classless-inter-domain-routing">Enter CIDR: Classless Inter-Domain Routing</h3>
<p><strong>CIDR (pronounced "cider")</strong> replaced the old class system in the 1990s. CIDR allows for more flexible and efficient allocation of IP addresses. Instead of using predefined classes, CIDR uses a <strong>prefix length</strong> to specify how many bits represent the network portion.</p>
<ul>
<li>Example: <code>192.168.1.0/24</code>: This means the first 24 bits are the network, and the last 8 bits are available for hosts.</li>
</ul>
<p>CIDR made it easier to split (subnet) networks and slow the exhaustion of IPv4 addresses. We’ll discuss this more below.</p>
<h3 id="heading-does-ipv6-use-classes">Does IPv6 Use Classes?</h3>
<p>No, IPv6 does not use classes. It was designed from the start to avoid the inefficiencies of the class system. Instead, it uses a hierarchical structure and <strong>prefix notation</strong> similar to CIDR. IPv6 addresses are divided into:</p>
<ul>
<li><p><strong>Global unicast</strong> (like public IPv4 addresses)</p>
</li>
<li><p><strong>Link-local</strong> (used within a local network)</p>
</li>
<li><p><strong>Multicast</strong> (send to many devices at once)</p>
</li>
</ul>
<p>IPv6’s design naturally supports efficient routing and address assignment without needing "classes" as a workaround.</p>
<h2 id="heading-understanding-subnetting-and-related-concepts">Understanding Subnetting and Related Concepts</h2>
<p>After learning about IP addresses – especially the difference between IPv4 and IPv6 – it’s important to understand how networks manage and organize these addresses. That’s where <strong>subnetting</strong> comes in.</p>
<h3 id="heading-what-is-subnetting">What Is Subnetting?</h3>
<p>Think of a large network like a school compound. Subnetting is like dividing the school into classrooms or departments. It’s the process of dividing a larger network into smaller, more manageable subnetworks (subnets).</p>
<p>Subnetting helps with:</p>
<ul>
<li><p><strong>Efficient use of IP addresses</strong>: You don’t need to assign a huge range of addresses when only a few devices are needed.</p>
</li>
<li><p><strong>Network organization</strong>: Departments or teams can be separated into their own subnets.</p>
</li>
<li><p><strong>Better performance and security</strong>: Traffic stays local within each subnet, and issues in one subnet don’t affect the whole network.</p>
</li>
</ul>
<h3 id="heading-how-subnet-masks-work">How Subnet Masks Work</h3>
<p>To understand subnetting, we need to talk about <strong>subnet masks</strong>.</p>
<p>Every IPv4 address is divided into two parts:</p>
<ul>
<li><p>The <strong>network portion</strong> tells you <em>which</em> network it belongs to.</p>
</li>
<li><p>The <strong>host portion</strong> tells you <em>which specific device</em> (computer, phone, printer, and so on) on that network.</p>
</li>
</ul>
<p>A <strong>subnet mask</strong> tells us how to separate those two parts.</p>
<h4 id="heading-example">Example:</h4>
<ul>
<li><p><strong>IP Address</strong>: <code>192.168.1.10</code></p>
</li>
<li><p><strong>Subnet Mask</strong>: <code>255.255.255.0</code></p>
</li>
</ul>
<p>This means:</p>
<ul>
<li><p>The first three numbers of the IP address (<code>192.168.1</code>) represent the network.</p>
</li>
<li><p>The last number (<code>10</code>) identifies the specific host on that network.</p>
</li>
</ul>
<p>The subnet mask acts like a filter that shows which part of the IP is fixed (network) and which part can vary (host).</p>
<h3 id="heading-cidr-notation-a-modern-alternative">CIDR Notation: A Modern Alternative</h3>
<p>You might also see IP addresses written like this: <code>192.168.1.0/24</code>. This is called <strong>CIDR notation</strong> (Classless Inter-Domain Routing), which we discussed briefly above.</p>
<p>CIDR is a more flexible and compact way to express IP addresses and subnet masks. The <code>/24</code> tells us that the <strong>first 24 bits</strong> of the address are used for the network. The rest are for hosts.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>CIDR Notation</td><td>Subnet Mask</td><td>Number of Hosts</td></tr>
</thead>
<tbody>
<tr>
<td>/24</td><td>255.255.255.0</td><td>256 IPs (254 usable)</td></tr>
<tr>
<td>/26</td><td>255.255.255.192</td><td>64 IPs (62 usable)</td></tr>
<tr>
<td>/30</td><td>255.255.255.252</td><td>4 IPs (2 usable)</td></tr>
</tbody>
</table>
</div><p>CIDR allows networks to be split or combined more precisely than the old Class A/B/C system, which had fixed sizes.</p>
<h3 id="heading-how-to-calculate-a-subnet">How to Calculate a Subnet</h3>
<p>Let’s walk through a basic example.</p>
<p>You’re given the network: <code>192.168.1.0/26</code></p>
<ol>
<li><p>The <code>/26</code> means 26 bits are used for the network and 6 bits remain for hosts (since IPv4 has 32 bits total).</p>
</li>
<li><p>Using the formula <code>2^number_of_host_bits</code>, you get <code>2^6 = 64</code> total addresses.</p>
</li>
<li><p>But 2 addresses are reserved: one for the network itself, and one for the broadcast address.</p>
</li>
<li><p>So, you’re left with 62 usable addresses in that subnet.</p>
</li>
</ol>
<p>This is helpful when dividing a network among departments, buildings, or device types.</p>
<h3 id="heading-public-vs-private-ip-addresses">Public vs Private IP Addresses</h3>
<p>Not all IP addresses are meant for use on the open internet. Some are private, used within internal networks.</p>
<h4 id="heading-private-ip-addresses">Private IP Addresses:</h4>
<ul>
<li><p>Not routed over the internet.</p>
</li>
<li><p>Used in homes, schools, and offices.</p>
</li>
<li><p>Can be reused in different networks without conflict.</p>
</li>
</ul>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Range</td><td>Purpose</td></tr>
</thead>
<tbody>
<tr>
<td>10.0.0.0 – 10.255.255.255</td><td>Private use</td></tr>
<tr>
<td>172.16.0.0 – 172.31.255.255</td><td>Private use</td></tr>
<tr>
<td>192.168.0.0 – 192.168.255.255</td><td>Private use</td></tr>
</tbody>
</table>
</div><p>Devices with private IPs connect to the internet through a router that uses NAT (Network Address Translation).</p>
<h4 id="heading-public-ip-addresses">Public IP Addresses:</h4>
<ul>
<li><p>Assigned by your ISP (Internet Service Provider).</p>
</li>
<li><p>Must be <strong>globally unique</strong>.</p>
</li>
<li><p>Used by websites, servers, and other devices reachable over the internet.</p>
</li>
</ul>
<h3 id="heading-static-vs-dynamic-ip-addresses">Static vs Dynamic IP Addresses</h3>
<p>IP addresses can also be either <strong>static</strong> or <strong>dynamic</strong>.</p>
<ul>
<li><p><strong>Static IP Address</strong>:</p>
<ul>
<li><p>Manually assigned to a device.</p>
</li>
<li><p>Doesn’t change over time.</p>
</li>
<li><p>Commonly used for servers, printers, or devices that need consistent access.</p>
</li>
</ul>
</li>
<li><p><strong>Dynamic IP Address</strong>:</p>
<ul>
<li><p>Assigned automatically using <strong>DHCP (Dynamic Host Configuration Protocol)</strong>.</p>
</li>
<li><p>Changes occasionally.</p>
</li>
<li><p>Most home networks use dynamic IPs for convenience and flexibility.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-why-this-all-matters">Why This All Matters</h3>
<p>Understanding subnetting, masks, and IP types helps you:</p>
<ul>
<li><p>Design networks that scale and perform well.</p>
</li>
<li><p>Assign addresses efficiently.</p>
</li>
<li><p>Improve security through network isolation.</p>
</li>
<li><p>Troubleshoot and configure routers and firewalls effectively.</p>
</li>
</ul>
<p>Subnetting felt confusing at first, but once I saw how it's like breaking down a neighborhood into streets and houses, it clicked. It's a powerful skill for anyone working in networking or IT. And with the rise of IPv6 and cloud-based systems, it's more relevant than ever.</p>
<h2 id="heading-chapter-9-routing-and-switching-directing-data-on-the-network"><strong>Chapter 9: Routing and Switching — Directing Data on the Network</strong></h2>
<p>In this chapter, you will:</p>
<ul>
<li><p>Understand the roles of routers and switches</p>
</li>
<li><p>Learn how data is directed within and across networks</p>
</li>
<li><p>Explore routing tables, packet forwarding, and switching techniques</p>
</li>
<li><p>Compare static vs. dynamic routing</p>
</li>
<li><p>Understand how LAN and WAN switching works</p>
</li>
</ul>
<p>Every time we send an email or watch a video, data is being <strong>routed</strong> and <strong>switched</strong> through a maze of devices. It’s like navigating a city using both small alleyways (switching) and highways (routing).</p>
<p>These processes ensure that data goes from point A to point B efficiently, securely, and correctly, even if they’re continents apart.</p>
<h2 id="heading-what-is-switching">What is Switching?</h2>
<p>Switching happens within local networks (LANs). It’s all about moving data between devices on the same network.</p>
<h3 id="heading-what-is-a-switch">What is a Switch?</h3>
<p>A <strong>switch</strong> is a device used in LANs to connect computers, printers, and other networked devices. It operates at <strong>Layer 2 (Data Link Layer)</strong> of the OSI model and plays a crucial role in directing traffic inside a local network.</p>
<p>But how does a switch know where to send the data?</p>
<p>It uses something called a <strong>MAC address</strong>.</p>
<h4 id="heading-what-are-mac-addresses">What Are MAC Addresses?</h4>
<p>A <strong>MAC (Media Access Control) address</strong> is a unique identifier assigned to a device’s network interface card (NIC). It’s like a digital fingerprint for your laptop, printer, or phone.</p>
<p>Each MAC address is a 48-bit address usually displayed in hexadecimal format like this:<br><code>00:1A:2B:3C:4D:5E</code></p>
<p>When data is sent over a LAN, it’s broken into frames, which include both a <strong>source MAC address</strong> and a <strong>destination MAC address</strong>.</p>
<p>The switch reads the destination MAC address and forwards the frame only to the port where that specific device is connected. This makes switching faster and more secure than old-style hubs that sent data to all devices.</p>
<h4 id="heading-lan-switching-techniques">LAN Switching Techniques</h4>
<p>Switches use different techniques to decide <strong>when and how to forward frames</strong>. These include:</p>
<ul>
<li><p><strong>Store-and-Forward Switching:</strong> The switch receives the entire frame, checks it for errors using a CRC (Cyclic Redundancy Check), and then forwards it. It’s reliable but slightly slower.</p>
</li>
<li><p><strong>Cut-Through Switching:</strong> The switch reads just the destination MAC address – often within the first 6 bytes – and immediately begins forwarding the frame. It’s faster but doesn’t check for errors.</p>
</li>
<li><p><strong>Fragment-Free Switching:</strong> A hybrid approach. It reads the first 64 bytes before forwarding, enough to avoid most collision-related errors.</p>
</li>
</ul>
<h2 id="heading-what-is-routing">What is Routing?</h2>
<p>While switching moves data within a single network, <strong>routing</strong> is what moves data <strong>between networks</strong>. This is how information travels from your home network to the wider internet.</p>
<h3 id="heading-what-is-a-router">What is a Router?</h3>
<p>A <strong>router</strong> is a device that connects different networks and determines the best path for data to travel. It operates at <strong>Layer 3 (Network Layer)</strong> of the OSI model and forwards data based on <strong>IP addresses</strong> rather than MAC addresses.</p>
<p>You can think of a router like a GPS navigator for internet traffic. It chooses the best available route based on traffic, cost, and destination.</p>
<h4 id="heading-what-is-a-routing-table">What is a Routing Table?</h4>
<p>Each router has a <strong>routing table</strong>, which is like a map that tells the router:</p>
<ul>
<li><p>Which destination networks does it know about</p>
</li>
<li><p>The next hop (which router to send the packet to next)</p>
</li>
<li><p>Which interface (port) to send it out on</p>
</li>
<li><p>The metric, which is a number representing the cost or preference of that path</p>
</li>
</ul>
<p>When a router receives a data packet, it checks the routing table to decide where to send it next.</p>
<h3 id="heading-static-vs-dynamic-routing">Static vs. Dynamic Routing</h3>
<p>Routers can learn routes in two main ways: <strong>static</strong> or <strong>dynamic</strong>.</p>
<h4 id="heading-static-routing">Static Routing</h4>
<p>With <strong>static routing</strong>, a network administrator manually enters routes into the router's configuration. This method is:</p>
<ul>
<li><p>Simple and efficient for small, stable networks</p>
</li>
<li><p>Very secure since routes never change unless manually updated</p>
</li>
<li><p>Limited because it doesn’t adapt if a network link goes down</p>
</li>
</ul>
<p>Example: If you tell a router, “To reach network X, always go through Router A,” that route will stay in place until someone changes it.</p>
<h4 id="heading-dynamic-routing">Dynamic Routing</h4>
<p><strong>Dynamic routing</strong> uses protocols that allow routers to automatically share and update routing information with each other. This approach is:</p>
<ul>
<li><p>Ideal for large or complex networks</p>
</li>
<li><p>Adaptive routes are recalculated if something changes or fails</p>
</li>
<li><p>Slightly more resource-intensive due to constant updates</p>
</li>
</ul>
<p>Common dynamic routing protocols include:</p>
<ul>
<li><p><strong>RIP (Routing Information Protocol)</strong> – Simple, but outdated</p>
</li>
<li><p><strong>OSPF (Open Shortest Path First)</strong> – Fast and widely used in large networks</p>
</li>
<li><p><strong>EIGRP (Enhanced Interior Gateway Routing Protocol)</strong> – Cisco’s proprietary protocol, combining the best of both distance vector and link-state methods</p>
</li>
<li><p><strong>BGP (Border Gateway Protocol)</strong> – The protocol that powers routing across the entire internet</p>
</li>
</ul>
<h3 id="heading-routing-in-action">Routing in Action</h3>
<p>Let’s say I’m watching a YouTube video:</p>
<ol>
<li><p>My device sends a request</p>
</li>
<li><p>The switch sends it to the router</p>
</li>
<li><p>The router consults its table and forwards it to another router</p>
</li>
<li><p>This process continues until the request reaches YouTube’s server</p>
</li>
<li><p>The server sends data back, following the same or a different route</p>
</li>
</ol>
<p>Routers and switches never sleep. They’re working behind the scenes, 24/7, making sure our digital lives function smoothly.</p>
<p>Routing and switching may sound technical, but they are the backbone of modern networking. Knowing how they work has helped me troubleshoot issues and understand why certain delays or outages happen.</p>
<p>Switching keeps local communication efficient. Routing connects us to the world.Together, they are the traffic controllers of the internet.</p>
<h2 id="heading-chapter-10-network-infrastructure-devices-security-and-the-modern-internet"><strong>Chapter 10: Network Infrastructure — Devices, Security, and the Modern Internet</strong></h2>
<p>As I continued my journey through networking and data communication, I could see that it's not theory alone – it's hardware, security, and innovation that are essential to the backbone of our everyday life on the internet.</p>
<p>This final chapter brings together the essential knowledge of networks: devices, security protocols, and the technologies behind new connectivity.</p>
<p>In this chapter, you will:</p>
<ul>
<li><p>Understand common networking devices and their functions</p>
</li>
<li><p>Explore firewalls, intrusion detection, and best practices for security</p>
</li>
<li><p>Learn how the internet works (DNS, cloud computing, IoT)</p>
</li>
<li><p>Appreciate the role of protocols, encryption, and data integrity in today's connected world</p>
</li>
</ul>
<h2 id="heading-network-devices-the-building-blocks-of-connectivity"><strong>Network Devices — The Building Blocks of Connectivity</strong></h2>
<p>Every time we send an email, stream a video, or browse the web, a collection of physical devices quietly work behind the scenes to make it all possible. These network devices form the infrastructure of both small local networks and the vast global internet. Let’s take a closer look at some of the key players.</p>
<h3 id="heading-hub">Hub</h3>
<p>The <strong>hub</strong> is one of the earliest and simplest network devices. It operates at the <strong>Physical Layer (Layer 1)</strong> of the OSI model and has a very basic job: when it receives data from one of its ports, it broadcasts that data to all other connected devices.</p>
<p>This method is inefficient, as it creates unnecessary traffic and poses security risks. Because of this, hubs are rarely used in modern networks, having been largely replaced by more intelligent devices like switches.</p>
<h3 id="heading-switch">Switch</h3>
<p>A <strong>switch</strong> is a more advanced and efficient version of a hub. It operates at <strong>Layer 2 (Data Link Layer)</strong> and uses MAC addresses to forward data only to the intended recipient. Instead of flooding the entire network with every transmission, a switch makes sure the data goes only where it's needed. This makes it the go-to device in most <strong>Local Area Networks (LANs)</strong> today.</p>
<h3 id="heading-router">Router</h3>
<p>While switches handle local traffic, <strong>routers</strong> are responsible for sending data between different networks. Operating at <strong>Layer 3 (Network Layer)</strong>, a router uses <strong>IP addresses</strong> to determine the best path for forwarding packets across the internet. In home and business environments, routers are essential for enabling access to the wider world beyond the local network.</p>
<h3 id="heading-access-point-ap">Access Point (AP)</h3>
<p>An <strong>Access Point</strong> bridges the gap between wired and wireless networking. It connects to a wired network and provides <strong>Wi-Fi</strong> so that wireless devices like laptops and smartphones can connect. Access points are especially important in large areas such as offices, schools, or public places where seamless wireless connectivity is needed.</p>
<h3 id="heading-modem">Modem</h3>
<p>A <strong>modem</strong> (short for <em>modulator-demodulator</em>) is the device that connects your local network to your <strong>Internet Service Provider (ISP)</strong>. It converts digital data from your computer into signals that can travel over telephone lines or cable systems, and vice versa. In many homes, the modem is combined with a router in a single device.</p>
<h3 id="heading-network-interface-card-nic">Network Interface Card (NIC)</h3>
<p>A <strong>NIC</strong> is the hardware component inside a device—like a laptop or desktop—that allows it to connect to a network. It can be built-in or external and can support either wired Ethernet or wireless Wi-Fi connections. Without a NIC, a device simply can’t participate in network communication.</p>
<h2 id="heading-network-security-protecting-our-digital-lives">Network Security — Protecting Our Digital Lives</h2>
<p>I never thought much about network security – until I once received a very convincing spam email that nearly tricked me into sharing personal info. It was a wake-up call that our digital spaces aren’t always as safe as they seem.</p>
<p>In today’s connected world, network security is not just an IT concern – it’s a crucial part of everyday life. As we connect more devices and store more personal data online, the risks of cyberattacks and data breaches grow. Here’s a look at the major threats and how we protect against them.</p>
<h3 id="heading-common-threats">Common Threats</h3>
<p>There are many ways attackers can exploit vulnerabilities in a network. Some of the most common threats include:</p>
<ul>
<li><p><strong>Malware</strong>: This includes viruses, worms, and ransomware – malicious software that can damage files, steal information, or lock systems until a ransom is paid.</p>
</li>
<li><p><strong>Phishing</strong>: Attackers send fake emails or create deceptive websites to trick users into revealing sensitive information like passwords or credit card numbers.</p>
</li>
<li><p><strong>DDoS Attacks</strong>: A Distributed Denial of Service attack overwhelms a system with traffic from multiple sources, causing it to slow down or crash entirely.</p>
</li>
</ul>
<h3 id="heading-security-devices-and-techniques">Security Devices and Techniques</h3>
<p>To defend against these threats, networks are equipped with various tools and strategies:</p>
<ul>
<li><p><strong>Firewalls</strong>: These act as gatekeepers between networks, blocking unauthorized access while allowing legitimate communication.</p>
</li>
<li><p><strong>Intrusion Detection Systems (IDS)</strong>: These monitor network traffic for suspicious behavior or known attack patterns.</p>
</li>
<li><p><strong>Antivirus and Endpoint Security</strong>: These tools protect individual devices by scanning for and removing malicious software.</p>
</li>
<li><p><strong>VPNs (Virtual Private Networks)</strong>: VPNs encrypt data transmitted over the internet, shielding users from eavesdropping—especially on public Wi-Fi networks.</p>
</li>
</ul>
<h3 id="heading-best-practices"><strong>Best Practices</strong></h3>
<p>Technology alone isn’t enough – human behavior plays a big role in security. Some key habits include:</p>
<ul>
<li><p>Using strong, unique passwords and changing them regularly</p>
</li>
<li><p>Keeping software and operating systems up to date, since patches often fix security holes</p>
</li>
<li><p>Enabling multi-factor authentication (MFA) to add an extra layer of protection</p>
</li>
<li><p>Educating users to recognize suspicious emails and links</p>
</li>
</ul>
<p>Together, these tools and habits form a multi-layered defense that helps safeguard personal and organizational data.</p>
<h2 id="heading-the-modern-internet-dns-cloud-and-iot"><strong>The Modern Internet — DNS, Cloud, and IoT</strong></h2>
<p>Today’s internet is about far more than just connecting computers. It’s a complex, evolving ecosystem of services and smart devices, all working together to deliver seamless digital experiences. Let’s explore three key pillars of the modern internet: <strong>DNS</strong>, <strong>Cloud Computing</strong>, and the <strong>Internet of Things (IoT)</strong>.</p>
<h3 id="heading-domain-name-system-dns">Domain Name System (DNS)</h3>
<p>Imagine trying to access websites using IP addresses like <code>142.250.190.206</code> instead of just typing <a target="_blank" href="http://google.com"><code>google.com</code></a>. It would be nearly impossible to remember. That’s where the <strong>Domain Name System (DNS)</strong> comes in.</p>
<p>DNS works like the internet’s phonebook: it translates easy-to-remember domain names (like google.com) into the numerical IP addresses that computers use to communicate. Without DNS, web browsing as we know it wouldn’t exist.</p>
<h3 id="heading-cloud-computing">Cloud Computing</h3>
<p>The <strong>cloud</strong> has transformed how we store, process, and access information. Rather than relying on local hardware, cloud computing delivers services—like file storage, applications, or processing power—via the internet. Platforms like Google Drive, Amazon Web Services (AWS), and Microsoft Azure make it easy to scale up resources as needed, work from anywhere, and reduce infrastructure costs.</p>
<p>The benefits are clear: scalability, flexibility, and cost efficiency. But it also brings new challenges in terms of data privacy, security, and compliance.</p>
<h3 id="heading-internet-of-things-iot">Internet of Things (IoT)</h3>
<p>The <strong>Internet of Things</strong> refers to everyday objects – like light bulbs, refrigerators, security cameras – that are connected to the internet and can communicate with each other. These devices offer convenience and automation, like turning off lights remotely or monitoring your home while away.</p>
<p>But the explosion of connected devices introduces challenges:</p>
<ul>
<li><p><strong>Security</strong>: Many IoT devices are poorly secured, making them easy targets for hackers.</p>
</li>
<li><p><strong>Interoperability</strong>: With so many manufacturers and standards, getting devices to work together can be difficult.</p>
</li>
<li><p><strong>Privacy</strong>: IoT devices often collect sensitive personal data, raising concerns about how that information is used.</p>
</li>
</ul>
<h2 id="heading-encryption-and-secure-protocols"><strong>Encryption and Secure Protocols</strong></h2>
<p>As data travels through this vast digital landscape, it must be protected from prying eyes. That’s where <strong>encryption</strong> and <strong>secure protocols</strong> come into play. These tools ensure that even if data is intercepted, it remains unreadable without the correct key.</p>
<p>Some of the most widely used secure protocols include:</p>
<ul>
<li><p><strong>HTTPS (Hypertext Transfer Protocol Secure)</strong>: Ensures encrypted communication between your browser and websites.</p>
</li>
<li><p><strong>SSL/TLS (Secure Sockets Layer / Transport Layer Security)</strong>: Used behind HTTPS to secure web data.</p>
</li>
<li><p><strong>IPSec</strong>: Encrypts IP packets and is commonly used in VPNs to secure network-level communication.</p>
</li>
<li><p><strong>SSH (Secure Shell)</strong>: Provides secure remote access to systems and devices.</p>
</li>
</ul>
<p>These technologies form the backbone of secure internet communication, protecting users from data leaks, identity theft, and other forms of digital attack.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Looking back, it's amazing how far we've come – from learning what a bit is, to understanding how huge global networks function securely and efficiently.</p>
<p>Networking is more than routers and wires – it's a finely crafted system of trust, logic, and global cooperation. It's the very reason that we're able to learn, work, connect, and create anywhere.</p>
<p>And having established this foundation, I feel ready to go further.</p>
<p>Thank you for joining me on this journey.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create Database Documentation Using dbdocs with DBML ]]>
                </title>
                <description>
                    <![CDATA[ Database documentation plays a crucial role in maintaining and scaling systems. Clear and well-organized documentation can significantly improve communication between team members and enhance project longevity. One of the most efficient ways to docum... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/create-database-documentation-using-dbdocs-with-dbml/</link>
                <guid isPermaLink="false">670d3f2e7e2c70da5a203bba</guid>
                
                    <category>
                        <![CDATA[ Databases ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Devops ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ci-cd ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Truong-Phat Nguyen ]]>
                </dc:creator>
                <pubDate>Mon, 14 Oct 2024 15:56:30 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1728620241328/79515009-0fa3-4fcd-a4ce-e1ec2d5609f8.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Database documentation plays a crucial role in maintaining and scaling systems. Clear and well-organized documentation can significantly improve communication between team members and enhance project longevity.</p>
<p>One of the most efficient ways to document a database is through <a target="_blank" href="https://dbdocs.io/"><strong>dbdocs</strong></a> and <a target="_blank" href="https://dbml.dbdiagram.io/home"><strong>DBML</strong></a> - an open sourced Database Markup Language.</p>
<p>In this guide, I’ll show you how to create database documentation using these tools, step by step.</p>
<h1 id="heading-what-is-dbdocs"><strong>What is dbdocs?</strong></h1>
<p><a target="_blank" href="https://dbdocs.io/"><strong>dbdocs</strong></a> is a platform that generates database documentation from your schema, easily shareable via a link. Using <a target="_blank" href="https://dbml.dbdiagram.io/home"><strong>DBML</strong></a> <strong>(Database Markup Language)</strong>, you can create clear, shareable, and updatable documentation of your database structure.</p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>Before we begin, ensure you have the following:</p>
<ul>
<li><p>Basic knowledge of databases and SQL.</p>
</li>
<li><p>A database schema to document (we’ll use a PostgreSQL example in this guide).</p>
</li>
</ul>
<h2 id="heading-step-1-install-dbml-cli-and-dbdocs"><strong>Step 1: Install DBML CLI and dbdocs</strong></h2>
<p>Start by installing the <strong>DBML CLI</strong>, which helps convert your database schema into a DBML format. You also need the <strong>dbdocs CLI</strong> to generate and publish your documentation.</p>
<pre><code class="lang-bash">npm install -g dbdocs
</code></pre>
<h2 id="heading-step-2-export-your-database-schema-to-dbml"><strong>Step 2: Export Your Database Schema to DBML</strong></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728615902517/20974a9d-729e-4b3a-997c-0b89e944a6cd.png" alt="DB diagram" class="image--center mx-auto" width="1818" height="514" loading="lazy"></p>
<p>If you’re working with an existing database, you can export the schema into DBML using the DBML CLI tool.</p>
<p>For PostgreSQL, run the following command:</p>
<pre><code class="lang-bash">$ dbdocs db2dbml postgres &lt;connection-string&gt; -o database.dbml

✔ Connecting to database &lt;db-name&gt;... <span class="hljs-keyword">done</span>.
✔ Generating DBML... <span class="hljs-keyword">done</span>.
✔ Wrote to database.dbml
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728615885904/9f68f18b-fa14-4e88-b58b-bd90d292ef31.gif" alt="Extract DBML code from database connection" class="image--center mx-auto" width="700" height="400" loading="lazy"></p>
<p>This command will export your database schema and save it into a file called <code>database.dbml</code>.</p>
<p>Here’s an example of how a generated DBML file might look:</p>
<pre><code class="lang-bash">Table users {
  id int [pk, increment]
  username varchar(50) [not null]
  email varchar(100) [not null, unique]
  created_at timestamp [not null]
}

Table orders {
  id int [pk, increment]
  user_id int [not null, ref: &gt; users.id]
  total decimal [not null]
  created_at timestamp [not null]
}
</code></pre>
<p><strong>In this example:</strong></p>
<p>• The users and orders tables are defined.</p>
<p>• Fields are annotated with types and constraints.</p>
<p>• The relationship between <code>orders.user_id</code> and <code>users.id</code> is established using <code>ref</code>.</p>
<h2 id="heading-step-3-edit-and-add-notes-to-the-dbml-file"><strong>Step 3: Edit and Add Notes to the DBML File</strong></h2>
<p>You may want to clean it up or add extra documentation like table descriptions and field descriptions to communicate with other members in the team.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728615980279/8e1851a8-2e38-4ded-8b6a-c873d6b395b8.gif" alt="Add notes to generated DBML Code" class="image--center mx-auto" width="800" height="501" loading="lazy"></p>
<h2 id="heading-step-4-generate-documentation-with-dbdocs"><strong>Step 4: Generate Documentation with dbdocs</strong></h2>
<p>Once your DBML file is ready, the next step is to generate the documentation using dbdocs. First, you need to login to dbdocs:</p>
<pre><code class="lang-bash">dbdocs login
</code></pre>
<p>After logging in, publish the DBML file:</p>
<pre><code class="lang-bash">dbdocs build database.dbml
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728616039961/0ef67db3-8a86-495a-b42f-3fad0fead933.gif" alt="Generate database documentation from DBML file" class="image--center mx-auto" width="800" height="499" loading="lazy"></p>
<p>This command will generate a shareable documentation link that you can access via the dbdocs platform. You can also set access permissions and collaborate with your team.</p>
<p>This seamless workflow ensures that your documentation always reflects the latest state of your database.</p>
<h1 id="heading-benefits-of-using-dbdocs-with-dbml"><strong>Benefits of Using dbdocs with DBML</strong></h1>
<ul>
<li><p><strong>Simplicity</strong>: The <a target="_blank" href="https://dbml.dbdiagram.io/home">DBML</a> syntax is simple and easy to learn, making it a perfect fit for teams.</p>
</li>
<li><p><strong>Automation</strong>: You can <a target="_blank" href="https://docs.dbdocs.io/features/generate-dbml-from-db">automate your database documentation updates</a> as part of your <a target="_blank" href="https://docs.dbdocs.io/features/ci-integration">CI/CD pipeline</a>.</p>
</li>
<li><p><strong>Collaboration</strong>: Easily <a target="_blank" href="https://docs.dbdocs.io/features/project-access-control">share documentation links</a> with your team or stakeholders for easy access and discussion.</p>
</li>
<li><p><strong>Version Control:</strong> Use <a target="_blank" href="https://docs.dbdocs.io/features/schema-changelog">schema changelog</a> to track database schema changes over time.</p>
</li>
<li><p><strong>Visualization</strong>: dbdocs provides a clean interface to visualize your database schema, relationships, and annotations. <a target="_blank" href="https://dbdocs.io/Holistics/Ecommerce">Try this demo</a> to learn more.</p>
</li>
</ul>
<h1 id="heading-conclusion"><strong>Conclusion</strong></h1>
<p>In this tutorial, we explored how to export a database schema, customize it, and generate shareable documentation using dbdocs.</p>
<p>By incorporating this workflow into your development process, you’ll improve your team’s collaboration, enhance your project’s scalability, and ensure that everyone stays on the same page. Happy documenting!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How Do Numerical Conversions Work in Computer Systems? Explained With Examples ]]>
                </title>
                <description>
                    <![CDATA[ Computers perform complex calculations when carrying out their assigned tasks. At the very core, the calculations boil down to operations like comparisons, assignments, and addition. Have you ever wondered how they are performed under the hood and wh... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-do-numerical-conversions-work/</link>
                <guid isPermaLink="false">66578856935992fb202d9272</guid>
                
                    <category>
                        <![CDATA[ Computers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ MathJax ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Zaira Hira ]]>
                </dc:creator>
                <pubDate>Wed, 29 May 2024 19:56:06 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1715271341530/60608a00-2e63-434e-91e8-c766b171f6f7.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Computers perform complex calculations when carrying out their assigned tasks. At the very core, the calculations boil down to operations like comparisons, assignments, and addition.</p>
<p>Have you ever wondered how they are performed under the hood and why they are important? At a fundamental level, a computer works by performing various numerical conversions.</p>
<p>In this article, you'll learn the following concepts:</p>
<ul>
<li><p>The importance of numerical systems in computers.</p>
</li>
<li><p>Types of numerical systems.</p>
</li>
<li><p>Numerical conversion techniques.</p>
</li>
<li><p>Application of different numerical systems.</p>
</li>
<li><p>Mini exercises to keep you engaged along the way.</p>
</li>
</ul>
<h2 id="heading-types-of-numerical-systems">Types of Numerical Systems</h2>
<p>Numerical conversion is the process of converting numbers from one numeral system to another. In computer systems, the common numeral systems include decimal (base-10), binary (base-2), hexadecimal (base-16), and octal (base-8).</p>
<h3 id="heading-but-what-is-a-base">But What Is a Base?</h3>
<p>In mathematics and computer science, the term "base" refers to the number of unique digits or symbols used in a positional numeral system. Each digit's value is multiplied by the base raised to the power of its position in the number, starting from the rightmost digit, which represents the units place.</p>
<p>Here's an explanation of the commonly encountered numeral systems:</p>
<ol>
<li><p><strong>Base-2 (Binary)</strong>:</p>
<ul>
<li><p>Base-2, or binary, uses only two symbols: 0 and 1.</p>
</li>
<li><p>Each digit's value is a power of 2, with positions increasing from right to left.</p>
</li>
</ul>
</li>
<li><p><strong>Base-10 (Decimal)</strong>:</p>
<ul>
<li><p>Base-10, or decimal uses ten symbols from 0 to 9.</p>
</li>
<li><p>Each digit's value is a power of 10, with positions increasing from right to left.</p>
</li>
</ul>
</li>
<li><p><strong>Base-8 (Octal)</strong>:</p>
<ul>
<li><p>Base-8, or octal, uses eight symbols: 0 to 7.</p>
</li>
<li><p>Each digit's value is a power of 8, with positions increasing from right to left.</p>
</li>
</ul>
</li>
<li><p><strong>Base-16 (Hexadecimal)</strong>:</p>
<ul>
<li><p>Base-16, or hexadecimal, uses sixteen symbols: 0 to 9 and A to F (representing 10 to 15).</p>
</li>
<li><p>Each digit's value is a power of 16, with positions increasing from right to left.</p>
</li>
<li><p>Below is a table showing the mapping of hexadecimal numbers from 10 with alphabets.</p>
</li>
</ul>
</li>
</ol>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Character</td><td>Hexadecimal</td></tr>
</thead>
<tbody>
<tr>
<td>A</td><td>10</td></tr>
<tr>
<td>B</td><td>11</td></tr>
<tr>
<td>C</td><td>12</td></tr>
<tr>
<td>D</td><td>13</td></tr>
<tr>
<td>E</td><td>14</td></tr>
<tr>
<td>F</td><td>15</td></tr>
</tbody>
</table>
</div><p>This notation is commonly used to simplify the representation of binary-coded values.</p>
<h2 id="heading-importance-of-understanding-numerical-systems-in-computers">Importance of Understanding Numerical Systems in Computers</h2>
<p>Learning numeral conversions in computer science is essential for several reasons:</p>
<ol>
<li><p><strong>Understanding Data Representation</strong>: Computers store and manipulate data using binary (base-2) representation. Knowing how to convert between numeral systems helps in understanding how data is stored and processed at the fundamental level.</p>
</li>
<li><p><strong>Addressing Memory</strong>: Memory addresses in computers are frequently represented in hexadecimal format. Knowing how to convert between decimal and hexadecimal is crucial for understanding memory management and for debugging.</p>
</li>
<li><p><strong>Networking and Communication</strong>: In networking, IP addresses and MAC addresses are often represented in hexadecimal format. Understanding hexadecimal conversion is thus comes in handy for networking professionals.</p>
</li>
<li><p><strong>Cryptography</strong>: In cryptography, hexadecimal numbers are frequently used to represent keys, cipher texts, and other cryptographic data. Understanding numeral conversions helps in understanding cryptographic operations.</p>
</li>
</ol>
<h2 id="heading-conversion-techniques">Conversion Techniques</h2>
<p>In this section, you'll learn techniques to convert one number system to another.</p>
<h3 id="heading-decimal-to-binary">Decimal to Binary</h3>
<p><strong>Step-by-Step Conversion Process:</strong></p>
<ol>
<li><p><strong>Divide the number by 2:</strong> The first step is to divide the number by 2 and record the remainder.</p>
</li>
<li><p><strong>Divide the quotient by 2 repetitively:</strong> Divide the quotient from step 1 and record the remainder. Continue to divide and record the remainder till 1 remains as the quotient.</p>
</li>
<li><p><strong>Find the solution in reverse order:</strong> Starting from the last quotient that would be <code>1</code>, go upwards to get the final answer.</p>
</li>
</ol>
<p><strong>Example Conversion:</strong></p>
<p>Let's say you want the binary equivalent of <code>17</code>, then the process would be like this:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Operation</td><td>Result</td><td>Remainder</td></tr>
</thead>
<tbody>
<tr>
<td>17/2</td><td>8</td><td>1 ⬆️</td></tr>
<tr>
<td>8/2</td><td>4</td><td>0 ⬆️</td></tr>
<tr>
<td>4/2</td><td>2</td><td>0 ⬆️</td></tr>
<tr>
<td>2/2</td><td>1 ➡️</td><td>0 ⬆️</td></tr>
</tbody>
</table>
</div><p>To find the final answer, follow the arrows. Start from the bottom where the result is <code>1</code> and go upwards. You'll get <code>10001</code>.</p>
<p>So,</p>
<p>$$17_{10} = 10001_{2}$$</p><p>Let's try a bigger number <code>55</code></p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Operation</td><td>Result</td><td>Remainder</td></tr>
</thead>
<tbody>
<tr>
<td>55/2</td><td>27</td><td>1 ⬆️</td></tr>
<tr>
<td>27/2</td><td>13</td><td>1 ⬆️</td></tr>
<tr>
<td>13/2</td><td>6</td><td>1 ⬆️</td></tr>
<tr>
<td>6/2</td><td>3</td><td>0 ⬆️</td></tr>
<tr>
<td>3/2</td><td>1 ➡️</td><td>1 ⬆️</td></tr>
</tbody>
</table>
</div><p>So,</p>
<p>$$55_{10} = 110111_{2}$$</p><h4 id="heading-now-your-turn">Now, your turn:</h4>
<p>What is <code>67</code> in binary?</p>
<details><summary>Show Answer</summary><div data-type="detailsContent"><code>67</code> in binary is <code>1000011</code>.</div></details>

<h3 id="heading-binary-to-decimal">Binary to Decimal</h3>
<p><strong>Step-by-Step Conversion Process:</strong></p>
<ol>
<li><p><strong>Write down the binary number</strong>: Separate each bit for clarity.</p>
</li>
<li><p><strong>Map each bit with its corresponding power of 2</strong>: Start from <code>2^0</code> on the right and increase the exponent by <code>1</code> as you move left.</p>
</li>
<li><p><strong>Multiply each bit by its corresponding power of 2</strong>: If the bit is 1, multiply it by the power of 2 for that position. If the bit is 0, the result is 0 for that position.</p>
</li>
<li><p><strong>Sum all the products</strong>: Add all the results from step 3 to get the decimal equivalent.</p>
</li>
</ol>
<p><strong>Example Conversion:</strong></p>
<p>For <code>101</code>, the conversion would be like this:</p>
<p>$$\begin{align} &amp;1\times2^2 + 0\times2^1 + 1\times2^0 \newline &amp;= 4 + 0 + 1 \newline &amp;= 5 \end{align}$$</p><p>So,</p>
<p>$$101_{2} = 5_{10}$$</p><p>Let's convert <code>1011001</code> to decimal:</p>
<p>$$\begin{align} &amp;1\times2^6+0\times2^5+1\times2^4+1\times2^3+0\times2^2+0\times2^1+1\times2^0\newline &amp;= 64+0+16+8+0+0+1 \newline &amp;= 89 \end{align}$$</p><p>So,</p>
<p>$$1011001_{2} = 89_{10}$$</p><h3 id="heading-binary-to-hexadecimal">Binary to Hexadecimal</h3>
<p><strong>Step-by-Step Conversion Process:</strong></p>
<ol>
<li><p><strong>Make pairs of 4:</strong> Segregate the given binary number into 4 bits each, starting from the rightmost bit.</p>
</li>
<li><p><strong>Pad in 0 to the left-most pair if the bits do not count to 4:</strong> If the leftmost part doesn't make 4 bits, add zeros to the left of it to complete the count.</p>
</li>
<li><p><strong>Find equivalent decimal number as explained previously:</strong> Use binary to decimal conversion.</p>
</li>
</ol>
<p><strong>Example Conversion:</strong></p>
<p>Let's convert <code>10010010</code> to hexadecimal.</p>
<ol>
<li><p>Split the bits into sections of 4 bits each, starting from the rightmost bit:</p>
<ul>
<li><p><code>10010010</code> = [<code>1001][0010]</code></p>
</li>
<li><p>Padding was not needed here as each section is 4 bits long.</p>
</li>
</ul>
</li>
<li><p>Convert binary to decimal:</p>
</li>
</ol>
<p>$$\begin{align} &amp;[1001][0010]\newline &amp;=[1\times2^3 + 0\times2^2 + 0\times2^1 + 1\times2^0] [0\times2^3 + 0\times2^2 + 1\times2^1 + 1\times2^0] \newline &amp;=[8+0+0+1][0+0+1+1] = [9][2] \end{align}$$</p><p>So,</p>
<p>$$10010010_{2} = 92_{16}$$</p><p>Let's run another example. But first,</p>
<p>Recall that, the numbers 10 - 15 are represented as follows in hexadecimal:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Character</td><td>Hexadecimal</td></tr>
</thead>
<tbody>
<tr>
<td>A</td><td>10</td></tr>
<tr>
<td>B</td><td>11</td></tr>
<tr>
<td>C</td><td>12</td></tr>
<tr>
<td>D</td><td>13</td></tr>
<tr>
<td>E</td><td>14</td></tr>
<tr>
<td>F</td><td>15</td></tr>
</tbody>
</table>
</div><p>Let's convert <code>11010011011</code> to hexadecimal.</p>
<ol>
<li><p>Divide the bits into groups of 4, starting from the right.</p>
<ul>
<li>[110][1001][1011]</li>
</ul>
</li>
<li><p>Add padding of <code>0</code> to the leftmost section.</p>
<ul>
<li>[0110][1001][1011]</li>
</ul>
</li>
<li><p>Convert the bits to decimal using the binary-to-decimal method.</p>
</li>
</ol>
<p>$$\begin{align} &amp;[0110][1001][1011]\newline &amp;=[0\times2^3+1\times2^2+1\times2^1+0\times2^0]\ [1\times2^3+0\times2^2+0\times2^1+1\times2^0]\ [1\times2^3+0\times2^2+1\times2^1+1\times2^0]\newline &amp;=[6][9][11]\newline &amp;=[6][9][B] \end{align}$$</p><ol start="4">
<li><p>As <code>11</code> maps to <code>B</code> in hexadecimal, replace <code>11</code> with <code>B</code> .</p>
<p> $$[6][9][11] =[6][9][B]$$</p>
</li>
</ol>
<p>So,</p>
<p>$$11010011011_{2} = 69B_{16}$$</p><h3 id="heading-hexadecimal-to-binary">Hexadecimal to Binary</h3>
<p><strong>Step-by-Step Conversion Process:</strong></p>
<p><strong>Example Conversion:</strong></p>
<ol>
<li><p><strong>Identify Each Hexadecimal Digit</strong>: Break down the hexadecimal number into individual digits.</p>
</li>
<li><p><strong>Convert Each Hexadecimal Digit to Binary</strong>: Each hexadecimal digit corresponds to a unique four-bit binary sequence.</p>
</li>
</ol>
<h3 id="heading-example-conversion"><strong>Example Conversion:</strong></h3>
<p>Let's convert the hexadecimal number <code>2F3</code> to binary.</p>
<ol>
<li><p><strong>Identify Each Hexadecimal Digit</strong>:</p>
<ul>
<li><p><code>2</code></p>
</li>
<li><p><code>F</code></p>
</li>
<li><p><code>3</code></p>
</li>
</ul>
</li>
<li><p><strong>Convert Each Hexadecimal Digit to Binary</strong>:</p>
<ul>
<li><p><code>2</code> in binary: <code>0010</code></p>
</li>
<li><p><code>F</code> is <code>15</code> in decimal and in binary: <code>1111</code></p>
</li>
<li><p><code>3</code> in binary: <code>0011</code></p>
</li>
</ul>
</li>
<li><p><strong>Combine the Binary Sequences</strong>:</p>
<ul>
<li><code>2F3</code> in binary: <code>0010 1111 0011</code></li>
</ul>
</li>
</ol>
<p>So, the hexadecimal number <code>2F3</code> converts to <code>001011110011</code> in binary.</p>
<h3 id="heading-octal-to-binary">Octal to Binary</h3>
<p><strong>Step-by-Step Conversion Process:</strong></p>
<p><strong>Example Conversion:</strong></p>
<p>To convert an octal number to binary, each octal digit (0-7) is converted to a three-bit binary number because the largest octal digit (7) can be represented using three bits (111).</p>
<h3 id="heading-step-by-step-conversion-process"><strong>Step-by-Step Conversion Process:</strong></h3>
<ol>
<li><p><strong>Identify Each Octal Digit</strong>: Break down the octal number into individual digits.</p>
</li>
<li><p><strong>Convert Each Octal Digit to Binary</strong>: Use the same decimal-to-binary conversion method.</p>
</li>
<li><p><strong>Combine the Binary Sequences</strong>: Each sequence should be 3 bits, pad zeros to the left if needed. Concatenate the three-bit binary sequences to form the final binary number.</p>
</li>
</ol>
<h3 id="heading-example-conversion-1"><strong>Example Conversion:</strong></h3>
<p>Let's convert the octal number <code>157</code> to binary.</p>
<ol>
<li><p><strong>Identify Each Octal Digit</strong>:</p>
<ul>
<li><p><code>1</code></p>
</li>
<li><p><code>5</code></p>
</li>
<li><p><code>7</code></p>
</li>
</ul>
</li>
<li><p><strong>Convert Each Octal Digit to Binary</strong>:</p>
<ul>
<li><p><code>1</code> in binary: <code>001</code></p>
</li>
<li><p><code>5</code> in binary: <code>101</code></p>
</li>
<li><p><code>7</code> in binary: <code>111</code></p>
</li>
</ul>
</li>
<li><p><strong>Combine the Binary Sequences</strong>:</p>
<ul>
<li><code>157</code> in binary: <code>001 101 111</code></li>
</ul>
</li>
</ol>
<p>So, the octal number <code>157</code> converts to <code>001101111</code> in binary.</p>
<h3 id="heading-binary-to-octal">Binary to Octal</h3>
<p>To convert a binary number to an octal, group the binary digits into sets of three, starting from the right to the left. You can pad that group with leading zeros if the left-most group isn't 3 digits.</p>
<h3 id="heading-step-by-step-conversion-process-1"><strong>Step-by-Step Conversion Process:</strong></h3>
<ol>
<li><p><strong>Pad the Binary Number with Leading Zeros</strong> (if necessary) to make the number of digits in groups of three:</p>
<ul>
<li><p>Binary: <code>11010011</code></p>
</li>
<li><p>Padded Binary: <code>011 010 011</code></p>
</li>
</ul>
</li>
<li><p><strong>Group the Binary Digits into Sets of Three</strong>:</p>
<ul>
<li>Groups: <code>011 010 011</code></li>
</ul>
</li>
<li><p><strong>Convert Each Group of Three Binary Digits to Its Octal Equivalent</strong>:</p>
<ul>
<li>Use the same method as binary to decimal.</li>
</ul>
</li>
<li><p><strong>Combine the Octal Digits</strong>: Form the final octal number by combining the octal digits.</p>
</li>
</ol>
<h3 id="heading-example-conversion-2"><strong>Example Conversion:</strong></h3>
<p>Let's convert the binary number <code>11010011</code> to octal.</p>
<ol>
<li><p><strong>Pad the Binary Number with Leading Zeros</strong> (if necessary):</p>
<ul>
<li><p>Binary: <code>11010011</code></p>
</li>
<li><p>Padded Binary: <code>011 010 011</code></p>
</li>
</ul>
</li>
<li><p><strong>Group the Binary Digits into Sets of Three</strong>:</p>
<ul>
<li>Groups: <code>011 010 011</code></li>
</ul>
</li>
<li><p><strong>Convert Each Group of Three Binary Digits to Its Octal Equivalent</strong>:</p>
<ul>
<li><p><code>011</code> (binary) = <code>3</code> (octal)</p>
</li>
<li><p><code>010</code> (binary) = <code>2</code> (octal)</p>
</li>
<li><p><code>011</code> (binary) = <code>3</code> (octal)</p>
</li>
</ul>
</li>
<li><p><strong>Combine the Octal Digits</strong>:</p>
<ul>
<li><code>11010011</code> in octal: <code>323</code></li>
</ul>
</li>
</ol>
<p>So, the binary number <code>11010011</code> converts to <code>323</code> in octal.</p>
<h2 id="heading-applications-of-numerical-conversions">Applications of Numerical Conversions</h2>
<p>In this section, you'll learn about two common applications of numerical conversions.</p>
<h3 id="heading-file-permissions">File permissions</h3>
<p>Octal notation is commonly used in file permission management in Unix-like operating systems. In Unix systems, each file has associated permissions that determine who can read, write, or execute the file. These permissions are represented by a 3-digit octal number, where each digit corresponds to a specific set of permissions: <code>owner</code>, <code>group</code>, and <code>others</code>.</p>
<p>Each digit in the octal representation is composed of three bits, with each bit representing a specific permission:</p>
<ul>
<li><p>The first digit represents permissions for the file owner.</p>
</li>
<li><p>The second digit represents permissions for the group associated with the file.</p>
</li>
<li><p>The third digit represents permissions for others (users not in the owner group).</p>
</li>
</ul>
<p>The mapping of permissions to bits is as follows:</p>
<ul>
<li><p>Read permission corresponds to the value <code>4.</code></p>
</li>
<li><p>Write permission corresponds to the value <code>2</code>.</p>
</li>
<li><p>Execute permission corresponds to the value <code>1</code>.</p>
</li>
</ul>
<p>To calculate the octal representation of permissions, you sum the values of the granted permissions. For example:</p>
<ul>
<li>If a file has read and write permissions for the owner, read-only permissions for the group, and no permissions for others, the octal representation would be <code>640</code>.</li>
</ul>
<p>Here's the breakdown:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Permission</td><td>Owner</td><td>Group</td><td>Others</td></tr>
</thead>
<tbody>
<tr>
<td>Read = 4</td><td>Yes</td><td>Yes</td><td>No</td></tr>
<tr>
<td>Write = 2</td><td>Yes</td><td>No</td><td>No</td></tr>
<tr>
<td>Execute = 1</td><td>No</td><td>No</td><td>No</td></tr>
<tr>
<td></td><td>4 +2 + 0 = 6</td><td>4 +0 + 0 = 4</td><td>0</td></tr>
</tbody>
</table>
</div><ul>
<li><p>The owner has read (4) + write (2) permissions, resulting in 6.</p>
</li>
<li><p>The group has read (4) permissions only.</p>
</li>
<li><p>Others have no permissions, which corresponds to 0.</p>
</li>
</ul>
<p>So, the permissions for the file in octal representation are <code>640</code>.</p>
<p><strong>Quiz:</strong></p>
<details><summary>What does the permission 777 show?</summary><div data-type="detailsContent">Read, write and execute for all- users, groups and others.</div></details>

<p>This octal representation of permissions provides a concise and efficient way to manage file permissions in Unix systems, allowing for easy understanding and manipulation of access rights.</p>
<p>To learn more about file permissions, you can read my other article <a target="_blank" href="https://www.freecodecamp.org/news/linux-chmod-chown-change-file-permissions/">here</a>.</p>
<h3 id="heading-color-codes">Color codes</h3>
<p>You might have noticed that the notation <code>#ffffff</code>, <code>#c3c400</code> are prevalent in various digital contexts, such as web design, graphics editing software, and programming. As you might have guessed, this is a hexadecimal representation. As an example, see this palette from <a target="_blank" href="https://colorhunt.co/palette/ffff80ffaa80ff5580ff0080">Colorhunt</a>:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1715250432475/ccab919f-3796-441a-89e7-60fc3a85e01c.png" alt="ccab919f-3796-441a-89e7-60fc3a85e01c" class="image--center mx-auto" width="634" height="205" loading="lazy"></p>
<p>Here we have a hexadecimal value of the color followed by the equivalent RGB value.</p>
<p>Hexadecimal color codes represent colors in the RGB model using pairs of hexadecimal digits for each color component (red, green, and blue). Each pair corresponds to an 8-bit value, ranging from <code>00</code> to <code>FF</code>, where <code>00</code> represents the lowest intensity(black) and <code>FF</code> represents the highest intensity(white).</p>
<p>For instance, <code>#FF0000</code> stands for red, <code>#00FF00</code> stands for green, and <code>#0000FF</code> stands for blue.</p>
<p><strong>QUIZ:</strong></p>
<details><summary>If red and green makes yellow in RGB model, what would be the hex equivalent?</summary><div data-type="detailsContent">#ffff00</div></details>

<h2 id="heading-conclusion">Conclusion</h2>
<p>By the end of this article, you should be comfortable with carrying out most of the common conversions. In this article, you:</p>
<ul>
<li><p>Explored the importance of numerical conversions in computers.</p>
</li>
<li><p>Explored numeral systems like binary, decimal, hexadecimal, and octal.</p>
</li>
<li><p>Learned conversion techniques between these systems.</p>
</li>
<li><p>Understood some practical applications of numeral systems in computing.</p>
</li>
</ul>
<h2 id="heading-next-steps">Next steps</h2>
<p>You can code a decimal to binary converter in JavaScript by following <a target="_blank" href="https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures-v8/learn-recursion-by-building-a-decimal-to-binary-converter/step-1">this</a> step-by-step guide.</p>
<p>I hope you found this article helpful. I would love to connect with you on any of these <a target="_blank" href="https://zaira_.bio.link/">platforms</a>.</p>
<p>See you in the next tutorial, happy coding 😁</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Asynchronous vs Batch Data Processing in Distributed Systems – Explained with Examples ]]>
                </title>
                <description>
                    <![CDATA[ Distributed Systems often process and store huge amounts of data. Processing this data efficiently is typically an ongoing endeavor, and how it is designed almost always affects the end-user experience of a product. Two popular modes of processing da... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/asynchronous-vs-batch-processing-in-distributed-systems/</link>
                <guid isPermaLink="false">66d0335915ea3036a9539915</guid>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ distributed systems ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Anant Chowdhary ]]>
                </dc:creator>
                <pubDate>Wed, 20 Mar 2024 15:13:11 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/07/pexels-sydney-troxell-223521-718759.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Distributed Systems often process and store huge amounts of data. Processing this data efficiently is typically an ongoing endeavor, and how it is designed almost always affects the end-user experience of a product.</p>
<p>Two popular modes of processing data are Batch Processing and Asynchronous Processing. We'll learn more about both in this article, along with when to use each approach. </p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-batch-processing-of-data">Batch Processing of Data</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-batch-processing">What is Batch Processing</a>?</p>
</li>
<li><a class="post-section-overview" href="#when-do-we-use-batch-procesing">When Do We Use Batch Processing</a>?</li>
<li><a class="post-section-overview" href="#heading-real-world-example-of-batch-processing-of-data">Real World Example of Batch Processing of Data</a></li>
<li><p><a class="post-section-overview" href="#heading-what-does-batch-processing-look-like-in-code">What Does Batch Processing Look Like in Code</a>?</p>
</li>
<li><p><a class="post-section-overview" href="#heading-asynchronous-processing-of-data">Asynchronous Processing of Data</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-asynchronous-processing">What is Asynchronous Processing</a>?</p>
</li>
<li><a class="post-section-overview" href="#when-do-we-use-asynchronous-procesing">When Do We Use Asynchronous Processing</a></li>
<li><a class="post-section-overview" href="#heading-real-world-example-of-asynchronous-processing-of-data">Real World Example of Asynchronous Processing of Data</a></li>
<li><p><a class="post-section-overview" href="#heading-what-does-async-processing-look-like-in-code">What Does Async Processing Look Like in Code</a>?</p>
</li>
<li><p><a class="post-section-overview" href="#heading-summary">Summary</a></p>
</li>
</ol>
<h2 id="heading-batch-processing-of-data">Batch Processing of Data</h2>
<h3 id="heading-what-is-batch-processing">What is Batch Processing?</h3>
<p>Batch Processing, as you may have guessed, waits for a certain amount of data to be accumulated, and then processes this <em>batch</em> of data in one go. In other words, this means that in most scenarios we would wait for some number of events to complete and then process the data.</p>
<p>This is different from asynchronous processing of data, where we process an event and its associated data as soon as it occurs. More on that soon.</p>
<p>Now that you know a bit more about batch processing, it'll be useful to see a couple of real world examples. </p>
<h3 id="heading-when-do-we-use-batch-processing">When Do We Use Batch Processing?</h3>
<p>Batch processing is used in lots of scenarios, such as: </p>
<ol>
<li>Large volume of data: When we have a very large amount of data, it is often more resource-efficient to let the data collect over a period of time and then process it.</li>
<li>Data that isn't time sensitive: Since batch processing waits for data to collect, it is generally not suitable for processing data that's very time sensitive. On the other hand, it is possible to process batches of data within short intervals of time.</li>
<li>Scheduled Processing of data: In lots of instances, we need a large amount of data to be processed at regular intervals. Automated system backup and updates, for example, are generally scheduled for particular intervals. Batch processing can be very useful in such scenarios.</li>
</ol>
<h3 id="heading-real-world-example-of-batch-processing-of-data">Real World Example of Batch Processing of Data</h3>
<p>A popular real world use case for batch processing is credit card transactions. </p>
<p>Many financial institutions choose to settle credit card transactions in batches instead of settling them in real time. Since the settlement of transactions is generally not very time sensitive, this gives systems the time to run various other analyses / jobs on the transactions such as fraud detection, currency conversions etc. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/BatchProcessing.drawio-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Credit Card Transactions and Batch Processing</em></p>
<p>The diagram above shows a very high level example of a lifecycle of a credit card transaction. The steps are as follows: </p>
<ol>
<li>The credit card transaction takes place at the Point of Sale (POS).</li>
<li>A gateway forwards the request to a serverless component that writes the transaction to a <em>staging</em> database where the transaction is stored temporarily.</li>
<li>At the end of the business day, the transactions in the staging database are reconciled and go through fraud detection. This is the component where batch processing takes place (note that we waited for some data to collect, and processed a large amount of data). </li>
</ol>
<h3 id="heading-what-does-batch-processing-look-like-in-code">What Does Batch Processing Look Like in Code?</h3>
<p>We saw an example of a distributed system in the above example. How would batch processing look like in code? </p>
<p>Below you'll see some code that lets you process a batch of SQS messages:</p>
<pre><code class="lang-python3">import boto3 

def process_batch_messages(sqs, queue_url):
    partial_response = sqs.receive_message(
        QueueUrl=queue_url
        MaxNumberOfMessages=10 # This sets the maximum batch size to 10
        WaitTimeSeconds=10 # We wait for a maximum of 10 seconds
    )
    if 'Messages' in partial_response:
        messages = partial_response['Messages']
        for each message in messages:
            # do something with each message

            # remove the message from the queue after processing
            sqs.delete_message(QueueUrl=queue_url, ReceiptHandle=message['ReceiptHandle'])


if __name__ == '__main__':
    # Initialize sqs client
        sqs = boto3.client(
        'sqs',
        aws_access_key_id='Your access key id',
        aws_secret_access_key='your secret access key,
        region_name='Your AWS region'
    )
    your_queue_url = 'your-queue-url'
    process_batch_messages(sqs, your_queue_url)
</code></pre>
<p>The above code waits for the earlier of two events: either 10 seconds having passed, or a batch size of 10 being reached within the queue. </p>
<h2 id="heading-asynchronous-processing-of-data">Asynchronous Processing of Data</h2>
<h3 id="heading-what-is-asynchronous-processing">What is Asynchronous Processing?</h3>
<p>The word asynchronous is generally defined as "events that are not coordinated in time". As the definition suggests, asynchronous processing of data does <em>not</em> rely on coordination of data events, and these events are processed as and when they occur. </p>
<p>This means that as soon as an event occurs, the event is processed and the data corresponding to the event may be stored in a sub system, passed on to another component in the system, or may simply lead to another event being fired off. </p>
<h3 id="heading-when-do-we-use-asynchronous-processing">When Do We Use Asynchronous Processing?</h3>
<p>You'll use asynchronous processing of data (sometimes also referred to as async) in various scenarios. </p>
<ol>
<li>Microservices: Microservices often involve a request that needs an immediate response. Since this processing is done "per event", this would require async processing of data, so in most cases results are returned to clients within a very short period of time (low latency).</li>
<li>User Interfaces: Often, components in user facing UI components need to use async processing of data. For instance, multiple data fetches can be performed in the background using async calls when a user is using an application. This ensures that the application works smoothly and responsively without having the need for the UI components to "freeze".</li>
<li>Systems that require real time responses: Many interactive systems require real time processing of data. In the past few years, video calls and meetings have become increasingly popular. Since systems like these require immediate requests and responses (and in some cases streams of data being processed), async processing of data is used here. </li>
</ol>
<h3 id="heading-real-world-example-of-asynchronous-processing-of-data">Real World Example of Asynchronous Processing of Data</h3>
<p>Chat apps are a great example of asynchronous processing of data. Here, if a user 1 types a message and sends it to user 2, the message must be written to the required databases / systems, delivered to user 2, and possibly read by user 2 without any delay. </p>
<p>Since this is <em>real time</em> processing of the event that occurred here (the event being that a message was sent), this is an example of asynchronous processing of data.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/AsyncProcessing.drawio-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Exchange of messages in a chat app</em></p>
<p>In the above diagram we see that User 1 sends a message through their phone. The message gets routed to a message server which ultimately creates an entry in a messages database (Messages DB). </p>
<p>Now that MessagesDB has an entry, an event is fired off that is consumed by the Notification Pusher. This then communicates with User 2's notification queue to put a notification related to the message in their notification queue. </p>
<p>Whenever User 2's device comes online or has access to the internet, they receive a message notification.</p>
<p>Note that we did not wait for any data to collect, nor did we process this data after any specific time delay. We processed the event as soon as it happened. So this is an example of asynchronous processing of data. </p>
<h3 id="heading-what-does-async-processing-look-like-in-code">What Does Async Processing Look Like in Code?</h3>
<p>Can we modify the code that we saw in the section for batch processing to work for async processing? Remember that we said "<em>this code waits for the earlier of two events: 10 seconds having passed, or a batch size of 10 being reached within the queue</em>". </p>
<p>If we change the batch size to 1, we would effectively process a message as soon as it is received.</p>
<pre><code><span class="hljs-keyword">import</span> boto3 

def process_async_messages(sqs, queue_url, batch_size):
    partial_response = sqs.receive_message(
        QueueUrl=queue_url
        MaxNumberOfMessages=batch_size # This sets the maximum batch size
        WaitTimeSeconds=<span class="hljs-number">10</span> # We wait <span class="hljs-keyword">for</span> a maximum <span class="hljs-keyword">of</span> <span class="hljs-number">10</span> seconds
    )
    <span class="hljs-keyword">if</span> <span class="hljs-string">'Messages'</span> <span class="hljs-keyword">in</span> partial_response:
        messages = partial_response[<span class="hljs-string">'Messages'</span>]
        <span class="hljs-keyword">for</span> each message <span class="hljs-keyword">in</span> messages:
            # <span class="hljs-keyword">do</span> something <span class="hljs-keyword">with</span> each message

            # remove the message <span class="hljs-keyword">from</span> the queue after processing
            sqs.delete_message(QueueUrl=queue_url, ReceiptHandle=message[<span class="hljs-string">'ReceiptHandle'</span>])


<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
    # Initialize sqs client
        sqs = boto3.client(
        <span class="hljs-string">'sqs'</span>,
        aws_access_key_id=<span class="hljs-string">'Your access key id'</span>,
        aws_secret_access_key=<span class="hljs-string">'your secret access key,
        region_name='</span>Your AWS region<span class="hljs-string">'
    )
    your_queue_url = '</span>your-queue-url<span class="hljs-string">'
    process_batch_messages(sqs, your_queue_url, 1)</span>
</code></pre><p>Note that in the above code we modified the <code>process_batch_messages</code> to accept a <code>batch_size</code> parameter and renamed the method to <code>process_async_messages</code>. This method processes a message as soon as the queue receives a method (assuming the queue has received a message within the wait time of 10 seconds) </p>
<h2 id="heading-summary">Summary</h2>
<p>Let's summarize batch and asynchronous data processing. </p>
<p>Batch Processing is a paradigm where you wait for an amount of data to collect or some time to pass before the data is processed. </p>
<p>Batch processing is often used in scenarios where you have large volumes of data, data that isn't time sensitive, and data that can be processed on a set schedule. The example we discussed above was that of a credit card transaction.</p>
<p>Asynchronous processing of data, on the other hand, is used to process data related to events as soon as they occur. </p>
<p>This approach is often used when dealing with data processed in microservices, user interfaces, and in general with systems needing real time request-response processing. We looked at an example of a chat app in the above discussion and learnt how asynchronous processing of data is applicable to the scenario. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Protect Data in Transit using HMAC and Diffie-Hellman in Node.js [Full Handbook] ]]>
                </title>
                <description>
                    <![CDATA[ Data integrity refers to the assurance that data will remain accurate, unaltered, and consistent throughout its lifecycle. In communication, data integrity is important in safeguarding against unintended alterations and malicious interventions during... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/hmac-diffie-hellman-in-node/</link>
                <guid isPermaLink="false">66c4c5351b22d2d8d9040ebd</guid>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                    <category>
                        <![CDATA[ MathJax ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Hamdaan Ali ]]>
                </dc:creator>
                <pubDate>Mon, 18 Mar 2024 23:00:22 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/03/Protect-Data-in-Transit-Handbook-v2--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Data integrity refers to the assurance that data will remain accurate, unaltered, and consistent throughout its lifecycle. In communication, data integrity is important in safeguarding against unintended alterations and malicious interventions during data transmission.</p>
<p>The integrity of Digital Data is accomplished using Hashing Algorithms. The <code>crypto</code> module in Node provides various built-in vetted library functions to provide means to not only verify the integrity of data but also the authenticity of its origin.</p>
<p>This handbook aims to highlight the internal workings of the functions in the <code>crypto</code> library and give you some insights into the internal workings of HMAC and Diffie-Hellman Key Exchange. This will help you make informed decisions about hash algorithms and key lengths depending on your business requirements.</p>
<p>The primary focus of this handbook is to emphasize the crucial aspect of data integrity rather than discussing the various encryption algorithms available. </p>
<p>Encryption is used to protect information by converting it into a secure format, which ensures its confidentiality. But data integrity is concerned with ensuring that the data remains accurate and unaltered.</p>
<p>You can also watch the associated video here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/FAfzQo_eJHI" 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>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-the-alice-bob-paradigm">The Alice-Bob Paradigm</a></li>
<li><a class="post-section-overview" href="#heading-message-detection-code-mdc">Message Detection Code (MDC)</a></li>
<li><a class="post-section-overview" href="#heading-message-authentication-code-mac">Message Authentication Code (MAC)</a></li>
<li><a class="post-section-overview" href="#heading-hash-based-macs-hmac">Hash-based MACs (HMAC)</a></li>
<li><a class="post-section-overview" href="#heading-the-diffie-hellman-merkle-protocol">The Diffie-Hellman-Merkle Protocol</a></li>
<li><a class="post-section-overview" href="#heading-connecting-the-dots">Connecting the Dots</a></li>
<li><a class="post-section-overview" href="#heading-invoking-the-apis">Invoking the APIs</a></li>
<li><a class="post-section-overview" href="#heading-wrapping-up">Wrapping Up</a></li>
<li><a class="post-section-overview" href="#heading-references">References</a></li>
</ul>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<ol>
<li><strong>Node and Express:</strong> We'll create a TypeScript sample application using the Express framework. A basic understanding of the framework would be helpful. You will need the <a target="_blank" href="https://nodejs.org/en/download/">Node Runtime Environment</a> to execute the scripts.</li>
<li><strong>Postman Client:</strong> To make an API request and to test out the sample application, you will need a tool to make HTTP Requests. You may use your web browser's "Edit and Send" feature under the Networks tab, but since not all browsers allow this, it's best to use a tool like <a target="_blank" href="https://www.postman.com/downloads/">Postman</a> which provides a better UI to observe responses.</li>
</ol>
<h2 id="heading-the-alice-bob-paradigm">The Alice-Bob Paradigm</h2>
<p>Throughout this handbook you will come across numerous sequence diagrams and mathematical proofs that use the Alice-Bob Paradigm. </p>
<p>The Alice-Bob paradigm is a common convention in cryptography where two generic entities, often named Alice and Bob, are used to illustrate various scenarios, protocols, or cryptographic principles. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/alice-bob-1.svg" alt="The Alice-Bob Paradigm" width="600" height="400" loading="lazy">
<em>The Alice-Bob Paradigm</em></p>
<p>These characters represent two parties engaged in communication, with Alice typically representing the sender or initiator, and Bob representing the receiver or responder. </p>
<p>We often introduce Eve as a third party, symbolizing an eavesdropper or potential attacker, adding an element of security risk and illustrating scenarios where external entities might attempt to intercept or manipulate the communication.  </p>
<p>The sample application shown in the later sections models after this Alice-Bob Paradigm to use Boost Inc. and Account Aggregator (AA) as the parties engaged in communication.</p>
<h2 id="heading-message-detection-code-mdc">Message Detection Code (MDC)</h2>
<p>When Alice needs to send critical data to Bob over the internet, the data changes hands, jumping between routers and servers, each step carrying the potential risk of unintended alterations. </p>
<p>If Eve manages to get their hands on Alice's data, they might modify it. So the integrity of the data becomes questionable, emphasizing that its original state may have been compromised during transmission.</p>
<p>Note that we are talking about the integrity and not the confidentiality of the data. Say even after Alice encrypts the data, it doesn't inherently guarantee that the data hasn't been tampered with during transit.</p>
<p>Consider this scenario: even though Eve may be unable to decrypt the encrypted message, they might attempt to modify the ciphertext in transit. This could involve altering bits, rearranging packets, or injecting malicious code, potentially leading to unintended consequences upon decryption.</p>
<p>This is where a Message Detection Code (MDC) or a hash comes in picture. A modification detection code (MDC) is a message digest or a checksum that can prove the integrity of a message: that the message has not been changed [1].<br>The figure below explains how MDC is used to verify the integrity of a message:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/MDC.png" alt="Image" width="600" height="400" loading="lazy">
<em>Modification Detection Code [1]</em></p>
<p>A Hash Function is used to generate the digest for any given message. This hash function processes the entire content of the message, producing a fixed-size string of characters that uniquely represents the message's contents. This is called the message digest or MDC.</p>
<p>Note that any hash function, such as SHA-256, SHA-3, or MD5, can be used depending on your specific security requirements and preferences. </p>
<p>Once the digest is generated, it serves as a unique fingerprint for the original message. When Alice sends both the message and its corresponding digest to Bob, they can independently apply the same hash function to the received message. If the calculated digest matches the one received from Alice, it serves as irrefutable evidence that the message has not undergone any modifications during transmission.</p>
<h2 id="heading-message-authentication-code-mac">Message Authentication Code (MAC)</h2>
<p>While MDC or the checksum is typically transferred over a safe channel, it may so happen that the safety of the channel or the trusted party itself is compromised. In such a case Eve can easily modify both the message and the digest and Bob will never know if the message actually came from Alice as intended.</p>
<p>What MDC lacks is a definitive guarantee of the message origin, leaving a potential vulnerability in confirming the true sender. </p>
<p>This is where Message Authentication Code (MAC) comes in. MACs not only ensure the integrity of the message, detecting any unauthorized alterations, but they also provide a mechanism for authenticating the origin of the data. In other words, MACs offer assurance that the message is indeed originating from Alice and not by someone else.</p>
<p>The figure below explains how MAC can help authenticate the origin of a message besides providing integrity check:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/MAC.png" alt="Image" width="600" height="400" loading="lazy">
<em>Message Authentication Code [1]</em></p>
<p>Notice that the difference between a MDC and a MAC is that MAC also includes a secret key (K) between Alice and Bob. The hash function also takes in a key (K) along with the message (M) to generate a MAC.</p>
<p>                                                          $$ h (K | M) = MAC $$</p>
<p>Now both the message and MAC can be sent over the same insecure channel. When Bob receives this ( M + MAC ), he can separate out the message M and compute the MAC for it using the same hash function and the secret key (K). </p>
<p>Bob will then compare the newly computed MAC with the one he received. If the two MACs match, the message is authentic and has not been modified by an adversary.</p>
<p>$$ Alice: S(K,M) = MAC \\ Bob: V(M, K, MAC) = Accept/ Reject $$</p><p>Since Eve does not have this secret key (K), they cannot modify the message and generate a valid MAC. Consequently, the resulting MAC becomes a unique fingerprint, signifying not only the integrity of the message but also authenticating its origin.</p>
<h2 id="heading-hash-based-macs-hmac">Hash-based MACs (HMAC)</h2>
<p>While MAC do provide a guarantee of authentication of the origin of a message, it is still falls short in ensuring unforgeability. It is easy for Eve to perform a Man in The Middle (MiTM) attack, intercept the MAC + Message pair and then perform the Length Extension Attack.</p>
<p>Given ( S = h( K || M) ) and the message (M), Eve can extend (M) to (M' = M || Pad || w) and create (MAC(M')); where (MAC(M')) is evaluated as<br>( S = h( K || M || Pad || w) ).</p>
<p>Eve does not require knowledge of the secret key (K) to extend the message (M) to (M'). When Alice receives this modified (M') and (MAC(M')), they are unable to determine the modification. </p>
<p>HMAC or a Hash-based MAC is a specific method for constructing a MAC algorithm out of a collision resistant hash function. HMAC uses two passes of hash computation and provides a better immunity against length extension attacks. The figure below explains the construction of HMACs. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/HMAC-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Hash-based Message Authentication Code [1]</em></p>
<p>There are several steps involved in the implementation of HMACs [1]:</p>
<ol>
<li>Divide the message into N blocks, each of b bits</li>
<li>Select a secret key and left-padded with 0’s to create a b-bit key and exclusive-ored with a constant called (ipad) (input pad). </li>
<li>Use the same secret key and XOR it with an another constant called (opad).<br>The value of (ipad) and (opad) are fixed constants as defined in the HMAC Standards [3]. The value of (ipad) is taken as b/8 repetition of the sequence<br>00110110 (hex: 36) and the value of (opad) is taken as b/8 repetition of the sequence 01011100 (hex: 5C).<br>These values are defined in such a way to have the most "non-regular" <a target="_blank" href="https://en.wikipedia.org/wiki/Hamming_distance">Hamming distance</a> from each other.<br>The Hamming distance between (ipad) and (opad) 4, meaning exactly half of the bits are flipped.</li>
<li>Prepend the result produced in Step 2 to the message block. Use the hash function on this (N+1) block to create a n bit message digest called the intermediate HMAC.</li>
<li>The intermediate HMAC is prepended with (0)s to make a b bit block and then the result of Step 3 is prepended to this block.</li>
<li>Use the hash function again on the result of step 5 to get a final n bit HMAC.</li>
</ol>
<p>Mathematically, this can be represented as: </p>
<p>$$ S(k, m) = H(k \oplus \text{opad}  ||  H(k \oplus \text{ipad}  || m)) $$</p><p>Now if Eve tries to extend (M) to (M' = M || Pad || w), the resulting HMAC construction this would be:</p>
<p>$$ HMAC(K, M')=H(K||opad, H(K||ipad, M || Pad || w)) $$</p><p>Due to the unique application of (opad) in the outer hash, the attacker cannot construct (H(K||opad, &lt;...&gt; )) without knowing the key (K). The outer padding disrupts the internal state for any additional input, thwarting the attacker's attempt.              </p>
<h2 id="heading-the-diffie-hellman-merkle-protocol">The Diffie-Hellman-Merkle Protocol</h2>
<p>One of the main challenges in Symmetric-key Ciphers is the distribution of keys. A fundamental question naturally arises: How will Bob know what keys Alice has used?</p>
<p>A very intuitive answer to this problem could be to use a Key Exchange or a Key Distribution Center (KDC). However, the utilization of a KDC or a Key Exchange introduces a notable caveat: the requirement of a secure channel for transmitting keys. </p>
<p>The security of a system employing a Key Distribution Center (KDC), such as in the case of the Kerberos authentication protocol, is heavily dependent on the security of the KDC itself. If the KDC is compromised, the cryptographic keys it manages and distributes can be exposed, leading to potential security vulnerabilities throughout the system as seen in a Golden Ticket Attack.</p>
<p>In the year 1979, <a target="_blank" href="https://en.wikipedia.org/wiki/Ralph_Merkle">Ralph Merkle</a>, <a target="_blank" href="https://en.wikipedia.org/wiki/Whitfield_Diffie">Whitfield Diffie</a> and <a target="_blank" href="https://en.wikipedia.org/wiki/Martin_Hellman">Martin Hellman</a> came up with a way to Securely exchange Cryptographic Keys over Public Insecure Channels. </p>
<p>The Diffie-Hellman-Merkle Protocol provides a way for two parties to agree upon a shared secret key over an insecure channel without directly exchanging that key. The <code>crypto</code> module in Node.js contains the <code>DiffieHellman</code> class, which is a utility for creating Diffie-Hellman key exchanges. </p>
<p>Before we go through all of the functions defined in this class, it is important to understand the mathematics that goes around in The Diffie-Hellman-Merkle Protocol. The UML Sequence Diagram below explains the steps involved in The Diffie-Hellman-Merkle Protocol:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/dh-1.svg" alt="Image" width="600" height="400" loading="lazy">
<em>The Diffie-Hellman-Merkle Protocol</em></p>
<p>The process begins with either of the party who wants to establish a secure communication with the other. In this case, Alice wants to start the communication. </p>
<p>Alice will first pick a randomly chosen Generator <code>g</code> and a large prime number <code>p</code>. Increasing the length of the prime number results in heightened security, as it amplifies the difficulty for adversaries to execute certain cryptographic attacks.</p>
<p>However, enlarging the prime number also comes with computational costs. Longer prime numbers require more computational resources to perform the key generation.</p>
<p>Now, Alice needs to select a Private <code>a</code> and compute a modular exponentiation:</p>
<p>$$ A = g^a  (\text{mod} , p) $$</p><p>Alice will send over the Generator <code>g</code>, the large prime <code>p</code> and Alice's Public Key <code>A</code> to Bob. At this point, Bob has all the values he needs to evaluate his own modular exponentiation of:</p>
<p>$$ A = g^b  (\text{mod} , p) $$</p><p>He will send back this Public Key <code>B</code> to Alice.</p>
<p>Note that up until this point, all communication are occurring over insecure channel. The values <code>g</code>, <code>p</code>, <code>A</code> and <code>B</code> "might" as well be sent as plaintext. The Actual Secret Key is evaluated when Alice and Bob use these data to compute what is known as a "Shared Secret". </p>
<p>Shared Secret computed by A:</p>
<p>$$ S = A^b  (\text{mod} , p) \\  S = g^{\left(ab\right)}  (\text{mod} , p) $$</p><p>Shared Secret computed by B:</p>
<p>$$ S = B^a  (\text{mod} , p) \\  S = g^{\left(ab\right)}  (\text{mod} , p) $$</p><p>Notice how the Shared Secret computed by both parties at their end are the same. </p>
<p>This symmetrical outcome is the essence of the Diffie-Hellman key exchange, where each party independently computes the shared secret using their private key and the public key received from the other party. This ensures that both Alice and Bob arrive at an identical Shared Secret, establishing a secure foundation for further encrypted communication.</p>
<h3 id="heading-why-is-the-shared-secret-secure">Why is the Shared Secret Secure?</h3>
<p>Diffie-Hellman key exchange relies on the mathematical principles of discrete logarithm, primitive roots and Modular exponentiation.</p>
<p>Modular exponentiation is the problem of computing (a^b  mod n), where (a), (b), and (n) are known integers. Discrete logarithm is the problem of finding (x) such that (a^x  mod n = b), where (a), (b), and (n) are known integers and (a) is a primitive root modulo (n).</p>
<p>The security of Diffie-Hellman is rooted in the computational complexity of calculating discrete logarithms. </p>
<p>For example, given <code>g</code>, <code>p</code> and <code>a</code>, it's easy to compute <code>A</code> as Modular exponentiation is in P, meaning that there is a polynomial-time algorithm to solve it. </p>
<p>But, the other way can't be said true. Given <code>g</code>, <code>p</code>, and <code>A</code>, computing <code>a</code> requires solving the discrete logarithm problem, which is widely believed to be a computationally infeasible task [2].</p>
<p>Remember that both parties will compute the Shared Secret at their end and there is no need to send over this secret to the other party. This eliminates the risk of the Shared Secret getting intercepted by Eve and the only option they are left with is to solve the discrete logarithm problem.</p>
<h2 id="heading-connecting-the-dots">Connecting the Dots</h2>
<p>The key (K) that we provide in an HMAC has to be the same for both Alice and Bob. Now that we know how a Diffie-Hellman-Merkle key exchange works, it becomes intuitive that we can plug in the shared secret as the key for an HMAC.</p>
<p>Alice can use the shared key (S) in the HMAC function as a parameter and Bob can use the same shared secret (S), computed at their end, in the verification algorithm. </p>
<p>The <code>crypto</code> module in Node.js provides various built-in functions to implement cryptographic constructs such as HMACs and Diffie-Hellman Key Exchange. It is always recommended to use vetted cryptographic libraries and avoid implementing cryptographic algorithms yourselves over the concerns of <a target="_blank" href="https://en.wikipedia.org/wiki/Side-channel_attack">Side Channel Attacks</a> or a <a target="_blank" href="https://en.wikipedia.org/wiki/Heartbleed">Heartbleed</a>.</p>
<p>Let's create a TypeScript/ Node.js application to understand the implementation and prototypes of these functions. The two entities involved in communication in this application would be Boost Inc. and Account Aggregator. Boost needs to send a critical data over to the Account Aggregator. </p>
<p>We will first utilize the <code>DiffieHellman</code> class to create Secret Keys for both entities. Boost will then use the Secret Key to create a HMAC using the <code>Hmac</code> Class in Node. Account Aggregator will recieve this HMAC along with the message. They will verify this HMAC against the newly generated HMAC from the message they received.</p>
<p>Note that the code at Account Aggregator's end will be simulated and we will create API endpoints for each operation to show separation of concerns in this sample application.</p>
<p>The following sequence diagram explains what the application does:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/Sample-Application-1.svg" alt="Image" width="600" height="400" loading="lazy">
<em>UML Sequence Diagram for the sample application</em></p>
<h3 id="heading-project-setup">Project Setup</h3>
<p>In the root of your workspace, install Express, Axios, type definitions of Node, and type definitions of Express using the following command:</p>
<pre><code class="lang-bash">npm init -y | npm install axios express
npm install -D nodemon ts-node @types/express @types/node typescript
</code></pre>
<p>Configure <code>tsconfig</code> as per your liking and create a file called <code>cryto.utils.ts</code> under <code>src/utils</code>.  Let's create an interface and import all necessary modules from the <code>crypto</code> library:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { createHmac, createDiffieHellman, DiffieHellman, KeyObject, BinaryLike } <span class="hljs-keyword">from</span> <span class="hljs-string">'crypto'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> KeyPair {
  publicKey: Buffer;
  privateKey: Buffer;
  generator: Buffer;
  prime: Buffer;
  diffieHellman: DiffieHellman;
}
</code></pre>
<p>This interface will function as a blueprint for managing cryptographic key pairs throughout this application. It encapsulates the public and private keys, generator, prime, and a Diffie-Hellman object. </p>
<p>By using this interface we will ensure a structured and standardized approach to handle cryptographic key pair information, thus promoting clarity and consistency in cryptographic operations within a Node.js environment.</p>
<h3 id="heading-the-creatediffiehellman-function">The createDiffieHellman Function</h3>
<p>Next, we will define the function <code>generateKeyPair</code> which will allow us to generate the private and public keys, (A) and (B) along with the large prime (p) and the generator (g) using the <code>createDiffieHellman</code> and <code>generateKeys</code> functions.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateKeyPair</span>(<span class="hljs-params">prime?: <span class="hljs-built_in">any</span>, generator?: <span class="hljs-built_in">any</span></span>): <span class="hljs-title">KeyPair</span> </span>{
  <span class="hljs-keyword">const</span> diffieHellman = prime &amp;&amp; generator ? createDiffieHellman(prime, <span class="hljs-string">'hex'</span>, generator, <span class="hljs-string">'hex'</span>) : createDiffieHellman(<span class="hljs-number">2048</span>);
  diffieHellman.generateKeys();

  <span class="hljs-keyword">return</span> {
    publicKey: diffieHellman.getPublicKey(),
    privateKey: diffieHellman.getPrivateKey(),
    generator: diffieHellman.getGenerator(),
    prime: diffieHellman.getPrime(),
    diffieHellman,
  };
}
</code></pre>
<p>Notice that the parameters to this function – <code>prime</code> and <code>generator</code> – are optional. This is because the underlying <code>createDiffieHellman</code> has five defined overloads:</p>
<pre><code class="lang-ts"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createDiffieHellman</span>(<span class="hljs-params">primeLength: <span class="hljs-built_in">number</span>, generator?: <span class="hljs-built_in">number</span></span>): <span class="hljs-title">DiffieHellman</span></span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createDiffieHellman</span>(<span class="hljs-params">
    prime: <span class="hljs-built_in">ArrayBuffer</span> | NodeJS.ArrayBufferView,
    generator?: <span class="hljs-built_in">number</span> | <span class="hljs-built_in">ArrayBuffer</span> | NodeJS.ArrayBufferView,
</span>): <span class="hljs-title">DiffieHellman</span></span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createDiffieHellman</span>(<span class="hljs-params">
    prime: <span class="hljs-built_in">ArrayBuffer</span> | NodeJS.ArrayBufferView,
    generator: <span class="hljs-built_in">string</span>,
    generatorEncoding: BinaryToTextEncoding,
</span>): <span class="hljs-title">DiffieHellman</span></span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createDiffieHellman</span>(<span class="hljs-params">
    prime: <span class="hljs-built_in">string</span>,
    primeEncoding: BinaryToTextEncoding,
    generator?: <span class="hljs-built_in">number</span> | <span class="hljs-built_in">ArrayBuffer</span> | NodeJS.ArrayBufferView,
</span>): <span class="hljs-title">DiffieHellman</span></span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createDiffieHellman</span>(<span class="hljs-params">
    prime: <span class="hljs-built_in">string</span>,
    primeEncoding: BinaryToTextEncoding,
    generator: <span class="hljs-built_in">string</span>,
    generatorEncoding: BinaryToTextEncoding,
</span>): <span class="hljs-title">DiffieHellman</span></span>;
</code></pre>
<p>The first function creates a Diffie-Hellman object with a randomly generated prime of the specified length. The <code>createDiffieHellman(2048);</code> creates a Diffie-Hellman object where the length of the randomly generated prime is 2048 bits. </p>
<p>When no generator value is provided to this function, it takes the default value of 2. The length of the prime necessarily has to be large and if you select a small value Node will throw an error signifying that this length will not make a secure key.</p>
<p>Instead of passing in the length of the prime, we can pass the prime as a buffer. This is what Account Aggregator will to at their end when Boost sends over the necessary details. </p>
<p>Similarly you can use the other function declarations as per your use case to pass the prime and generator as <code>ArrayBuffer</code> or <code>ArrayBufferView</code> types or as <code>string</code> with a specified encoding.</p>
<h3 id="heading-the-computesecret-function">The computeSecret Function</h3>
<p>Now, let's define a method <code>generateSharedSecret</code> that takes in a Key pair and a public key as parameter and computes the shared secret (S): </p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateSharedSecret</span>(<span class="hljs-params">keyPair: KeyPair, publicKey: Buffer</span>): <span class="hljs-title">Buffer</span> </span>{
  <span class="hljs-keyword">return</span> keyPair.diffieHellman.computeSecret(publicKey);
}
</code></pre>
<p>The <code>computeSecret</code> function also has four overrides, which allows you to either provide the Public key parameter as <code>string</code> or <code>ArrayBufferView</code> as well as options to specify the <code>inputEncoding</code> and <code>outputEncoding</code>.</p>
<h3 id="heading-the-createhmac-function">The createHmac Function</h3>
<p>Now that we've computed our shared secret, let's create a function <code>generateHMAC</code> that consumes this shared secret and generates a digest against it. </p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateHMAC</span>(<span class="hljs-params">data: <span class="hljs-built_in">any</span>, secretKey: KeyObject | BinaryLike</span>): <span class="hljs-title">any</span> </span>{
  data = <span class="hljs-built_in">JSON</span>.stringify(data);
  <span class="hljs-keyword">const</span> hmac = createHmac(<span class="hljs-string">'sha256'</span>, secretKey);
  hmac.update(data);
  <span class="hljs-keyword">return</span> hmac.digest(<span class="hljs-string">'hex'</span>);
}
</code></pre>
<p>The first parameter of the <code>createHmac</code> function takes an algorithm. This is where you need to specify what underlying hash function do you want to use. </p>
<p>Remember that the security of HMAC relies on various factors, including the cryptographic strength of the underlying hash function, the size of its hash output, and the quality and size of the key.</p>
<p>The options given to you under this algorithms parameter depends on the available algorithms supported by the OpenSSL version on the platform. To check what algorithms are available to you, execute the following command in the terminal:</p>
<pre><code class="lang-bash">openssl list -digest-algorithms
</code></pre>
<p>This will give you a list from which you can select your desired algorithm for the underlying hash function:</p>
<pre><code class="lang-bash">RSA-MD4 =&gt; MD4
RSA-MD5 =&gt; MD5
RSA-MDC2 =&gt; MDC2
RSA-RIPEMD160 =&gt; RIPEMD160
RSA-SHA1 =&gt; SHA1
RSA-SHA1-2 =&gt; RSA-SHA1
RSA-SHA224 =&gt; SHA224
RSA-SHA256 =&gt; SHA256
...
</code></pre>
<p>The secret key that the <code>createHmac</code> function takes could either be of type <code>KeyObject</code> or of type <code>BinaryLike</code>. Note that the type <code>BinaryLike</code> is a union type in TypeScript. It is a type that can be either a <code>string</code> or a <code>NodeJS.ArrayBufferView</code>.</p>
<p>The <code>createHmac</code> function's <code>data</code> parameter is designed to accepts <code>strings</code>, <code>Buffer</code>, <code>TypedArray</code> and <code>DataView</code>. To simplify the developer experience and minimize complexity, we intentionally set the <code>data</code> parameter type in the generateHMAC function as <code>any</code>. Internally, we handle the conversion to a string using <code>JSON.stringify</code>.</p>
<h3 id="heading-initializing-communication">Initializing communication</h3>
<p>Now on Boost's end create a file <code>verification.controller.ts</code> under <code>src/controllers</code>: </p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { generateKeyPair, generateSharedSecret, generateHMAC, KeyPair } <span class="hljs-keyword">from</span> <span class="hljs-string">'@boost/v1/utils/crypto.utils'</span>;
<span class="hljs-keyword">import</span> { KeyObject, BinaryLike } <span class="hljs-keyword">from</span> <span class="hljs-string">'crypto'</span>;

<span class="hljs-keyword">const</span> boostKeyPair: KeyPair = generateKeyPair();

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">shareKeys</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> boostPublicKey: Buffer = boostKeyPair.publicKey;
    <span class="hljs-keyword">const</span> boostPrivateKey: Buffer = boostKeyPair.privateKey;
    <span class="hljs-keyword">const</span> boostGenerator: Buffer = boostKeyPair.generator;
    <span class="hljs-keyword">const</span> boostPrime: Buffer = boostKeyPair.prime;
    <span class="hljs-keyword">const</span> boostDiffieHellman = boostKeyPair.diffieHellman;

    <span class="hljs-keyword">return</span> {
        boostPublicKey,
        boostPrivateKey,
        boostGenerator,
        boostPrime,
        boostDiffieHellman,
    };
}

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">hmacDigest</span>(<span class="hljs-params">data: <span class="hljs-built_in">any</span>, secretKey: KeyObject | BinaryLike</span>): <span class="hljs-title">any</span> </span>{
    <span class="hljs-keyword">return</span> generateHMAC(<span class="hljs-built_in">JSON</span>.stringify(data), secretKey);
}
</code></pre>
<p>This file imports the interface and all necessary modules from <code>cryto.utils.ts</code> and defines two wrapper functions – <code>shareKeys</code> and <code>hmacDigest</code>. <code>shareKeys</code> will only serve as a wrapper around <code>generateKeyPair</code> which will allow developers at Boost to send only the required keys over to the Account Aggregator. </p>
<h3 id="heading-setting-up-the-account-aggregator">Setting up the Account Aggregator</h3>
<p>At the Account Aggregator's end, we need to set up a function that computes AA's public key and sends it over to Boost Inc. We will also need a function to verify the received HMAC of a data by comparing it against one that AA generates:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { generateKeyPair, generateSharedSecret, generateHMAC, KeyPair } <span class="hljs-keyword">from</span> <span class="hljs-string">'../utils/crypto.utils'</span>;  
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span>;

<span class="hljs-keyword">let</span> sharedSecret: Buffer;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sendAAPublicKey</span>(<span class="hljs-params"></span>): <span class="hljs-title">Promise</span>&lt;<span class="hljs-title">Buffer</span>&gt; </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">'http://localhost:3000/init'</span>);

    <span class="hljs-keyword">const</span> boostPublicKey: Buffer = Buffer.from(response.data.boostPublicKey, <span class="hljs-string">'hex'</span>);
    <span class="hljs-keyword">const</span> boostGenerator: Buffer = Buffer.from(response.data.boostGenerator, <span class="hljs-string">'hex'</span>);
    <span class="hljs-keyword">const</span> boostPrime: Buffer = Buffer.from(response.data.boostPrime, <span class="hljs-string">'hex'</span>);

    <span class="hljs-keyword">const</span> AA: KeyPair = generateKeyPair(boostPrime, boostGenerator);
    sharedSecret = generateSharedSecret(AA, boostPublicKey);

    <span class="hljs-keyword">return</span> AA.publicKey;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error sending AA public key:'</span>, (error <span class="hljs-keyword">as</span> <span class="hljs-built_in">Error</span>).message);
    <span class="hljs-keyword">throw</span> error;
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">verifyData</span>(<span class="hljs-params">data: <span class="hljs-built_in">any</span>, hmac: <span class="hljs-built_in">string</span></span>): <span class="hljs-title">Promise</span>&lt;<span class="hljs-title">string</span>&gt; </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> calculatedHMAC = generateHMAC(<span class="hljs-built_in">JSON</span>.stringify(data), sharedSecret);
    <span class="hljs-keyword">return</span> calculatedHMAC === hmac ? <span class="hljs-string">"Integrity and authenticity verified"</span> : <span class="hljs-string">"Integrity or authenticity compromised"</span>;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error verifying data:'</span>, (error <span class="hljs-keyword">as</span> <span class="hljs-built_in">Error</span>).message);
    <span class="hljs-keyword">throw</span> error;
  }
}
</code></pre>
<p>We make an Axios request to the <code>/init</code> endpoint defined at Boost and fetch (p), (g) and (A). Once we've computed the public key, we'll send that back to Boost. We will also compute our shared secret here which we'll use while verifying the HMAC in the <code>verifyData</code> method.</p>
<h3 id="heading-setting-up-the-express-apis">Setting up the Express APIs</h3>
<p>Now that all the controllers and utility functions are in place, we'll create a few endpoints to facilitate communication between Boost Inc. and the Account Aggregator.</p>
<h4 id="heading-boost">Boost:</h4>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> express, { Request, Response } <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-keyword">import</span> { hmacDigest, shareKeys } <span class="hljs-keyword">from</span> <span class="hljs-string">'@boost/v1/controllers/verification.controller'</span>;
<span class="hljs-keyword">import</span> { KeyPair, generateSharedSecret } <span class="hljs-keyword">from</span> <span class="hljs-string">'@boost/v1/utils/crypto.utils'</span>;
<span class="hljs-keyword">import</span> { DiffieHellman } <span class="hljs-keyword">from</span> <span class="hljs-string">'crypto'</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span>;

<span class="hljs-keyword">const</span> appBoost = express();
<span class="hljs-keyword">const</span> PORT_BOOST = <span class="hljs-number">3000</span>;

<span class="hljs-keyword">let</span> boostPublicKey: Buffer, boostPrivateKey: Buffer;
<span class="hljs-keyword">let</span> boostGenerator: Buffer, boostPrime: Buffer;
<span class="hljs-keyword">let</span> sharedSecret: Buffer;
<span class="hljs-keyword">let</span> boostKeyPair: KeyPair, boostDiffieHellman: DiffieHellman;

appBoost.get(<span class="hljs-string">'/init'</span>, <span class="hljs-keyword">async</span> (req: Request, res: Response) =&gt; {
    ({ boostPublicKey, boostPrivateKey, boostGenerator, boostPrime, boostDiffieHellman } = shareKeys());
    res.send({ boostPublicKey, boostGenerator, boostPrime });
});

<span class="hljs-comment">// Simulated Data</span>
<span class="hljs-keyword">const</span> data = {
    name: <span class="hljs-string">'Boost User 1'</span>,
    phone: <span class="hljs-string">'1234567890'</span>,
};

appBoost.get(<span class="hljs-string">'/fetchData'</span>, <span class="hljs-keyword">async</span> (req: Request, res: Response) =&gt; {
    <span class="hljs-keyword">const</span> hmac = hmacDigest(data, sharedSecret);
    res.send({ data, hmac });
});

appBoost.listen(PORT_BOOST, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Boost server is running on http://localhost:<span class="hljs-subst">${PORT_BOOST}</span>`</span>);
});
</code></pre>
<p>The <code>/init</code> endpoint, hosted by Boost, is invoked by AA within its <code>sendAAPublicKey</code> function. When the shared secret is calculated, AA will invoke the endpoint <code>/fetchData</code> to retrieve the critical information.</p>
<h4 id="heading-account-aggregator-aa">Account Aggregator (AA):</h4>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> express, { Request, Response } <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-keyword">import</span> { sendAAPublicKey, verifyData } <span class="hljs-keyword">from</span> <span class="hljs-string">'@AA/v1/controllers/aa.controller'</span>;
<span class="hljs-keyword">import</span> { KeyPair, generateSharedSecret } <span class="hljs-keyword">from</span> <span class="hljs-string">'@boost/v1/utils/crypto.utils'</span>;
<span class="hljs-keyword">import</span> { DiffieHellman } <span class="hljs-keyword">from</span> <span class="hljs-string">'crypto'</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span>;

<span class="hljs-keyword">const</span> appAA = express();
<span class="hljs-keyword">const</span> PORT_AA = <span class="hljs-number">3001</span>;

<span class="hljs-keyword">let</span> boostPublicKey: Buffer, boostPrivateKey: Buffer;
<span class="hljs-keyword">let</span> boostGenerator: Buffer, boostPrime: Buffer;
<span class="hljs-keyword">let</span> AAPublicKey: Buffer;
<span class="hljs-keyword">let</span> sharedSecret: Buffer;
<span class="hljs-keyword">let</span> boostKeyPair: KeyPair, boostDiffieHellman: DiffieHellman;

appAA.get(<span class="hljs-string">'/fetchAAPublicKey'</span>, <span class="hljs-keyword">async</span> (req: Request, res: Response) =&gt; {
    AAPublicKey = <span class="hljs-keyword">await</span> sendAAPublicKey();
    res.send({ AAPublicKey: AAPublicKey.toString(<span class="hljs-string">'hex'</span>) });

    boostKeyPair = {
        publicKey: boostPublicKey,
        privateKey: boostPrivateKey,
        generator: boostGenerator,
        prime: boostPrime,
        diffieHellman: boostDiffieHellman,
    }

    sharedSecret = generateSharedSecret(boostKeyPair, AAPublicKey);
});

appAA.get(<span class="hljs-string">'/verifyData'</span>, <span class="hljs-keyword">async</span> (req: Request, res: Response) =&gt; {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">'http://localhost:3000/fetchData'</span>);
    <span class="hljs-keyword">const</span> { data, hmac } = response.data;
    <span class="hljs-keyword">const</span> verified = <span class="hljs-keyword">await</span> verifyData(data, hmac);
    res.send({ verified });
});

appAA.listen(PORT_AA, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`AA server is running on http://localhost:<span class="hljs-subst">${PORT_AA}</span>`</span>);
});
</code></pre>
<p>The <code>fetchAAPublicKey</code> endpoint, hosted as AA's end, will be invoked by Boost when it wants to evaluate the Shared Secret. The <code>verifyData</code> method is encapsulated within a <code>GET</code> request, enabling either party to confirm the integrity of the transmitted data.</p>
<h2 id="heading-invoking-the-apis">Invoking the APIs</h2>
<p>Head over to your Postman Client to test out these APIs. Since the <code>sendAAPublicKey</code> method takes care of the initiation, we need to start our communication using the <code>/fetchAAPublicKey</code> endpoint:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/image-35.png" alt="Image" width="600" height="400" loading="lazy">
<em>Postman Client: fetchAAPublicKey Endpoint</em></p>
<p>You will observe the AA's public key as a response. Now, Boost Inc. will use this Public Key and evaluate the Shared Secret.</p>
<p>Once that is done, it will use the Shared Secret to compute the message digest in the <code>/fetchData</code> endpoint. Since <code>/verifyData</code> invokes the former endpoint, we'll check this in action on our Postman Client:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/image-36.png" alt="Image" width="600" height="400" loading="lazy">
<em>Postman Client: verifyData Endpoint</em></p>
<p>You will notice that the <code>/verifyData</code> response declares the successful verification of both integrity and authenticity. This acknowledgment ensures that the transmitted data remains untampered and originates from the authenticated source, providing a layer of security for communication between the two entities.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>And there you have it: by utilizing HMACs and the Diffie-Hellman-Merkle Key Exchange, you can verify the integrity and authenticity of your transmitted data, enhancing the security of your applications and ensuring a reliable API communication framework for developers. </p>
<p>By understanding the intricacies and mathematical underpinnings of these practices, you can now make informed decisions, fortifying your system against tampering threats.</p>
<p>Find the complete code snippets here — <a target="_blank" href="https://gist.github.com/HamdaanAliQuatil/8e0942eddfe708aafd4f95b739802c0c">GitHub Gist | HamdaanAliQuatil</a>.<br>You may find me on X (formerly Twitter) – <a target="_blank" href="https://twitter.com/violinblackeye">Hamdaan Ali Quatil</a>.</p>
<h3 id="heading-references">References</h3>
<p>[1] Behrouz A. Forouzan – Introduction to Cryptography and Network Security</p>
<p>[2] New Directions in Cryptography, Whitfield Diffie and Martin E. Hellman <a target="_blank" href="https://www.cs.jhu.edu/~rubin/courses/sp03/papers/diffie.hellman.pdf">diffie.hellman.pdf (jhu.edu)</a></p>
<p>[3] Keying Hash Functions for Message Authentication, Mihir Bellare, Ran Canetti, Hugo Krawczyk <a target="_blank" href="https://cseweb.ucsd.edu/~mihir/papers/kmd5.pdf">https://cseweb.ucsd.edu/~mihir/papers/kmd5.pdf</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use OpenTelementry to Trace Node.js Applications ]]>
                </title>
                <description>
                    <![CDATA[ Observability refers to our ability to "see" and understand what's happening inside a system by looking at its external signals (like logs, metrics, and traces). Observability involves collecting and analyzing data from sources within a system to mon... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-opentelementry-to-trace-node-js-applications/</link>
                <guid isPermaLink="false">66d45d5ad7a4e35e38434924</guid>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ node js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ performance ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abraham Dahunsi ]]>
                </dc:creator>
                <pubDate>Sat, 03 Feb 2024 00:21:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/feature-image-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Observability refers to our ability to "see" and understand what's happening inside a system by looking at its external signals (like logs, metrics, and traces).</p>
<p>Observability involves collecting and analyzing data from sources within a system to monitor its performance and address problems effectively.</p>
<h2 id="heading-why-is-observability-useful">Why is Observability Useful?</h2>
<ol>
<li><p><strong>Detecting and Troubleshooting Problems:</strong> Observability plays a role in identifying and diagnosing issues within a system. When something goes wrong, having access to data helps pinpoint the cause and resolve problems more quickly.</p>
</li>
<li><p><strong>Optimizing Performance:</strong> Through monitoring metrics and performance indicators, observability helps in optimizing the performance of your system. This includes identifying bottlenecks, improving resource utilization, and ensuring operation.</p>
</li>
<li><p><strong>Planning for Future Capacity:</strong> Understanding how your system behaves over time is vital for planning capacity requirements. Observability data can reveal trends, peak usage periods, and resource needs, helping your decisions regarding scaling.</p>
</li>
<li><p><strong>Enhancing User Experience:</strong> By observing user interactions with your system through logs and metrics, you can improve the user experience. It assists in recognizing patterns, preferences, and potential areas that can be enhanced for user satisfaction.</p>
</li>
</ol>
<h2 id="heading-why-should-i-use-opentelementary">Why Should I Use OpenTelementary?</h2>
<p>Observability is essential for ensuring the reliability and availability of your Node.js applications. But manually instrumenting your code to collect and export telemetry data, such as traces, metrics, and logs, can become very stressful.</p>
<p>Manual instrumentation is very tedious, error-prone, and inconsistent. It can also introduce additional overhead and complexity to your application logic.</p>
<p>In this guide, you will learn how to use OpenTelemetry’s auto-instrumentation to help you achieve effortless Node.js monitoring.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you go through this guide, make sure you have the following:</p>
<ul>
<li><p>A Node.js application</p>
</li>
<li><p>A Datadog account and an API key. If you don't have one, you can <a target="_blank" href="https://us5.datadoghq.com/signup">sign up here to get one</a>.</p>
</li>
<li><p>A Backend service. You can use a backend service like Zepkin or Jaeger to store and analyze trace data. For this guide, we'll be using Jaeger.</p>
</li>
<li><p>Some basic knowledge of <a target="_blank" href="https://www.freecodecamp.org/news/helpful-linux-commands-you-should-know/">Linux commands</a>. You should be familiar with using the command line and editing configuration files.</p>
</li>
</ul>
<h2 id="heading-prepare-your-application">Prepare Your Application</h2>
<p>In this guide, you will be using a Node.js application that has two services that transfer data between themselves. You will use OpenTelemetry’s Node.js client library to send trace data to an OpenTelementay collector.</p>
<p>Firstly, clone the Repo Locally:</p>
<pre><code class="lang-bash">$ git <span class="hljs-built_in">clone</span> https://github.com/&lt;github-account&gt;/nodejs-example.git
</code></pre>
<p>Then run the application:</p>
<pre><code class="lang-bash">npm install
</code></pre>
<p>Go to the directory of the first service using this command:</p>
<pre><code class="lang-bash">$ <span class="hljs-built_in">cd</span> &lt;ServiceA&gt;
</code></pre>
<p>And start the first service.</p>
<pre><code class="lang-bash">$ node index.js
</code></pre>
<p>Then go to the directory of the second service</p>
<pre><code class="lang-bash">$ <span class="hljs-built_in">cd</span> &lt;ServiceB&gt;
</code></pre>
<p>And start the second service.</p>
<pre><code class="lang-bash">$ node index.js
</code></pre>
<p>Open Service A, in this case port <code>5555</code>, and input some information. Then repeat the same for Service B.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/ServiceASshot.png" alt="ServiceASshot" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-set-up-opentelementary">How to Set Up OpenTelementary</h2>
<p>After starting the services, it's time to install the OpenTelementary modules you'll need for auto-instrumentation.</p>
<p>Here are what we need to install:</p>
<pre><code class="lang-bash">$ npm install --save @opentelemetry/api

$ npm install --save @opentelemetry/instrumentation

$ npm install --save @opentelemetry/tracing

$ npm install --save @opentelemetry/exporter-trace-otlp-http

$ npm install --save @opentelemetry/resources

$ npm install --save @opentelemetry/semantic-conventions

$ npm install --save @opentelemetry/auto-instrumentations-node

$ npm install --save @opentelemetry/sdk-node

$ npm install --save @opentelemetry/exporter-jaeger
</code></pre>
<p>Here's break down of what each module does:</p>
<ul>
<li><p><code>@opentelemetry/api</code>: This module provides the OpenTelemetry API for Node.js.</p>
</li>
<li><p><code>@opentelemetry/instrumentation</code>: The instrumentation libraries provide automatic instrumentation for your Node.js application. They automatically capture telemetry data without requiring manual code modifications.</p>
</li>
<li><p><code>@opentelemetry/tracing</code>: This module contains the core tracing functionality for OpenTelemetry in your Node.js application. It includes the Tracer and Span interfaces, which are important for capturing and representing distributed traces within your applications.</p>
</li>
<li><p><code>@opentelemetry/exporter-trace-otlp-http</code>: This exporter module enables sending trace data to an OpenTelemetry Protocol (OTLP) compatible backend over HTTP.</p>
</li>
<li><p><code>@opentelemetry/resources</code>: This module provides a way to define and manage resources associated with traces.</p>
</li>
<li><p><code>@opentelemetry/semantic-conventions</code>: This module defines a set of semantic conventions for tracing. It establishes a common set of attribute keys and value formats to ensure consistency in how telemetry data is represented and interpreted.</p>
</li>
<li><p><code>@opentelemetry/auto-instrumentations-node</code>: This module simplifies the process of instrumenting your application by automatically applying instrumentation to supported libraries.</p>
</li>
<li><p><code>@opentelemetry/sdk-node</code>: The Software Development Kit (SDK) for Node.js provides the implementation of the OpenTelemetry API.</p>
</li>
<li><p><code>@opentelemetry/exporter-jaeger</code>: This exporter module allows exporting trace data to Jaeger. Jaeger provides a user-friendly interface for monitoring and analyzing trace data.</p>
</li>
</ul>
<h2 id="heading-configure-the-nodejs-application">Configure the Node.js Application</h2>
<p>Next, add a Node.js SDk tracer to handle the instantiation and shutdown of the tracing.</p>
<p>To add the tracer, create a file <code>tracer.js</code>:</p>
<pre><code class="lang-bash">$ nano tracer.js
</code></pre>
<p>Then add the following code to the file:</p>
<pre><code class="lang-javascript"><span class="hljs-meta">
"use strict"</span>;

<span class="hljs-keyword">const</span> {
    BasicTracerProvider,
    SimpleSpanProcessor,
} = <span class="hljs-built_in">require</span>(<span class="hljs-string">"@opentelemetry/tracing"</span>);
<span class="hljs-comment">// Import the JaegerExporter</span>
<span class="hljs-keyword">const</span> { JaegerExporter } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"@opentelemetry/exporter-jaeger"</span>);
<span class="hljs-keyword">const</span> { Resource } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"@opentelemetry/resources"</span>);
<span class="hljs-keyword">const</span> {
    SemanticResourceAttributes,
} = <span class="hljs-built_in">require</span>(<span class="hljs-string">"@opentelemetry/semantic-conventions"</span>);

<span class="hljs-keyword">const</span> opentelemetry = <span class="hljs-built_in">require</span>(<span class="hljs-string">"@opentelemetry/sdk-node"</span>);
<span class="hljs-keyword">const</span> {
    getNodeAutoInstrumentations,
} = <span class="hljs-built_in">require</span>(<span class="hljs-string">"@opentelemetry/auto-instrumentations-node"</span>);

<span class="hljs-comment">// Create a new instance of JaegerExporter with the options</span>
<span class="hljs-keyword">const</span> exporter = <span class="hljs-keyword">new</span> JaegerExporter({
    <span class="hljs-attr">serviceName</span>: <span class="hljs-string">"YOUR-SERVICE-NAME"</span>,
    <span class="hljs-attr">host</span>: <span class="hljs-string">"localhost"</span>, <span class="hljs-comment">// optional, can be set by OTEL_EXPORTER_JAEGER_AGENT_HOST</span>
    <span class="hljs-attr">port</span>: <span class="hljs-number">16686</span> <span class="hljs-comment">// optional</span>
});

<span class="hljs-keyword">const</span> provider = <span class="hljs-keyword">new</span> BasicTracerProvider({
    <span class="hljs-attr">resource</span>: <span class="hljs-keyword">new</span> Resource({
        [SemanticResourceAttributes.SERVICE_NAME]:
            <span class="hljs-string">"YOUR-SERVICE-NAME"</span>,
    }),
});
<span class="hljs-comment">// Add the JaegerExporter to the span processor</span>
provider.addSpanProcessor(<span class="hljs-keyword">new</span> SimpleSpanProcessor(exporter));

provider.register();
<span class="hljs-keyword">const</span> sdk = <span class="hljs-keyword">new</span> opentelemetry.NodeSDK({
    <span class="hljs-attr">traceExporter</span>: exporter,
    <span class="hljs-attr">instrumentations</span>: [getNodeAutoInstrumentations()],
});

sdk
    .start()
    .then(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Tracing initialized"</span>);
    })
    .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Error initializing tracing"</span>, error));

process.on(<span class="hljs-string">"SIGTERM"</span>, <span class="hljs-function">() =&gt;</span> {
    sdk
        .shutdown()
        .then(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Tracing terminated"</span>))
        .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Error terminating tracing"</span>, error))
        .finally(<span class="hljs-function">() =&gt;</span> process.exit(<span class="hljs-number">0</span>));
</code></pre>
<p>Here is a simple breakdown of the code:</p>
<ul>
<li><p>The code starts by importing the modules <code>BasicTracerProvider</code> and <code>SimpleSpanProcessor</code> for setting up tracing from the OpenTelemetry library</p>
</li>
<li><p>It then imports the JaegerExporter module for exporting trace data to Jaeger.</p>
</li>
<li><p>The code creates a new instance of the JaegerExporter, specifying the service name, host, and port.</p>
</li>
<li><p>It then creates a <code>BasicTracerProvider</code> and adds the JaegerExporter to the span processor using <code>SimpleSpanProcessor</code>.</p>
</li>
<li><p>The provider is registered, setting it as the default provider for the application.</p>
</li>
<li><p>An OpenTelemetry SDK instance is created, configuring it with the JaegerExporter and enabling auto-instrumentations for Node.js.</p>
</li>
<li><p>The OpenTelemetry SDK is started, initializing tracing.</p>
</li>
<li><p>A handler for the SIGTERM signal is set up to shut down tracing when the application is terminated.</p>
</li>
<li><p>The code then configures the trace provider with a trace exporter. To verify the instrumentation, <code>ConsoleSpanExporter</code> is used to print some of the tracer output to the console.</p>
</li>
</ul>
<h2 id="heading-how-to-set-up-opentelemetry-to-export-the-traces">How to Set Up OpenTelemetry to Export the Traces</h2>
<p>Next, you'll need to write the configurations to collect and export data in the OpenTelemetry Collector.</p>
<p>Create a file <code>config.yaml</code>:</p>
<pre><code class="lang-yaml">
<span class="hljs-attr">receivers:</span>
  <span class="hljs-attr">otlp:</span>
    <span class="hljs-attr">protocols:</span>
      <span class="hljs-attr">grpc:</span>
      <span class="hljs-attr">http:</span>

<span class="hljs-attr">exporters:</span>
  <span class="hljs-attr">datadog:</span>
    <span class="hljs-attr">api:</span> <span class="hljs-comment"># Replace with your Datadog API key</span>
      <span class="hljs-attr">key:</span> <span class="hljs-string">"&lt;YOUR_DATADOG_API_KEY&gt;"</span>
    <span class="hljs-comment"># Optional:</span>
    <span class="hljs-comment">#   - endpoint: https://app.datadoghq.eu  # For EU region</span>

<span class="hljs-attr">processors:</span>
  <span class="hljs-attr">batch:</span>

<span class="hljs-attr">extensions:</span>
  <span class="hljs-attr">pprof:</span>
    <span class="hljs-attr">endpoint:</span> <span class="hljs-string">:1777</span>
  <span class="hljs-attr">zpages:</span>
    <span class="hljs-attr">endpoint:</span> <span class="hljs-string">:55679</span>
  <span class="hljs-attr">health_check:</span>

<span class="hljs-attr">service:</span>
  <span class="hljs-attr">extensions:</span> [<span class="hljs-string">health_check</span>, <span class="hljs-string">pprof</span>, <span class="hljs-string">zpages</span>]
  <span class="hljs-attr">pipelines:</span>
    <span class="hljs-attr">traces:</span>
      <span class="hljs-attr">receivers:</span> [<span class="hljs-string">otlp</span>]
      <span class="hljs-attr">processors:</span> [<span class="hljs-string">batch</span>]
      <span class="hljs-attr">exporters:</span> [<span class="hljs-string">datadog</span>]
</code></pre>
<p>The configuration sets up OpenTelemetry with the OTLP (OpenTelemetry Protocol) receiver and the Datadog exporter. Here’s a break down of the code:</p>
<ul>
<li><p><code>receivers</code>: Specifies the components that receive the telemetry data. In this case, it includes the OTLP receiver, which supports both gRPC and HTTP protocols.</p>
</li>
<li><p><code>exporters</code>: Defines the components responsible for exporting telemetry data. Here, it configures the Datadog exporter, providing the Datadog API key. Additionally, an optional <code>endpoint</code> is provided for using Datadog's EU region.</p>
</li>
<li><p><code>processors</code>: Specifies the data processing components. In this case, the <code>batch</code> processor is used to batch and send data in larger chunks for efficiency.</p>
</li>
<li><p><code>extensions</code>: Defines additional components that extend the functionality. Here, it includes extensions for pprof (profiling data), zpages (debugging pages), and a health check extension.</p>
</li>
<li><p><code>service</code>: Configures the overall service behavior, including the extensions and pipelines. The <code>extensions</code> section lists the extensions to be used, and the <code>pipelines</code> section configures the telemetry data pipeline. Here, the traces pipeline includes the OTLP receiver, the batch processor, and the Datadog exporter.</p>
</li>
</ul>
<p>This code is configured by the collector with the Datadog exporter to send the traces to Datadog Distributed Tracing services. However, there are other distributed tracing services that you can use like New Relic, Logzio, and Zipkin.</p>
<h2 id="heading-how-to-start-the-application">How to Start the Application</h2>
<p>After correctly setting up auto-instrumentation, start the application again to test and verify the tracing configuration.</p>
<p>Begin by starting the OpenTelemetry Collector:</p>
<pre><code class="lang-bash">./otelcontribcol_darwin_amd64 --config ./config.yaml
</code></pre>
<p>The collector will start on port 4317.</p>
<p>Next, go to the directory of the first service:</p>
<pre><code class="lang-bash">$ <span class="hljs-built_in">cd</span> &lt;ServiceA&gt;
</code></pre>
<p>Then start the first service with the “--require './tracer.js'” parameter to enable the application instrumentation.</p>
<pre><code class="lang-bash">$ node --require <span class="hljs-string">'./tracer.js'</span> index.js
</code></pre>
<p>Repeat this to start the second service.</p>
<p>Using a browser like Chrome, go to the endpoints of your two applications' services, add some data, and send some requests to test the tracing configuration.</p>
<p>Once the requests are made, these traces are picked up by the collector, which then dispatches them to the distributed tracing backend specified by the exporter configuration in the collector's configuration file.</p>
<p>It's worth noting that our tracer not only facilitates the transmission of traces to the designated backend, but also exports them to the console at the same time.</p>
<p>This dual functionality allows for real-time visibility into the traces being generated and sent, helping us in the monitoring and debugging processes.</p>
<p>Now, let’s use Jaeger UI to monitor the traces:</p>
<p>Start Jaeger with the following command:</p>
<pre><code class="lang-bash">docker run -d --name jaeger \
  -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14250:14250 \
  -p 14268:14268 \
  -p 14269:14269 \
  -p 9411:9411 \
  jaegertracing/all-in-one:1.32
</code></pre>
<p>Using a browser, start Jaeger UI at the http://localhost:16686/ endpoint.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/image4-1024x508.png" alt="image4-1024x508" width="600" height="400" loading="lazy"></p>
<p>There you have it! The initiation of the trace starting from the inception point of one service, navigating through a sequence of operations.</p>
<p>This path is created as the service starts its operations, resulting in the set up of the other service to fulfill the original request you initiated earlier.</p>
<p>The trace provides a visual narrative of what happens between these services, offering insights into each step of the process.</p>
<h2 id="heading-how-can-you-use-observability-data">How Can You Use Observability Data?</h2>
<ol>
<li><p><strong>Monitoring Metrics:</strong> Keep an eye on key metrics such as response times, error rates, and resource usage. Sudden spikes or anomalies can indicate issues that require attention.</p>
</li>
<li><p><strong>Logging:</strong> Log data provides detailed information about events and actions within a system. Analyzing logs helps in understanding the sequence of activities and tracing the steps leading to an issue.</p>
</li>
<li><p><strong>Tracing:</strong> Tracing involves tracking the flow of requests or transactions across different components of a system. This helps in understanding the journey of a request and identifying any bottlenecks or delays.</p>
</li>
<li><p><strong>Alerting:</strong> Set up alerts based on specific conditions or thresholds. When certain metrics exceed predefined limits, alerts can notify you in real-time, allowing for immediate action.</p>
</li>
<li><p><strong>Visualization:</strong> Use graphical representations and dashboards to visualize complex data. This makes it easier to identify patterns, trends, and correlations in the observability data.</p>
</li>
</ol>
<p>Observability, when implemented effectively, empowers teams to proactively manage and improve the performance, reliability, and user experience of their systems. It's a crucial aspect of modern software development and operations.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this guide you learned how to auto-instrument Node.js applications with little code by:</p>
<ul>
<li><p>Installing and configuring the OpenTelemetry Node.js SDK and the auto-instrumentation package</p>
</li>
<li><p>Enabling automatic tracing and metrics collection for your Node.js applications and their dependencies</p>
</li>
<li><p>Exporting to visualize your telemetry data on a backend, Jaeger.</p>
</li>
</ul>
<p>Using OpenTelemetry’s auto-instrumentation can help you gain valuable insights into the performance and behavior of your Node.js applications without having to manually instrument each library or framework.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Pandas for Data Cleaning and Preprocessing ]]>
                </title>
                <description>
                    <![CDATA[ Steve Lohr of The New York Times said: "Data scientists, according to interviews and expert estimates, spend 50 percent to 80 percent of their time mired in the mundane labor of collecting and preparing unruly digital data, before it can be explored ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/data-cleaning-and-preprocessing-with-pandasbdvhj/</link>
                <guid isPermaLink="false">66d4608c733861e3a22a734d</guid>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data analysis ]]>
                    </category>
                
                    <category>
                        <![CDATA[ pandas ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oluwadamisi Samuel ]]>
                </dc:creator>
                <pubDate>Tue, 30 Jan 2024 14:55:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/Cream-Neutral-Minimalist-New-Business-Pitch-Deck-Presentation--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Steve Lohr of The New York Times said: "Data scientists, according to interviews and expert estimates, spend 50 percent to 80 percent of their time mired in the mundane labor of collecting and preparing unruly digital data, before it can be explored for useful nuggets."</p>
<p>This statement is 100% accurate, as this encompasses a series of steps that ensure data used for data science, machine learning and analysis projects are complete, accurate, unbiased and reliable.</p>
<p>The quality of your dataset plays a pivotal role in the success of your analysis or model. As the saying goes, “garbage in, garbage out”, the quality and reliability of your model and analysis heavily depends on the quality of your data.</p>
<p>Raw data, collected from various sources, are often messy, contain errors, inconsistencies, missing values and outliers. Data cleaning and preprocessing aims to identify and rectify these issues to ensure accurate, reliable and meaningful results during model building and data analysis as wrong conclusions could be costly.</p>
<p>This is where Pandas comes into play, it is a wonderful tool used in the data world to do both data cleaning and preprocessing. In this article, we'll delve into the essential concepts of data cleaning and preprocessing using the powerful Python library, Pandas.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-introduction">Introduction</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-data-cleaning">What is Data Cleaning?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-data-processing">What is Data Processing?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-import-the-necessary-libraries">How to Import the Necessary Libraries</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-load-the-dataset">How to Load the Dataset</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-exploratory-data-analysis-eda">Exploratory Data Analysis (EDA)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-handle-missing-values">How to Handle Missing Values</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-remove-duplicate-records">How to Remove Duplicate Records</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-data-types-and-conversion">Data Types and Conversion</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-encode-categorical-variables">How to Encode Categorical Variables</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-handle-outliers">How to Handle Outliers</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li><p>A basic understanding of Python.</p>
</li>
<li><p>Basic understanding of data cleaning.</p>
</li>
</ul>
<h2 id="heading-introduction">Introduction</h2>
<p>Pandas is a popular open-source data manipulation and analysis library for Python. It provides easy-to-use functions needed to work with structured data seamlessly.</p>
<p>Pandas also integrates seamlessly with other popular Python libraries, such as NumPy for numerical computing and Matplotlib for data visualization. This makes it a powerful asset for data driven tasks.</p>
<p>Pandas excels in handling missing data, reshaping datasets, merging and joining multiple datasets, and performing complex operations on data, making it exceptionally useful for data cleaning and manipulation.</p>
<p>At its core, Pandas introduces two key data structures: <code>Series</code> and <code>DataFrame</code>. A <code>Series</code> is a one-dimensional array-like object that can hold any data type, while a <code>DataFrame</code> is a two-dimensional table with labeled axes (rows and columns). These structures allow users to manipulate, clean, and analyze datasets efficiently.</p>
<h2 id="heading-what-is-data-cleaning">What is Data Cleaning?</h2>
<p>Before we embark on our data adventure with Pandas, let's take a moment to explain the term "data cleaning." Think of it as the digital detox for your dataset, where we tidy up, and and prioritize accuracy above all else.</p>
<p>Data cleaning involves identifying and rectifying errors, inconsistencies, and missing values within a dataset. It's like preparing your ingredients before cooking; you want everything in order to get the perfect analysis or visualization.</p>
<p>Why bother with data cleaning? Well, imagine trying to analyze sales trends when some entries are missing, or working with a dataset that has duplicate records throwing off your calculations. Not ideal, right?</p>
<p>In this digital detox, we use tools like Pandas to get rid of inconsistencies, straighten out errors, and let the true clarity of your data shine through.</p>
<h2 id="heading-what-is-data-processing">What is Data Processing?</h2>
<p>You may be wondering, "Does data cleaning and data preprocessing mean the same thing?" The answer is no – they do not.</p>
<p>Picture this: you stumble upon an ancient treasure chest buried in the digital sands of your dataset. Data cleaning is like carefully unearthing that chest, dusting off the cobwebs, and ensuring that what's inside is authentic and reliable.</p>
<p>As for data preprocessing, you can think of it as taking that discovered treasure and preparing its contents for public display. It goes beyond cleaning; it's about transforming and optimizing the data for specific analyses or tasks.</p>
<p>Data cleaning is the initial phase of refining your dataset, making it readable and usable with techniques like removing duplicates, handling missing values and data type conversion while data preprocessing is similar to taking this refined data and scaling with more advanced techniques such as feature engineering, encoding categorical variables and and handling outliers to achieve better and more advanced results.</p>
<p>The goal is to turn your dataset into a refined masterpiece, ready for analysis or modeling.</p>
<h2 id="heading-how-to-import-the-necessary-libraries">How to Import the Necessary Libraries</h2>
<p>Before we embark on data cleaning and preprocessing, let's import the <code>Pandas</code> library.</p>
<p>To save time and typing, we often import Pandas as <code>pd</code>. This lets us use the shorter <code>pd.read_csv()</code> instead of <code>pandas.read_csv()</code> for reading CSV files, making our code more efficient and readable.</p>
<pre><code class="lang-py"><span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd
</code></pre>
<h2 id="heading-how-to-load-the-dataset">How to Load the Dataset</h2>
<p>Start by loading your dataset into a Pandas DataFrame.</p>
<p>In this example, we'll use a hypothetical dataset named <strong>your_dataset.csv</strong>. We will load the dataset into a variable called <code>df</code>.</p>
<pre><code class="lang-py"><span class="hljs-comment">#Replace 'your_dataset.csv' with the actual dataset name or file path</span>
df = pd.read_csv(<span class="hljs-string">'your_dataset.csv'</span>)
</code></pre>
<h2 id="heading-exploratory-data-analysis-eda">Exploratory Data Analysis (EDA)</h2>
<p>EDA helps you understand the structure and characteristics of your dataset. Some Pandas functions help us gain insights into our dataset. We call these functions by calling the dataset variable plus the function.</p>
<p>For example:</p>
<ul>
<li><p><code>df.head()</code> will call the first 5 rows of the dataset. You can specify the number of rows to be displayed in the parentheses.</p>
</li>
<li><p><code>df.describe()</code> gives some statistical data like percentile, mean and standard deviation of the numerical values of the Series or DataFrame.</p>
</li>
<li><p><code>df.info()</code> gives the number of columns, column labels, column data types, memory usage, range index, and the number of cells in each column (non-null values).</p>
</li>
</ul>
<p>Here's a code example below:</p>
<pre><code class="lang-py"><span class="hljs-comment">#Display the first few rows of the dataset</span>
print(df.head())

<span class="hljs-comment">#Summary statistics</span>
print(df.describe())

<span class="hljs-comment">#Information about the dataset</span>
print(df.info())
</code></pre>
<h2 id="heading-how-to-handle-missing-values">How to Handle Missing Values</h2>
<p>As a newbie in this field, missing values pose a significant stress as they come in different formats and can adversely impact your analysis or model.</p>
<p>Machine learning models cannot be trained with data that has missing or "NAN" values as they can alter your end result during analysis. But do not fret, Pandas provides methods to handle this problem.</p>
<p>One way to do this is by removing the missing values altogether. Code snippet below:</p>
<pre><code class="lang-py"><span class="hljs-comment">#Check for missing values</span>
print(df.isnull().sum())

<span class="hljs-comment">#Drop rows with missing valiues and place it in a new variable "df_cleaned"</span>
df_cleaned = df.dropna()

<span class="hljs-comment">#Fill missing values with mean for numerical data and place it ina new variable called df_filled</span>
df_filled = df.fillna(df.mean())
</code></pre>
<p>But if the number of rows that have missing values is large, then this method will be inadequate.</p>
<p>For numerical data, you can simply compute the mean and input it into the rows that have missing values. Code snippet below:</p>
<pre><code class="lang-py"><span class="hljs-comment">#Replace missing values with the mean of each column</span>
df.fillna(df.mean(), inplace=<span class="hljs-literal">True</span>)

<span class="hljs-comment">#If you want to replace missing values in a specific column, you can do it this way:</span>
<span class="hljs-comment">#Replace 'column_name' with the actual column name</span>
df[<span class="hljs-string">'column_name'</span>].fillna(df[<span class="hljs-string">'column_name'</span>].mean(), inplace=<span class="hljs-literal">True</span>)

<span class="hljs-comment">#Now, df contains no missing values, and NaNs have been replaced with column mean</span>
</code></pre>
<h2 id="heading-how-to-remove-duplicate-records">How to Remove Duplicate Records</h2>
<p>Duplicate records can distort your analysis by influencing the results in ways that do not accurately show trends and underlying patterns (by producing outliers).</p>
<p>Pandas helps to identify and remove the duplicate values in an easy way by placing them in new variables.</p>
<p>Code snippet below:</p>
<pre><code class="lang-py"><span class="hljs-comment">#Identify duplicates</span>
print(df.duplicated().sum())

<span class="hljs-comment">#Remove duplicates</span>
df_no_duplicates = df.drop_duplicates()
</code></pre>
<h2 id="heading-data-types-and-conversion">Data Types and Conversion</h2>
<p>Data type conversion in Pandas is a crucial aspect of data preprocessing, allowing you to ensure that your data is in the appropriate format for analysis or modeling.</p>
<p>Data from various sources are usually messy and the data types of some values may be in the wrong format, for example some numerical values may come in 'float' or 'string' format instead of 'integer' format and a mix up of these formats leads to errors and wrong results.</p>
<p>You can convert a Column of type <code>int</code> to <code>float</code> with the following code:</p>
<pre><code class="lang-py"><span class="hljs-comment">#Convert 'Column1' to float</span>
df[<span class="hljs-string">'Column1'</span>] = df[<span class="hljs-string">'Column1'</span>].astype(float)

<span class="hljs-comment">#Display updated data types</span>
print(df.dtypes)
</code></pre>
<p>You can use <code>df.dtypes</code> to print column data types.</p>
<h2 id="heading-how-to-encode-categorical-variables">How to Encode Categorical Variables</h2>
<p>For machine learning algorithms, having categorical values in your dataset (non-numerical values) is crucial in ensuring the best model as they are equally as important.</p>
<p>These could be car brand names in a cars dataset for predicting car prices. But machine learning algorithms cannot processes this datatype, therefore it must be converted to numerical data before it can be used.</p>
<p>Pandas provides the <code>get_dummies</code> function which converts categorical values into numerical format(Binary format) such that it is recognized by the algorithm as a placeholder for values and not hierarchical data that can undergo numerical analysis. this just means that the numbers the brand name is converted to is not interpreted as 1 is greater than 0, but it tells the algorithm that both 1 and 0 are placeholders for categorical data. Code snippet is shown below:</p>
<pre><code class="lang-py"><span class="hljs-comment">#To convert categorical data from the column "Car_Brand" to numerical data</span>
df_encode = pd.get_dummies(df, columns=[Car_Brand])

<span class="hljs-comment">#The categorical data is converted to binary format of Numerical data</span>
</code></pre>
<h2 id="heading-how-to-handle-outliers">How to Handle Outliers</h2>
<p>Outliers are data points significantly different from the majority of the data, they can distort statistical measures and adversely affect the performance of machine learning models.</p>
<p>They may be caused by human error, missing NaN values, or could be accurate data that does not correlate with the rest of the data.</p>
<p>There are several methods to identify and remove outliers, they are:</p>
<ul>
<li><p>Remove NaN values.</p>
</li>
<li><p>Visualize the data before and after removal.</p>
</li>
<li><p>Z-score method (for normally distributed data).</p>
</li>
<li><p>IQR (Interquartile range) method for more robust data.</p>
</li>
</ul>
<p>The IQR is useful for identifying outliers in a dataset. According to the IQR method, values that fall below Q1−1.5× IQR or above Q3+1.5×IQR are considered outliers.</p>
<p>This rule is based on the assumption that most of the data in a normal distribution should fall within this range.</p>
<p>Here's a code snippet for the IQR method:</p>
<pre><code class="lang-py"><span class="hljs-comment">#Using median calculations and IQR, outliers are identified and these data points should be removed</span>
Q1 = df[<span class="hljs-string">"column_name"</span>].quantile(<span class="hljs-number">0.25</span>)
Q3 = df[<span class="hljs-string">"column_name"</span>].quantile(<span class="hljs-number">0.75</span>)
IQR = Q3 - Q1
lower_bound = Q1 - <span class="hljs-number">1.5</span> * IQR
upper_bound = Q3 + <span class="hljs-number">1.5</span> * IQR
df = df[df[<span class="hljs-string">"column_name"</span>].between(lower_bound, upper_bound)]
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Data cleaning and preprocessing are integral components of any data analysis, science or machine learning project. Pandas, with its versatile functions, facilitates these processes efficiently.</p>
<p>By following the concepts outlined in this article, you can ensure that your data is well-prepared for analysis and modeling, ultimately leading to more accurate and reliable results.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Web Storage API – How to Store Data on the Browser ]]>
                </title>
                <description>
                    <![CDATA[ The Web Storage API is a set of APIs exposed by the browser so that you can store data in the browser. The data stored in the Web Storage use the key/value pair format, and both data will be stored as strings. There are two types of storage introduce... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/web-storage-api-how-to-store-data-on-the-browser/</link>
                <guid isPermaLink="false">66bd91a827629f4c5e1893bc</guid>
                
                    <category>
                        <![CDATA[ browser ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ storage ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Nathan Sebhastian ]]>
                </dc:creator>
                <pubDate>Fri, 12 Jan 2024 17:43:34 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/web-storage-api-feature-image.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The Web Storage API is a set of APIs exposed by the browser so that you can store data in the browser.</p>
<p>The data stored in the Web Storage use the key/value pair format, and both data will be stored as strings.</p>
<p>There are two types of storage introduced in the Web Storage API: Local Storage and Session Storage.</p>
<p>In this article, I’m going to show you how to use the Web Storage API and why it’s useful for web developers.</p>
<h2 id="heading-how-the-web-storage-api-works">How the Web Storage API Works</h2>
<p>The Web Storage API exposes a set of objects and methods that you can use to store data in the browser. The data you store in Web Storage is private, which means no other website can access it.</p>
<p>In Google Chrome, you can view Web Storage by opening the developer tools window and going to the Application tab as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/web-storage-location-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>The web storage location in Google Chrome</em></p>
<p>In the picture above, you can see that the Storage menu also has other storage types like Indexed DB, Web SQL, and cookies. The Web SQL standard has been deprecated, and IndexedDB is rarely used because it’s too complex. Any data you store in IndexedDB might better be stored on the server.</p>
<p>As for cookies, it’s a more traditional mechanism of storing data that only allows you to store a maximum of 4 KB of data. By contrast, the Local Storage capacity is 10 MB and the session storage has 5 MB capacity.</p>
<p>This is why we’re going to focus only on Local Storage and Session Storage in this article.</p>
<h2 id="heading-local-storage-and-session-storage-explained">Local Storage and Session Storage Explained</h2>
<p>Local Storage and Session Storage are the two standard mechanisms supported by the Web Storage API.</p>
<p>Web storage is domain specific, meaning data stored under one domain (netflix.com) can’t be accessed by another domain (www.netflix.com or members.netflix.com)</p>
<p>Web storage is also protocol specific. This means the data you store in a <code>http://</code> site won’t be available under the <code>https://</code> site.</p>
<p>The main difference between Local and Session Storage is that Local Storage will store your data forever. If you want to remove the data, you need to use the available method or clear it manually from the Applications tab.</p>
<p>By contrast, the data stored in session storage is only available during the page session. When you close the browser or the tab, the session storage for that specific tab is removed.</p>
<p>Both Local and Session Storage can be accessed through the <code>window</code> object under the variables <code>localStorage</code> and <code>sesionStorage</code>, respectively. Let’s see the methods and properties of these storage types next.</p>
<h3 id="heading-methods-and-properties-of-local-and-session-storage">Methods and Properties of Local and Session Storage</h3>
<p>Both Local and Session Storage have the same methods and properties. To set a new key/value pair in the Local Storage, you can use the <code>setItem()</code> method of the <code>localStorage</code> object:</p>
<pre><code class="lang-js"><span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'firstName'</span>, <span class="hljs-string">'Nathan'</span>);
</code></pre>
<p>If you look into the Local Storage menu in the browser, you should see the data above saved into the storage as follows:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/localstorage-setitem.png" alt="Image" width="600" height="400" loading="lazy">
<em>Storing a key/value pair in Local Storage</em></p>
<p>The key you used in <code>localStorage</code> must be unique. If you set another data with a key that already exists, then the <code>setItem()</code> method will replace the previous value with the new one.</p>
<p>To get the value out of local storage, you need to call the <code>getItem()</code> method and pass the key you used when saving the data. If the key doesn’t exist, then <code>getItem()</code> will return <code>null</code> back:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> firstName = <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'firstName'</span>);
<span class="hljs-built_in">console</span>.log(firstName); <span class="hljs-comment">// Nathan</span>

<span class="hljs-keyword">const</span> lastName = <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'lastName'</span>);
<span class="hljs-built_in">console</span>.log(lastName); <span class="hljs-comment">// null</span>
</code></pre>
<p>To remove the data you have in local storage, call the <code>removeItem()</code> method and pass the key pointing to the data you want to remove:</p>
<pre><code class="lang-js"><span class="hljs-built_in">localStorage</span>.removeItem(<span class="hljs-string">'firstName'</span>);
</code></pre>
<p>The <code>removeItem()</code> method will always return <code>undefined</code>. When the data you want to remove doesn’t exist, the method simply does nothing.</p>
<p>If you want to clear the storage, you can use the <code>clear()</code> method:</p>
<pre><code class="lang-js"><span class="hljs-built_in">localStorage</span>.clear();
</code></pre>
<p>The <code>clear()</code> method removes all key/value pairs from the storage object you are accessing.</p>
<h3 id="heading-properties-of-local-and-session-storage">Properties of Local and Session Storage</h3>
<p>Both storage types have only one property, which is the <code>length</code> property that shows the amount of data stored in them.</p>
<pre><code class="lang-js">sessionStorage.setItem(<span class="hljs-string">'firstName'</span>, <span class="hljs-string">'Nathan'</span>);
sessionStorage.setItem(<span class="hljs-string">'lastName'</span>, <span class="hljs-string">'Sebhastian'</span>);

<span class="hljs-built_in">console</span>.log(sessionStorage.length); <span class="hljs-comment">// 2</span>

sessionStorage.clear();
<span class="hljs-built_in">console</span>.log(sessionStorage.length); <span class="hljs-comment">// 0</span>
</code></pre>
<p>And that’s all the methods and properties you can access in <code>localStorage</code> and <code>sessionStorage</code>.</p>
<h2 id="heading-how-to-store-json-strings-in-web-storage-storage">How to Store JSON Strings in Web Storage Storage</h2>
<p>Since Web Storage always stores data as strings, you can store complex data as a JSON string, and then convert that string back into an object when you access it.</p>
<p>For example, suppose I want to store the following information about a user:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> user = {
  <span class="hljs-attr">firstName</span>: <span class="hljs-string">'Nathan'</span>,
  <span class="hljs-attr">lastName</span>: <span class="hljs-string">'Sebhastian'</span>,
  <span class="hljs-attr">url</span>: <span class="hljs-string">'https://codewithnathan.com'</span>,
};
</code></pre>
<p>At first, I might store the data as a series of key/value pairs like this:</p>
<pre><code class="lang-js"><span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'firstName'</span>, user.firstName);
<span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'lastName'</span>, user.lastName);
<span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'url'</span>, user.url);
</code></pre>
<p>But a better way is to convert the JavaScript object into a JSON string, and then store the data under one key as follows:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> user = {
  <span class="hljs-attr">firstName</span>: <span class="hljs-string">'Nathan'</span>,
  <span class="hljs-attr">lastName</span>: <span class="hljs-string">'Sebhastian'</span>,
  <span class="hljs-attr">url</span>: <span class="hljs-string">'https://codewithnathan.com'</span>,
};

<span class="hljs-keyword">const</span> userData = <span class="hljs-built_in">JSON</span>.stringify(user);

<span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'user'</span>, userData);
</code></pre>
<p>Now the local storage will have only one key/value pair with the JSON string as its value. You can open the Applications tab to see this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/store-as-json.png" alt="Image" width="600" height="400" loading="lazy">
<em>Storing a JSON string in Local Storage</em></p>
<p>When you need the data, call the <code>getItem()</code> and <code>JSON.parse()</code> methods as follows:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> getUser = <span class="hljs-built_in">JSON</span>.parse(<span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'user'</span>));

<span class="hljs-built_in">console</span>.log(getUser);
<span class="hljs-comment">// {firstName: 'Nathan', lastName: 'Sebhastian', url: 'https://codewithnathan.com'}</span>
</code></pre>
<p>Here, you can see that the data is returned as a regular JavaScript object.</p>
<h2 id="heading-local-storage-vs-session-storage-which-one-to-use">Local Storage vs Session Storage – Which One to Use?</h2>
<p>Based on my experience, <code>localStorage</code> is the preferred Web Storage mechanism because the data will persist as long as you need it to. When you don’t need the data, you can remove it using the <code>removeItem()</code> method.</p>
<p><code>sessionStorage</code> is only used when you need to store temporary data, like tracking whether a popup box has been shown to the user or not.</p>
<p>But this is also open to discussion because you might not want to show a popup every time the user logs into your web application, but only once. In that case, you should use <code>localStorage</code> instead.</p>
<p>My rule of thumb is to use <code>localStorage</code> first, and <code>sessionStorage</code> when the situation needs it.</p>
<h2 id="heading-benefits-of-using-the-web-storage-api">Benefits of Using the Web Storage API</h2>
<p>Now that you know how the Web Storage API works, you can see that there are some benefits of using it:</p>
<ol>
<li>Storing data on the browser reduces the need to make a server request for a piece of information. This can improve the performance of your web applications.</li>
<li>The simple key/value pair format allows you to store user preferences and local settings that should persist between sessions.</li>
<li>The Web Storage API is simple to use, providing only a few methods and one property. It’s simple to set and retrieve data using JavaScript</li>
<li>It has offline support. By storing necessary data locally, the Web Storage enables your web application to work offline.</li>
<li>The Web Storage is also a standardized API, meaning the code you write will work in many different browsers.</li>
</ol>
<p>But of course, not all data should be stored in the Web Storage API. You still need a server database to keep records that are important for your application.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Web Storage is a useful API that allows you to quickly store and retrieve data from the browser. Using Web Storage, you can store the user’s preferences when accessing your application.</p>
<p><code>localStorage</code> allows you to store data forever until it’s removed manually, while <code>sessionStorage</code> will persist as long as the browser or tab is open.</p>
<p>Some benefits of using the Web Storage API include reducing server requests, offline support, and a simple API that’s easy to use. It’s also standardized, so it will work on different browsers.</p>
<p>If you enjoyed this article and want to take your JavaScript skills to the next level, I recommend you check out my new book <em>Beginning Modern JavaScript</em> <a target="_blank" href="https://codewithnathan.com/beginning-modern-javascript">here</a>.</p>
<p><a target="_blank" href="https://codewithnathan.com/beginning-modern-javascript"><img src="https://www.freecodecamp.org/news/content/images/2024/01/beginning-js-cover.png" alt="beginning-js-cover" width="600" height="400" loading="lazy"></a></p>
<p>The book is designed to be easy for beginners and accessible to anyone looking to learn JavaScript. It provides a step-by-step gentle guide that will help you understand how to use JavaScript to create a dynamic web application.</p>
<p>Here's my promise: <em>You will actually feel like you understand what you're doing with JavaScript.</em></p>
<p>See you later!  </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Signal Processing and Systems in Programming – Guide for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ Signal processing is an important field in engineering and programming.  Basically, it allows engineers and programmers to improve data so that people can use it more effectively. For example, it is thanks to signal processing that much of the backgr... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/signal-processing-and-systems-in-programming/</link>
                <guid isPermaLink="false">66ba5345cccc49d721b6ea21</guid>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Signal Processing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ systems ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Tiago Capelo Monteiro ]]>
                </dc:creator>
                <pubDate>Wed, 06 Sep 2023 14:49:58 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/03/pexels-igor-mashkov-6325003.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Signal processing is an important field in engineering and programming. </p>
<p>Basically, it allows engineers and programmers to improve data so that people can use it more effectively.</p>
<p>For example, it is thanks to signal processing that much of the background noise in a phone call is removed. This way, only your voice arrives on the other end of the call.</p>
<p>Other examples are:</p>
<ul>
<li>Audio and music software</li>
<li>Image and video processing software</li>
<li>Medical imaging software </li>
<li>Speech and language processing software </li>
<li>Wireless communication software</li>
</ul>
<p>Understanding signal processing and systems is key for any programmer who needs to process, manipulate, and analyze these types of data.</p>
<p>This tutorial will explore the field of signal processing and the main characteristics of a system, including some important system characteristics such as:</p>
<ul>
<li>Causality</li>
<li>Memory</li>
<li>Time-invariance</li>
<li>Linearity</li>
</ul>
<p>Here's what we'll cover:</p>
<ol>
<li><a class="post-section-overview" href="#heading-what-is-signal-processing">What is Signal Processing?</a></li>
<li><a class="post-section-overview" href="#heading-python-code-example-how-to-filter-a-signal">Python Code Example – How to Filter a Signal</a></li>
<li><a class="post-section-overview" href="#heading-background-on-the-fourier-transform">Background on the Fourier Transform</a></li>
<li><a class="post-section-overview" href="#heading-what-is-a-system-in-signal-processing">What is a System in Signal Processing</a>?</li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ol>
<h2 id="heading-what-is-signal-processing">What is Signal Processing?</h2>
<p>Signal processing, simply explained, is the field where tools are created for engineers and programmers to manipulate certain signals to solve problems.</p>
<p>It involves analyzing sounds or images to extract only the needed data.</p>
<p>For example, the data from biosensors that shows how much oxygen there is in your blood is displayed in a pulse oximeter. This data is filtered with the help of tools from signal processing.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/pexels-cottonbro-studio-7580256.jpg" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://www.pexels.com/photo/index-finger-in-blue-pulse-oximeter-7580256">Photo by cottonbro studio</a></em></p>
<p>This data processed in a program inside the oximeter with the help of signal processing software tools.</p>
<p>Also, when you're making a phone call to a friend, signal processing algorithms are running so that only your voice gets sent to your friend to reduce as much background noise as possible.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/pexels-karolina-grabowska-4195335.jpg" alt="Image" width="600" height="400" loading="lazy">
<em><a target="_blank" href="https://www.pexels.com/photo/charging-smartphone-and-white-earphones-on-wooden-table-4195335/">Photo by Karolina Grabowska</a></em></p>
<p>Often, signal processing works with the help of tools like the <strong>Fast Fourier Transform</strong>. And don't worry – I'll explain what this is.</p>
<p>Using the Fast Fourier Transform algorithm, we are able to decompose a signal to find the individual waves that make it up.</p>
<p>This way, we are able to remove the individual waves that we don't want (for example, the background noise of a phone call is a set of waves we can remove to improve quality).</p>
<p>The Fast Fourier Transform is also used as a building block or inspiration for some file compression algorithms.</p>
<p>In the end, this is what signal processing is all about: decomposing a signal to extract what we want from it.</p>
<h3 id="heading-where-is-signal-processing-used-in-real-life">Where is signal processing used in real life?</h3>
<ul>
<li>Audio processing – like removing the background noise from a movie</li>
<li>Image processing – like making the image black and white</li>
<li>Wireless communications systems – like modulating a signal so that it can travel further (frequency modulation)</li>
</ul>
<h2 id="heading-python-code-example-how-to-filter-a-signal">Python Code Example – How to Filter a Signal</h2>
<p>You don't need to understand the full code I am about to show you right now – this is just the code I used to generate the graphs I will show you to help you understand how the Fast Fourier Transform works.</p>
<p>I've shared the full code in the conclusion in a GitHub repository so you can check it out.</p>
<p>Here is the code that filters a signal:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np
<span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt

t = np.linspace(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">300</span>, endpoint=<span class="hljs-literal">False</span>)
x = np.sin(<span class="hljs-number">2</span>np.pi10t)
y = <span class="hljs-number">0.5</span>np.sin(<span class="hljs-number">2</span>np.pi20t)
w = <span class="hljs-number">0.2</span>np.sin(<span class="hljs-number">2</span>np.pi50t)
z = x + y + w

zf = np.fft.fft(z)

N = len(z)
freq = np.fft.fftfreq(N, d=t[<span class="hljs-number">1</span>]-t[<span class="hljs-number">0</span>])
spectrum = <span class="hljs-number">2</span>/N * np.abs(zf[:N//<span class="hljs-number">2</span>])

mask = np.ones(len(freq), dtype=bool)
mask[(freq &gt; <span class="hljs-number">15</span>) &amp; (freq &lt; <span class="hljs-number">60</span>)] = <span class="hljs-literal">False</span>
mask[(freq &lt; <span class="hljs-number">-15</span>) &amp; (freq &gt; <span class="hljs-number">-60</span>)] = <span class="hljs-literal">False</span>

zf_filtered = zf.copy()
zf_filtered[~mask] = <span class="hljs-number">0</span>

z_filtered = np.fft.ifft(zf_filtered)
</code></pre>
<p>Below i will show visually what each part of the code does with graphs:</p>
<h3 id="heading-step-1-creating-the-signals">Step 1: Creating the signals</h3>
<pre><code>t = np.linspace(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">300</span>, endpoint=False)
x = np.sin(<span class="hljs-number">2n</span>p.pi10t)
y = <span class="hljs-number">0.5n</span>p.sin(<span class="hljs-number">2n</span>p.pi20t)
w = <span class="hljs-number">0.2n</span>p.sin(<span class="hljs-number">2n</span>p.pi50*t)
z = x + y + w
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Figure_1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Three different signals and a green signal representing their sum</em></p>
<p>We can see here that the green signal is the sum of:</p>
<ul>
<li>Red wave – X signal</li>
<li>Blue wave – Y signal</li>
<li>Orange wave – W signal</li>
</ul>
<p>Note that any signal can be composed of a certain number of simple waves. In mathematics, these waves are the sine and cosine functions.</p>
<p>This incredibly important idea is called a Fourier series.</p>
<p>Below is a video I recommend that explains simply what a Fourier series is:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/UKHBWzoOKsY" 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>
<h3 id="heading-step-2-creating-a-fast-fourier-transform-on-the-signal-z">Step 2: Creating a Fast Fourier Transform on the signal Z</h3>
<p>We can apply the Fast Fourier Transform like this:</p>
<pre><code>zf = np.fft.fft(z)
</code></pre><p>To make a graph out of it, we still need to do the following:</p>
<pre><code>N = len(z)
freq = np.fft.fftfreq(N, d=t[<span class="hljs-number">1</span>]-t[<span class="hljs-number">0</span>])
spectrum = <span class="hljs-number">2</span>/N * np.abs(zf[:N<span class="hljs-comment">//2])</span>
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Figure_2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Seeing the green signal in terms of frequency instead of time - We are "seeing" the green signal from another point of view</em></p>
<p>Thanks to the Fast Fourier Transform, we are able to see the composition of the green signal. </p>
<p>As we can see, the green signal is composed of 3 waves with 3 different frequencies:</p>
<ul>
<li>10 hertz – Red wave – X signal</li>
<li>20 hertz – Blue wave – Y signal</li>
<li>50 hertz – Orange wave – W signal</li>
</ul>
<h3 id="heading-step-3-creating-and-applying-the-filter">Step 3: Creating and applying the filter</h3>
<pre><code>mask = np.ones(len(freq), dtype=bool)
mask[(freq &gt; <span class="hljs-number">15</span>) &amp; (freq &lt; <span class="hljs-number">60</span>)] = False
mask[(freq &lt; <span class="hljs-number">-15</span>) &amp; (freq &gt; <span class="hljs-number">-60</span>)] = False

zf_filtered = zf.copy()
zf_filtered[~mask] = <span class="hljs-number">0</span>

z_filtered = np.fft.ifft(zf_filtered)
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Figure_3.png" alt="Image" width="600" height="400" loading="lazy">
<em>Filtered X signal from the green signal - Only the 10 hertz signal passes</em></p>
<p>This filter is called a pass-band filter, because it filters all the frequencies between 30 hertz and 60 hertz.</p>
<p>So, this filtered red signal is essentially the <strong>original</strong> red signal.</p>
<h2 id="heading-background-on-the-fourier-transform">Background on the Fourier Transform</h2>
<p>The idea that any signal can be represented by the sum of simple waves was created by the mathematician Joseph Fourier.</p>
<p>These waves are called sine and cosine.</p>
<p>Note: you don't need to understand these equations completely – I'm just showing them so you can understand the history of the Fourier Transform.</p>
<p>This is what is called a Fourier series:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/fourier-series-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Equation for Fourier series</em></p>
<p><a target="_blank" href="https://cdn1.byjus.com/wp-content/uploads/2020/11/Fourier-series-formula.png">Here is a better image of  the equation</a></p>
<p>The coefficients are given by the following:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/fourier-series-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Coefficients of the Fourier series</em></p>
<p>From the Fourier series the Fourier transform can be deduced:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/fourier-tra-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Fourier transform equation</em></p>
<p><a target="_blank" href="https://abakcus.com/wp-content/uploads/2021/09/Fourier-Transform-Equations-That-Changed-the-World-Abakcus-scaled.jpg">H</a>ere is a better image of the formula</p>
<p>However, the Fourier transform was developed by various mathematicians and physicists over the years.</p>
<p>So, it was based on the work of many scholars over time that we were able to redefine the Fourier transform. </p>
<p>But this is not the pure mathematical complicated expression that is running in a computer.</p>
<p>In a computer, it is an algorithm that approximates very well the Fourier transform called the <strong>Fast Fourier Transform</strong>.</p>
<p>That is where in the code the FFT comes from:</p>
<pre><code>zf = np.fft.fft(z)
</code></pre><p><code>fft</code> stands for Fast Fourier Transform.</p>
<p>Here are the docs with the function:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://numpy.org/doc/stable/reference/generated/numpy.fft.fft.html">https://numpy.org/doc/stable/reference/generated/numpy.fft.fft.html</a></div>
<p>But you might be asking...</p>
<h3 id="heading-why-use-the-fast-fourier-transform">Why use the Fast Fourier Transform?</h3>
<p>Because the Fast Fourier Transform <strong>runs much faster</strong> than the pure mathematical equation.</p>
<p>There is even a whole field of mathematics dedicated to finding algorithms that approximate pure math so that computers can run it really fast.</p>
<p>This field is called <strong><a target="_blank" href="http://www.scholarpedia.org/article/Numerical_analysis">Numerical Analysis</a>.</strong></p>
<p>It is also used to find approximate solutions for problems that are impossible to find by hand.</p>
<p>For example, in the field of partial differential equations, many solutions to partial differential equations are only solved with numerical analysis methods running on computers.</p>
<p>This way, thanks to this field of mathematics, companies are able to save millions in energy costs</p>
<p>If you are interested in learning more about numerical analysis, I've included some more resources in the conclusion.</p>
<p>Changing the topic slightly, now we will talk about systems</p>
<h2 id="heading-what-is-a-system-in-signal-processing">What is a System in Signal Processing?</h2>
<p>A system is a combination of many “things” that work together as if they were a whole.</p>
<p>An example of a system could be a computer or a car.</p>
<p>In signal processing, a system is often a combination of software and hardware in a technology that takes an input signal and produces an output signal.</p>
<p>For example, when pressing the acceleration pedal in a car (input), the car goes faster (output).</p>
<p>Knowing the characteristics of a system is important for understanding how it will process the signal.</p>
<p>Four important characteristics of a system are:</p>
<ul>
<li>Causality</li>
<li>Memory</li>
<li>Time-invariance</li>
<li>Linearity</li>
</ul>
<p>But, why is it important to understand the main characteristics of a system in programming?</p>
<p>By understanding these characteristics, you will understand better how to design software (in this case, the system can be seen as software) as well as how to optimize and integrate it.</p>
<p>Knowing these characteristics is very important in systems engineering where they are applied to software development. They help you manage the complexity of programs, define their requirements, and ensure quality, adaptability and scalability.</p>
<p>If you want to learn more about systems engineering, <a target="_blank" href="https://www.freecodecamp.org/news/what-is-systems-engineering/">you can read my article on it</a>.</p>
<p>So, let's learn more about what each of these characteristics are.</p>
<h3 id="heading-causality">Causality</h3>
<p>Causality is the property of a system where the output depends on past and present input <strong>only</strong>.</p>
<p>For example, when predicting the weather, it is only possible to use past weather data to make a forecast. </p>
<p>It is not possible to use future weather data to predict the weather.</p>
<h3 id="heading-memory">Memory</h3>
<p>Memory is the property of a system where the output depends on past inputs.</p>
<p>Recommendation systems used by websites like Netflix and Amazon suggest movies or products based on a user's previous interactions.</p>
<p>The algorithms take into account products viewed or purchased, and use this information to recommend similar items.</p>
<p>With more data gathered over time, recommendations become more accurate and personalized.</p>
<p>Memory is important in programming because it allows us to create systems that can learn and adapt over time – for example, machine learning systems.</p>
<h3 id="heading-time-invariance">Time-invariance</h3>
<p>Time-invariance is the property of a system when the output does not depend on when the input was applied.</p>
<p>Real-time control systems used in robotics, manufacturing, and aerospace applications rely on time-invariant systems.</p>
<p>For instance, a flight control system must respond quickly and accurately to changes in an aircraft's position, irrespective of when they occur.</p>
<h3 id="heading-linearity">Linearity</h3>
<p>Linearity in programming is like a recipe where doubling the ingredients results in a proportionally doubled output, allowing for predictable and accurate results.</p>
<p>Linearity refers to the property of a system where the output is directly proportional to the input.</p>
<p>This means that if the input is doubled, the output will also be doubled.</p>
<p>For example, in digital image processing, linearity is used in techniques such as contrast adjustment and color correction to ensure that the output is proportional to the input. </p>
<p>This results in predictable and accurate image processing.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Signal processing and systems are essential for programming because they allow us to process, manipulate, and analyze data in a reliable and predictable way.</p>
<p>Whether you are working on audio processing, image processing, or any other application that involves signal processing, understanding the fundamentals of signal processing and systems is crucial for success.</p>
<p>Systems are closely related to signal processing, because they allow the transformation of signal for programmers and engineers to reach their desired goal.</p>
<p>If you are interested in learning more about Fourier Transform, here is a YouTube video explaining it in more depth:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/spUNpyF58BY" 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>Here is a YouTube video explaining the algorithm that actually runs on your computer:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/h7apO7q16V0" 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>And here is also a video detailing the history of the development of the Fast Fourier Transform:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/nmgFG7PUHfo" 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>
<h2 id="heading-final-note">Final Note</h2>
<p>There are more transforms used for signal processing and other purposes, such as the Laplace transform (used in continuous signals) and the Z transform (used in discreet signals).</p>
<p>But, since there are so many mathematical transforms formulas, what really is a transform?</p>
<p>A transform is simply a mathematical tool that helps us see something from a different point of view.</p>
<p>By seeing things a different way, we can learn about details we did not see originally.</p>
<p>For example, with the Fourier Transform, we can see the signal from the point of view of a frequency instead of the point of view of time.</p>
<p>This lets us see the same thing in a different way.</p>
<p>Mathematically, we can say we are changing the domain of the function. In other words, we are changing the x axis.</p>
<p>And I will leave this with you: the Laplace transform is a generalized Fourier transform.</p>
<h3 id="heading-full-code">Full code:</h3>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/tiagomonteiro0715/Signal-Processing-and-Systems-in-Programming-Guide-for-Beginners">https://github.com/tiagomonteiro0715/Signal-Processing-and-Systems-in-Programming-Guide-for-Beginners</a></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Steganography? How to Hide Data Inside Data ]]>
                </title>
                <description>
                    <![CDATA[ Ladies and Gentlemen, welcome to the world of Spies 🕵️. In the movie Uncharted (great movie by the way), Tom Holland and his brother have a secret form of communication. They would write a message on a plain postcard with special ink that became inv... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-steganography-hide-data-inside-data/</link>
                <guid isPermaLink="false">66bb9027d2bda3e4315491cd</guid>
                
                    <category>
                        <![CDATA[ Cryptography ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Iwugo ]]>
                </dc:creator>
                <pubDate>Thu, 13 Jul 2023 17:15:06 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/08/pexels-cottonbro-4966171.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Ladies and Gentlemen, welcome to the world of Spies 🕵️.</p>
<p>In the movie Uncharted (great movie by the way), Tom Holland and his brother have a secret form of communication. They would write a message on a plain postcard with special ink that became invisible and then send it to the other person. </p>
<p>On the outside, it seemed like another plain old postcard. But if a lighter was lit just behind the paper, the ink would reappear, and a new message would be found 🔥. </p>
<p>This is one of the coolest hidden information tricks seen in movies. But what if we could do this on computers?</p>
<p>Well, turns out we sorta can. Using Steganography.</p>
<p><strong>Disclaimer: This concept can be used for both good and bad. The content of this article is for educational purposes only and is not to be used to play pranks, or harm people and infrastructure.</strong></p>
<p>And with that out of the way, here’s what we’re going to explore in this article:</p>
<ol>
<li>What is Steganography?</li>
<li>Types of Steganography – Text, Image, Video, Audio, Network</li>
<li>Image steganography using Steghide</li>
</ol>
<h2 id="heading-what-is-steganography">What is Steganography?</h2>
<p>Steganography is the art of hiding secret data in plain sight. It sounds kind of counter-intuitive, but you’d be surprised how effective it is. </p>
<p>Hiding things such as source code, passwords, IP addresses, and other confidential information in pictures, music, or other random files tends to be the last place anyone would think of finding them.</p>
<p>You should note that steganography and cryptography are not mutually exclusive from each other. One may contain elements of the other or both. For example, you could perform steganography with an encryption algorithm or password, as you’ll find out soon.</p>
<h2 id="heading-types-of-steganography">Types of Steganography</h2>
<p>There are various types of steganography, and we’ll look at five of them in this tutorial.</p>
<h3 id="heading-text-steganography">Text Steganography</h3>
<p>This form involves hiding a message within a text. A common way to do this is substitution. It involves replacing certain characters with others and then substituting them back to retrieve the original data. </p>
<p>For example, take the following text.</p>
<pre><code class="lang-markdown">Thi follow eng tixt contaens a sicrit missagi
</code></pre>
<p>Doesn’t really make sense right? But what if we replace the i’s with e’s and the e’s with i’s?</p>
<pre><code class="lang-markdown">The follow ing text contains a secret message
</code></pre>
<p>I think that’s a little easier on the eyes. This is a pretty easy example, but there are much more complicated ones and even some you could come up with on your own.</p>
<h3 id="heading-image-steganography">Image Steganography</h3>
<p>Frankly, this is my favourite. It involves hiding data behind digital images. There are various techniques for image steganography which include the Least Significant Bit technique, Masking and Filtering, and Coding and Cosine Transformation. </p>
<p>Take a look at the two images below and spot the difference:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-75.png" alt="Image" width="600" height="400" loading="lazy">
<em>Groot on Linux ¦ Credit: Mercury</em></p>
<p>Basically, no human on earth can tell the visual difference. But if you take a closer look at the file details…</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-76.png" alt="Image" width="600" height="400" loading="lazy">
<em>Comparing the images ¦ Credit: Mercury</em></p>
<p>The only difference is the size of the images. That’s because the one on the right is hiding 260 words of text in it. How cool is that?</p>
<h3 id="heading-video-steganography">Video Steganography</h3>
<p>In Video steganography, you can literally hide entire videos inside another video. Videos are basically a sequence of images with audio playing as the sequence progresses. This type of steganography allows each video frame to encode an image of the one you want to hide.</p>
<p>This technique can also be used to hide text as demonstrated in the software <a target="_blank" href="https://steganosaur.us">Steganosaurus</a> by James Ridgeway. He shows how it works in this <a target="_blank" href="https://youtu.be/YhnlHmZolRM">video</a>.</p>
<h3 id="heading-audio-steganography">Audio Steganography</h3>
<p>This type of steganography enables hidden messages to be encoded inside an audio file. A common technique used in this is called Backmasking. Backmasking is hiding a message in the audio file and it can only be heard when played backwards.</p>
<p>The famous rapper, Eminem, did some backmasking in the song ‘Stimulate’ back in 2002.</p>
<h3 id="heading-network-steganography">Network Steganography</h3>
<p>This is relatively rare, but nevertheless, it is a technique in which messages are passed by hiding them in network traffic. The messages could be found in the payload or headers of data packets when captured and analysed by the receiver.</p>
<p>Now let’s take a look at how to do some image steganography.</p>
<h2 id="heading-steganography-using-steghide">Steganography using Steghide</h2>
<p>Steghide is an open source image steganography tool that uses the least significant bit (LSB) method to hide data in images. </p>
<p>Images are made up of pixels, which are made up of bits. The bit depth determines how many colours are present in an image. The higher the bit depth, the more colourful the image tends to look.</p>
<p>What LSB does is change the last bit of each byte (or pixel) in the image to one that represents the data you want to hide. This changes the image data, but if done properly is not perceivable. The higher the bit depth and resolution, the more data can be stored in the image.</p>
<p>Now that you understand how it works, let’s play a little hide and seek (no pun intended 👀).</p>
<p>First we’ll be needing a few things:</p>
<ol>
<li>A Linux OS</li>
<li>An Internet Connection</li>
<li>An Image</li>
<li>A Text file</li>
</ol>
<h3 id="heading-install-steghide">Install Steghide</h3>
<p>First we need to install Steghide. Open your terminal and run the following command to do that:</p>
<pre><code class="lang-markdown">sudo apt install steghide
</code></pre>
<p>You can always run <code>steghide --help</code> to get the command list to see all your options.</p>
<h3 id="heading-get-your-image-ready">Get your image ready</h3>
<p>Next, have an image and a text file in a directory. My files are ‘information.txt’ and ‘image.png’. I’ve also put some text in the file to hide in the image later.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-77.png" alt="Image" width="600" height="400" loading="lazy">
<em>Setting up files ¦ Credit: Mercury</em></p>
<p>Open up your terminal again and go to the directory you stored the files. Mine is in <code>~/Documents/steganography_tutorial</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-78.png" alt="Image" width="600" height="400" loading="lazy">
<em>Looking for the files ¦ Credit: Mercury</em></p>
<h3 id="heading-create-a-new-image">Create a new image</h3>
<p>Next, run the following command to create a new image that contains the text file you want hide.</p>
<pre><code class="lang-markdown">steghide embed -ef <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">data</span>&gt;</span></span> -cf <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">image</span>&gt;</span></span> -sf <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">stego_image</span>&gt;</span></span> -v
</code></pre>
<p>Let’s take a look at the command:</p>
<ul>
<li><code>steghide</code> – We specify the tool to use</li>
<li><code>embed</code> – Tells the tool we want to embed data</li>
<li><code>-ef</code> – Embed file, specifies the file to hide</li>
<li><code>-cf</code> – Cover file, specifies the cover image</li>
<li><code>-sf</code> – Stego file, creates a duplicate of the original image with the embedded file in it</li>
<li><code>-v</code> – Verbose, gives us more information about the process</li>
</ul>
<p>When the command is run, you’ll be asked to enter a password. If you want an extra layer of security, you might want to do this. If you don’t, just hit enter twice. Here’s the result of what I ran:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-79.png" alt="Image" width="600" height="400" loading="lazy">
<em>Embedding the information ¦ Credit: Mercury</em></p>
<h3 id="heading-inspect-the-new-file">Inspect the new file</h3>
<p>Now let’s take a look at the new file.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-80.png" alt="Image" width="600" height="400" loading="lazy">
<em>Comparing the images side by side ¦ Credit: Mercury</em></p>
<p>There’s seems to be no difference. We can take a closer look with a site called <a target="_blank" href="https://www.diffchecker.com/image-compare/">diffchecker.com</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-81.png" alt="Image" width="600" height="400" loading="lazy">
<em>Comparing the images details ¦ Credit: Mercury</em></p>
<h3 id="heading-extract-the-data">Extract the data</h3>
<p>The stego file is slightly bigger than the original because it contains information. We can extract the data from the stego file using the command below.</p>
<pre><code class="lang-markdown">steghide extract -sf <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">stego_image</span>&gt;</span></span> -xf <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">extracted_data</span>&gt;</span></span>
</code></pre>
<p>Let’s review the command above:</p>
<ul>
<li><code>-sf</code> – stego file, the image containing hidden data</li>
<li><code>-xf</code> – extract file, the file with extracted data</li>
</ul>
<p>Below is the screenshot from running the command. The extracted text is also shown below.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-82.png" alt="Image" width="600" height="400" loading="lazy">
<em>Extracting the information ¦ Credit: Mercury</em></p>
<p>If you extracted the text, Congratulations 🎉🎊. You have successfully hidden and extracted the text from the image. You can do this with a number of things, even whole books.</p>
<p>Using a different tool called Stegcore, I hid a text file containing Quincy Larson’s new book, “<strong><a target="_blank" href="https://www.freecodecamp.org/news/learn-to-code-book/">How to Learn to Code &amp; Get a Developer Job</a></strong>”, behind an image of the book🔍.</p>
<p>Here’s an excerpt from the book.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-83.png" alt="Image" width="600" height="400" loading="lazy">
<em>An excerpt from the book ¦ Credit: Quincy Larson</em></p>
<p>And just like before, the text was embedded into a new image. Here is the original and the stego image side by side.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-84.png" alt="Image" width="600" height="400" loading="lazy">
<em>The original image compared to the stego image ¦ Credit: Mercury</em></p>
<p>And as expected, the stego image is slightly larger in size than the original.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-85.png" alt="Image" width="600" height="400" loading="lazy">
<em>The image details side by side ¦ Credit: Mercury</em></p>
<p>Talk about hiding a book behind a book (bad joke, I know 🤧). If you want to try it out, you can check out the Github <a target="_blank" href="https://github.com/elementmerc/Stegcore">repository</a> or the <a target="_blank" href="https://sourceforge.net/projects/stegcore/">app</a>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>You’ve learned what steganography is and how to implement it using tools. Keep in mind that steganography is a tool and can be used for both good and bad. Companies can hide sensitive information using these means. On the other hand, a hacker could use it to hide malicious code.</p>
<p>Once again, this tutorial is for educational purposes only and is to be used to help and defend information from black hat hackers. Stay safe in the online jungle and happy hacking 🙃.</p>
<h3 id="heading-acknowledgements"><strong>Acknowledgements</strong></h3>
<p>Thanks to <a target="_blank" href="https://twitter.com/Anuoluwap__o">Anuoluwapo Victor</a>, <a target="_blank" href="https://www.linkedin.com/in/chinaza-nwukwa-22a256230/">Chinaza Nwukwa</a>, <a target="_blank" href="https://www.linkedin.com/in/mercy-holumidey-88a542232/">Holumidey Mercy</a>, <a target="_blank" href="https://www.linkedin.com/in/favour-ojo-906883199/">Favour Ojo</a>, <a target="_blank" href="https://www.linkedin.com/in/georgina-awani-254974233/">Georgina Awani</a>, and my family for the inspiration, support and knowledge used to put this together. I appreciate all of you.</p>
<p>If you want articles similar to this one, hit me up on <a target="_blank" href="https://www.upwork.com/freelancers/~01b1dea916f784d554">Upwork</a> or read more of my articles <a target="_blank" href="https://flipboard.com/@elementmerc">here</a>.</p>
<p>Cover image credit: Abstract Data Cube ¦ Credit: <a target="_blank" href="https://unsplash.com/@theshubhamdhage?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Shubham Dhage</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create Data Validation Rules in Excel ]]>
                </title>
                <description>
                    <![CDATA[ By Faith Oyama Data validation is a feature in Excel used in restricting data entry in specific cells. It can also prompt the user to enter valid data into the cells based on the rules and restrictions provided by the creator of the Excel worksheet. ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/create-data-validation-rules-excel/</link>
                <guid isPermaLink="false">66d45edd4a7504b7409c33d5</guid>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ excel ]]>
                    </category>
                
                    <category>
                        <![CDATA[ spreadsheets ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 26 May 2023 00:07:47 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/05/pexels-pixabay-262438.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Faith Oyama</p>
<p>Data validation is a feature in Excel used in restricting data entry in specific cells. It can also prompt the user to enter valid data into the cells based on the rules and restrictions provided by the creator of the Excel worksheet. </p>
<p>When setting up a workbook, you might want to make sure users input a specific type of data. For example, you might want to allow only dates, numbers, or letters in a specific range to be imputed in a cell. This is crucial if you want to eliminate mistakes as much as possible in your data.</p>
<h2 id="heading-types-of-data-validation-rules-in-excel">Types of Data Validation Rules in Excel</h2>
<p>Here are a few data validation rules you can set up in Excel:</p>
<ul>
<li>Only allow text or numeric values in a cell.</li>
<li>Only allow numbers within a specific range.</li>
<li>Display a warning message when a user inputs the wrong data.</li>
<li>Only allow dates and times outside a given range.</li>
<li>Validation rule based on criteria from another cell.</li>
</ul>
<h2 id="heading-steps-to-create-data-validation-rules-in-excel">Steps to Create Data Validation Rules in Excel.</h2>
<p>To create a data validation rule in Excel, do the following:</p>
<p>First, select the row, column, or specific cell you want to apply a data validation rule to.</p>
<p>Then open the data pane and click on the data validation. Alternatively, you can go directly to the data validation dialogue box by pressing the following keys on your keyboard separately. ALT &gt; D &gt; L. Do not hold the keys together, press the keys separately and you will be taken to the dialogue box as well.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/data-menu.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Create the data validation based on what data you want to be supplied in the cell or row.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/data-validation.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can supply the following validation criteria:</p>
<p><strong>Allow</strong>: Make a rule based on the type of data you want to allow. You can choose one from the drop-down menu. You can uncheck the “Ignore blank” button if you do not want blank spaces.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/select-whole-number.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Data</strong>: From the drop-down menu you can choose the criteria and also input the minimum and maximum values you want the user to input. </p>
<p>With the validation criteria set, click OK to close the window or click on the Input Message or Error Alert tab to give the user more information on the data validation rule.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/select-between.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><strong>Input message</strong>: While this is optional, you can input a message to be displayed when a user clicks on a cell that has a data validation rule defined on it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/input-message.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Next, give your input message a title, and under the input message, make sure the message you provide is clear to the user. Click on OK to close the dialogue box or navigate to the Error Alert tab.</p>
<p>Then display an error message. This is optional, but it is good practice to display an error message to users when they enter data that is outside the validation rule you set.</p>
<p>There are three types of error alerts:</p>
<ol>
<li><strong>Stop:</strong> This is the default and is very strict, as it stops users from entering  invalid data. You can only click on “Retry” or “Cancel”</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/enter-a-valid-number-popup.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ol start="2">
<li><strong>Warning:</strong> This will only warn the user but is not as strict as the stop warning. A user can ignore the message by clicking “YES” the invalid data will be inputted.</li>
</ol>
<p>Here’s an example of the warning message a user will get:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/continue-no.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ol start="3">
<li><strong>Information:</strong> This is a permissive type of error alert as it only informs the user about invalid data inputted.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/continue-yes.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If the user clicks OK, the invalid gets inserted into the worksheet. If the user clicks on Cancel, the data gets deleted.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/error-alert-stop.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Give a title to the error alert and also provide a message for your users to see. When you’re done, click on OK, and your data validation rule has been set.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>Data validation in Excel is one powerful feature you should utilize when creating an Excel spreadsheet.</p>
<p>You can use the data validation feature in Excel to make rules that will ensure the data inputted meets certain criteria or follows predefined rules. Setting a data validation rule helps to maintain data accuracy, consistency, and integrity within your Excel worksheet.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ YAML Commenting – How to Add a Multiline Comment in YAML ]]>
                </title>
                <description>
                    <![CDATA[ You can use a YAML file to store data in a format that can be easily read and understood by humans. It is a data serialization language that is often used for configuration files and data transfer between applications. YAML is similar to XML and JSON... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-add-a-multiline-comment-in-yaml/</link>
                <guid isPermaLink="false">66b0a2bd675b17049e0b4bf2</guid>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ YAML ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ihechikara Abba ]]>
                </dc:creator>
                <pubDate>Mon, 01 May 2023 18:28:28 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/vipul-jha-a4X1cdC1QAc-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>You can use a YAML file to store data in a format that can be easily read and understood by humans. It is a <a target="_blank" href="https://www.freecodecamp.org/news/what-is-yaml-the-yml-file-format/#intro:~:text=Serialization%20is%20a%20process%20where%20one%20application%20or%20service%20that%20has%20different%20data%20structures%20and%20is%20written%20in%20a%20different%20set%20of%20technologies%20can%20transfer%20data%20to%20another%20application%20using%20a%20standard%20format.">data serialization language</a> that is often used for configuration files and data transfer between applications.</p>
<p>YAML is similar to XML and JSON as they can all be used to store data in different formats. The main difference is their syntax. </p>
<p>Here's what XML format looks like: </p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">user</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">name</span>&gt;</span>John Doe<span class="hljs-tag">&lt;/<span class="hljs-name">name</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">phone</span>&gt;</span>00223344<span class="hljs-tag">&lt;/<span class="hljs-name">phone</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">age</span>&gt;</span>80<span class="hljs-tag">&lt;/<span class="hljs-name">age</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">user</span>&gt;</span>
</code></pre>
<p>Here's what JSON format looks like:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"user"</span>: {
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"John Doe"</span>,
    <span class="hljs-attr">"phone"</span>: <span class="hljs-string">"00223344"</span>,
    <span class="hljs-attr">"age"</span>: <span class="hljs-number">80</span>
  }
}
</code></pre>
<p>Here's what YAML format looks like:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">user:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">John</span> <span class="hljs-string">Doe</span>
  <span class="hljs-attr">phone:</span> <span class="hljs-number">00223344</span>
  <span class="hljs-attr">age:</span> <span class="hljs-number">80</span>
</code></pre>
<p>Each of the formats above is used to store data about a user's name, phone number, and age.</p>
<p>You can read more about the features, basic rules, and syntax of YAML, and its differences from JSON and XML in <a target="_blank" href="https://www.freecodecamp.org/news/what-is-yaml-the-yml-file-format/">this article</a>.</p>
<p>In this article, you'll learn about multiline comments in YAML. </p>
<h2 id="heading-how-to-add-a-multiline-comment-in-yaml">How to Add a Multiline Comment in YAML</h2>
<p>You can use comments for various reasons like documenting your code, collaborating with others, stopping a block of code from running, and so on. </p>
<p>You can use the <code>#</code> symbol to create comments in a YAML file. That is:</p>
<pre><code class="lang-yaml"><span class="hljs-comment"># The object below represents a user</span>

<span class="hljs-attr">user:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">John</span> <span class="hljs-string">Doe</span>
  <span class="hljs-attr">email:</span> <span class="hljs-string">john.doe@example.com</span>
  <span class="hljs-attr">age:</span> <span class="hljs-number">30</span>
</code></pre>
<p>Unlike some other languages, YAML doesn't have a different format for creating block or multiline comments. </p>
<p>You'll have to use the <code>#</code> symbol on every line the comments spans into. Here's an example: </p>
<pre><code class="lang-yaml"><span class="hljs-comment"># The object below is an example that represents a </span>
<span class="hljs-comment"># user's name, phone number and age</span>

<span class="hljs-attr">user:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">John</span> <span class="hljs-string">Doe</span>
  <span class="hljs-attr">email:</span> <span class="hljs-string">john.doe@example.com</span>
  <span class="hljs-attr">age:</span> <span class="hljs-number">30</span>
</code></pre>
<p>If you remove the <code>#</code> symbol on the second line, the text may still appear as a comment but the YAML parser may interpret it as plain text which may lead to an error. </p>
<p>To be on the safe side, use the <code>#</code> symbol at the start of each comment line. </p>
<h2 id="heading-summary">Summary</h2>
<p>In this article, we talked about YAML. It is mostly used to store and transfer data. </p>
<p>We saw how to create inline and multiline comments. In YAML, the <code>#</code> symbol is used for both inline and multiline comments. </p>
<p>Happy coding! Check out <a target="_blank" href="https://ihechikara.com/">my blog</a> for more programming content.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
