<?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" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[CareerByteCode’s Substack: Trainings]]></title><description><![CDATA[Cloud Devops Free Trainings]]></description><link>https://careerbytecode.substack.com/s/trainings</link><image><url>https://substackcdn.com/image/fetch/$s_!DK3n!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe12a63db-0058-4a43-91d6-ab0fa98ba988_474x474.png</url><title>CareerByteCode’s Substack: Trainings</title><link>https://careerbytecode.substack.com/s/trainings</link></image><generator>Substack</generator><lastBuildDate>Tue, 05 May 2026 07:13:52 GMT</lastBuildDate><atom:link href="https://careerbytecode.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[CareerByteCode]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[careerbytecode@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[careerbytecode@substack.com]]></itunes:email><itunes:name><![CDATA[CareerByteCode]]></itunes:name></itunes:owner><itunes:author><![CDATA[CareerByteCode]]></itunes:author><googleplay:owner><![CDATA[careerbytecode@substack.com]]></googleplay:owner><googleplay:email><![CDATA[careerbytecode@substack.com]]></googleplay:email><googleplay:author><![CDATA[CareerByteCode]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Week 5–6: Kubernetes Provisioning + Autoscaling]]></title><description><![CDATA[1.]]></description><link>https://careerbytecode.substack.com/p/week-56-kubernetes-provisioning-autoscaling</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/week-56-kubernetes-provisioning-autoscaling</guid><dc:creator><![CDATA[Infantus Godfrey]]></dc:creator><pubDate>Wed, 14 Jan 2026 17:07:59 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!F-vV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe1882536-e704-4718-ae63-2ecb588684db_1919x1022.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3><strong>1. Scenario:</strong></h3><p>Create K8s cluster in Azure (AKS) with 3-node pool</p><h3>1. Problem Statement</h3><p>Organizations running containerized workloads require scalable, reliable, and secure Kubernetes clusters to deploy and manage applications. Manually provisioning and managing Azure Kubernetes Service (AKS) clusters can be complex, time-consuming, and error-prone.<br>This use c&#8230;</p>
      <p>
          <a href="https://careerbytecode.substack.com/p/week-56-kubernetes-provisioning-autoscaling">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Week 7: FinOps, Forecasting, Showback, and Cost Control]]></title><description><![CDATA[1.]]></description><link>https://careerbytecode.substack.com/p/week-7-finops-forecasting-showback</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/week-7-finops-forecasting-showback</guid><dc:creator><![CDATA[Infantus Godfrey]]></dc:creator><pubDate>Wed, 14 Jan 2026 17:03:13 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!0Qsu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07b686b-0d9d-49e0-bfdf-c958ca1125f1_1919x1020.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3><strong>1. Scenario:</strong></h3>
      <p>
          <a href="https://careerbytecode.substack.com/p/week-7-finops-forecasting-showback">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Week 1–2: Multi-Cloud VM Provisioning & Cost Optimization Mastery]]></title><description><![CDATA[I Scenario:]]></description><link>https://careerbytecode.substack.com/p/week-12-multi-cloud-vm-provisioning</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/week-12-multi-cloud-vm-provisioning</guid><dc:creator><![CDATA[Bavithran]]></dc:creator><pubDate>Mon, 01 Dec 2025 14:21:52 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ohnf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ae4bf48-b374-48ad-9b29-fb875d8327e0_1919x1009.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3><strong>I Scenario:</strong></h3><p>Provision same VM spec (Ubuntu, 2 vCPU, 4GB RAM, SSD) in AWS, Azure, GCP</p><h3>1. Problem Statement</h3><p>In a multi-cloud environment, managing and provisioning identical virtual machines (VMs) across different cloud providers (AWS, Azure, GCP) manually is time-consuming, error-prone, and inconsistent. Each provider has its own interface, configuration se&#8230;</p>
      <p>
          <a href="https://careerbytecode.substack.com/p/week-12-multi-cloud-vm-provisioning">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[SheLeads Digital: Work-from-Home Empowerment Program for Women ]]></title><description><![CDATA[&#128171; SheLearns, SheLeads, SheEarns]]></description><link>https://careerbytecode.substack.com/p/sheleads-digital-work-from-home-empowerment-program-for-women</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/sheleads-digital-work-from-home-empowerment-program-for-women</guid><dc:creator><![CDATA[CareerByteCode]]></dc:creator><pubDate>Tue, 04 Nov 2025 20:18:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qMVJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3636e37c-e8bf-4b93-ab79-daf9102532ff_1920x1080.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qMVJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3636e37c-e8bf-4b93-ab79-daf9102532ff_1920x1080.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qMVJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3636e37c-e8bf-4b93-ab79-daf9102532ff_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!qMVJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3636e37c-e8bf-4b93-ab79-daf9102532ff_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!qMVJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3636e37c-e8bf-4b93-ab79-daf9102532ff_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!qMVJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3636e37c-e8bf-4b93-ab79-daf9102532ff_1920x1080.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qMVJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3636e37c-e8bf-4b93-ab79-daf9102532ff_1920x1080.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3636e37c-e8bf-4b93-ab79-daf9102532ff_1920x1080.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2978066,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/162682942?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3636e37c-e8bf-4b93-ab79-daf9102532ff_1920x1080.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qMVJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3636e37c-e8bf-4b93-ab79-daf9102532ff_1920x1080.png 424w, https://substackcdn.com/image/fetch/$s_!qMVJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3636e37c-e8bf-4b93-ab79-daf9102532ff_1920x1080.png 848w, https://substackcdn.com/image/fetch/$s_!qMVJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3636e37c-e8bf-4b93-ab79-daf9102532ff_1920x1080.png 1272w, https://substackcdn.com/image/fetch/$s_!qMVJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3636e37c-e8bf-4b93-ab79-daf9102532ff_1920x1080.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h1><strong>SheLeads Digital</strong></h1><h3><em>Work-from-Home Empowerment Program for Women</em></h3><p><strong>Unlock Your Digital Superpowers. Work, Learn &amp; Earn &#8212; From Home.</strong></p><div><hr></div><h2>&#127919; <strong>Who Is This Program For?</strong></h2><p>&#128105;&#8205;&#128188; <strong>Women Restarting Their Careers</strong><br>Took a career break? We&#8217;ll help you rebuild confidence, upgrade your skills, and rejoin the digital workforce &#8212; on <em>your terms.</em></p><p>&#127969; <strong>Homemakers Ready to Earn Digitally</strong><br>You already manage so much. Now, learn how to turn your time, creativity, and passion into <em>real digital income opportunities</em> &#8212; from your own home.</p><p>&#127891; <strong>Students &amp; Moms Seeking Flexibility</strong><br>Study, nurture, and grow &#8212; all while working remotely. Find flexible freelance and part-time digital roles that fit your schedule.</p><p>&#128171; <strong>Aspiring Personal Brands, Freelancers &amp; Coaches</strong><br>If you dream of becoming a content creator, freelancer, or online entrepreneur &#8212; this program gives you the roadmap to <em>build your brand, grow visibility, and earn from your expertise.</em></p><div><hr></div><h2>&#9881;&#65039; <strong>Pre-Requisites</strong></h2><p>&#9989; Dual-Monitor Setup &#8211; for higher productivity<br>&#9989; Fast &amp; Reliable Internet Connection<br>&#9989; Dedicated Computer or Laptop<br>&#9989; Single Gmail ID &#8211; use one consistent Gmail ID across all platforms for unified branding</p><div><hr></div><h2>&#127760; <strong>Create Your Digital Identity</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UsGD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ac485e-f6f0-42d8-a143-f4a9bae0a8e0_716x394.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UsGD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ac485e-f6f0-42d8-a143-f4a9bae0a8e0_716x394.png 424w, https://substackcdn.com/image/fetch/$s_!UsGD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ac485e-f6f0-42d8-a143-f4a9bae0a8e0_716x394.png 848w, https://substackcdn.com/image/fetch/$s_!UsGD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ac485e-f6f0-42d8-a143-f4a9bae0a8e0_716x394.png 1272w, https://substackcdn.com/image/fetch/$s_!UsGD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ac485e-f6f0-42d8-a143-f4a9bae0a8e0_716x394.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UsGD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ac485e-f6f0-42d8-a143-f4a9bae0a8e0_716x394.png" width="716" height="394" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f8ac485e-f6f0-42d8-a143-f4a9bae0a8e0_716x394.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:394,&quot;width&quot;:716,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:37152,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/162682942?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ac485e-f6f0-42d8-a143-f4a9bae0a8e0_716x394.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UsGD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ac485e-f6f0-42d8-a143-f4a9bae0a8e0_716x394.png 424w, https://substackcdn.com/image/fetch/$s_!UsGD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ac485e-f6f0-42d8-a143-f4a9bae0a8e0_716x394.png 848w, https://substackcdn.com/image/fetch/$s_!UsGD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ac485e-f6f0-42d8-a143-f4a9bae0a8e0_716x394.png 1272w, https://substackcdn.com/image/fetch/$s_!UsGD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ac485e-f6f0-42d8-a143-f4a9bae0a8e0_716x394.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p><strong>&#128161; Pro Tip:</strong><br>Use one consistent handle across all platforms to strengthen your brand.<br>Example:<br>&#128231; <em><a href="mailto:CloudByVenkat@gmail.com">CloudByVenkat@gmail.com</a></em><br>&#127760; <em>github.com/CloudByVenkat</em> | &#128188; <em>linkedin.com/in/CloudByVenkat</em> | </p><p>&#128221; <em>medium.com/@CloudByVenkat</em> | &#128187; <em>dev.to/CloudByVenkat</em> | </p><p>&#129504; <em>hashnode.com/@CloudByVenkat</em> | &#128038; <em>x.com/CloudByVenkat</em> | </p><p>&#127909; <em>youtube.com/@CloudByVenkat</em></p><div><hr></div><h2>&#127912; <strong>Design &amp; Tech Essentials</strong></h2><h3>&#129513; <strong>Google Workspace Essentials</strong></h3><p>&#128196; <strong>Google Docs</strong> &#8211; Create, format &amp; collaborate in real-time<br>&#128279; <strong>Sharing Docs</strong> &#8211; Manage permissions, comments &amp; link access<br>&#128202; <strong>Google Sheets</strong> &#8211; Track data, budgets &amp; client records<br>&#128221; <strong>Google Forms + Sheets Integration</strong> &#8211; Create forms &amp; automate data collection into linked spreadsheets</p><div><hr></div><h3>&#10024; <strong>Canva Poster Creation</strong></h3><p>&#127912; Learn to design <strong>eye-catching visuals</strong> for social media, blogs, and clients<br>&#128250; <strong>YouTube Thumbnails</strong> &#8211; Design posters in size <strong>1280px x 720px</strong><br>&#128240; <strong>Dev.to, Medium, Hashnode, Blogger Posters</strong> &#8211; Create optimized visuals <strong>1600px x 840px</strong><br>&#128220; <strong>Letterhead Posters</strong> &#8211; Build personalized templates for your freelance or business use</p><div><hr></div><h3>&#127916; <strong>Professional Design &amp; Presentation Skills</strong></h3><p>&#128202; <strong>PPT Mastery</strong> &#8211; Create visually powerful, story-based presentations<br>&#127908; <strong>Presentation Skills</strong> &#8211; Speak with confidence and impact<br>&#128196; <strong>Professional Documentation</strong> &#8211; Learn to draft client-ready documents with structure and polish<br>&#127902;&#65039; <strong>Basic Video Editing</strong> &#8211; Edit short-form videos for Instagram, YouTube, and clients</p><div><hr></div><h2>&#127897;&#65039; <strong>Podcasts &amp; Self Videos</strong></h2><p>&#127911; <strong>Podcast Creation</strong></p><ul><li><p>Interview experts, mentors, or industry leaders</p></li><li><p>Discuss trending topics: Cloud &#9729;&#65039; | DevOps &#9881;&#65039; | AI &#129302; | Leadership &#127757;</p></li><li><p>Publish on your <strong>YouTube Channel</strong></p></li><li><p>Repurpose podcasts into blogs for Medium, Dev.to, and LinkedIn</p></li></ul><p>&#128249; <strong>Self Video Creation</strong></p><ul><li><p>Record learnings, insights, or project highlights</p></li><li><p>Upload to YouTube &#8594; Repurpose as blogs</p></li><li><p>End every blog with your <em>branding footer</em> (social links &amp; handles)</p></li></ul><div><hr></div><h2>&#128188; <strong>LinkedIn Mastery</strong></h2><h3>&#129718; <strong>Profile Optimization</strong></h3><ul><li><p>Craft a professional <strong>headline</strong> &amp; keyword-rich <strong>summary</strong></p></li><li><p>Highlight achievements with <strong>numbers &amp; impact</strong></p></li><li><p>Use the <strong>Featured Section</strong> to display blogs, presentations, and media</p></li><li><p>Add <strong>volunteer work, certifications, and skills</strong> strategically</p></li></ul><h3>&#128226; <strong>Content &amp; Engagement</strong></h3><ul><li><p>Share <strong>industry insights</strong>, videos, polls, or carousels 3&#8211;5 times/week</p></li><li><p>Use <strong>storytelling</strong> to connect with your audience</p></li><li><p>Comment meaningfully on others&#8217; posts for visibility</p></li><li><p>Celebrate milestones, projects, and achievements</p></li></ul><h3>&#129309; <strong>Networking &amp; Relationship Building</strong></h3><ul><li><p>Send <strong>personalized connection requests</strong></p></li><li><p>Join active <strong>industry-specific groups</strong></p></li><li><p>Attend <strong>LinkedIn events, lives, and webinars</strong></p></li><li><p>Tag mentors &amp; peers authentically for organic visibility</p></li></ul><h3>&#127775; <strong>Thought Leadership</strong></h3><ul><li><p>Write <strong>LinkedIn Articles</strong> &amp; launch a <strong>Newsletter</strong></p></li><li><p>Share <strong>case studies</strong> or <strong>lessons learned</strong></p></li><li><p>Repurpose posts with your unique perspective</p></li><li><p>Post <strong>Q&amp;A discussions</strong> to boost interaction</p></li></ul><h3>&#128200; <strong>Growth &amp; Analytics</strong></h3><ul><li><p>Track profile views, post engagement, and follower growth</p></li><li><p>Analyze competitors&#8217; content strategies</p></li><li><p>Experiment with hashtags, content types, and post timings</p></li></ul><div><hr></div><h2>&#9997;&#65039; <strong>Blogging &amp; Writing Essentials</strong></h2><p>&#128221; Learn to:</p><ul><li><p>Create accounts on Medium, Dev.to, Hashnode &amp; Blogger</p></li><li><p>Write, format &amp; publish SEO-friendly blogs</p></li><li><p>Repurpose YouTube or podcast content into written posts</p></li></ul><p>&#128196; <strong>Resume &amp; Cover Letter Writing</strong> &#8211; Tailored for remote &amp; freelance roles<br>&#128240; <strong>LinkedIn Articles &amp; Newsletters</strong> &#8211; Grow credibility through writing<br>&#128171; <strong>Self-Branding Techniques</strong> &#8211; Position yourself as a thought leader<br>&#127757; <strong>Connect with Industry Leaders</strong> &#8211; Build genuine professional relationships</p><div><hr></div><h2>&#128188; <strong>Business, Clients &amp; Freelancing</strong></h2><p>&#127970; <strong>Understand Your Partner&#8217;s Offerings</strong><br>Learn to confidently explain the course or service offerings to potential clients or learners.</p><p>&#128172; <strong>Ready-Made Client Scripts &amp; Training</strong><br>Use proven templates to respond to inquiries, explain benefits, and close deals effectively.</p><p>&#128161; <strong>Lead Generation Mastery</strong></p><ul><li><p>Learn <strong>different question types</strong> leads may ask</p></li><li><p>Practice answering confidently &amp; empathetically</p></li><li><p>Identify real leads vs. time-wasters</p></li></ul><p>&#128172; <strong>Conversion Psychology</strong></p><ul><li><p>How to convince leads with <em>value-focused communication</em></p></li><li><p>How to overcome objections &amp; guide them to a &#8220;yes&#8221;</p></li></ul><p>&#128105;&#8205;&#127979; <strong>Onboarding Students with Partner Approval</strong></p><ul><li><p>Understand step-by-step onboarding</p></li><li><p>Maintain smooth communication &amp; documentation flow</p></li></ul><p>&#128640; <strong>Create &amp; Convert Leads</strong></p><ul><li><p>Build your client funnel &amp; master digital selling</p></li><li><p>Track, follow-up, and close with clarity</p></li></ul><p>&#129504; <strong>Respond Professionally</strong></p><ul><li><p>Craft polite, assertive, and empathetic messages</p></li></ul><p>&#128187; <strong>Freelancing Setup</strong></p><ul><li><p>Choose the right platforms (Fiverr, Upwork, LinkedIn)</p></li><li><p>Build your portfolio &amp; write professional proposals</p></li></ul><p>&#128172; <strong>Sell Use Cases Like a Pro</strong></p><ul><li><p>Present <strong>results</strong>, not just features &#8212; show real value</p></li></ul><div><hr></div><h2>&#127942; <strong>Program Highlights</strong></h2><p>&#9989; 100% Online &amp; Beginner Friendly<br>&#9989; Real-World Projects &amp; Portfolio Building<br>&#9989; Flexible Timings for Women<br>&#9989; Weekly Live Classes + Q&amp;A<br>&#9989; Peer Community + Personal Mentorship</p><div><hr></div><h2>&#128260; <strong>Program Flow</strong></h2><h3><strong>Phase 1: Learn &amp; Build Portfolio</strong></h3><p>Hands-on learning through guided projects and assignments</p><h3><strong>Phase 2: Evaluation</strong></h3><p>Submit practical work: designs, documents, videos, and responses</p><h3><strong>Phase 3: Work &amp; Earn</strong></h3><p>Qualified participants get paid opportunities &amp; project tasks &#128176;</p><div><hr></div><h2>&#127873; <strong>Bonuses Included</strong></h2><p>&#127912; Canva Pro Templates<br>&#128196; Resume &amp; Cover Letter Templates<br>&#128444;&#65039; LinkedIn Banner + Branding Kit<br>&#127891; Certificate of Completion<br>&#128105;&#8205;&#128172; Access to Private Women&#8217;s Community</p><div><hr></div><h2>&#128172; <strong>Tagline Options</strong></h2><p>&#10024; &#8220;Build Your Brand. Work from Anywhere.&#8221;<br>&#10024; &#8220;Digital Skills for Today&#8217;s Women.&#8221;<br>&#10024; &#8220;From Kitchen to Keyboard &#8212; Rewrite Your Story.&#8221;<br>&#10024; &#8220;Learn. Prove. Work. Earn.&#8221;</p>]]></content:encoded></item><item><title><![CDATA[From Linux Admin to Cyber Warrior: Master Red & Blue Team Operations]]></title><description><![CDATA[From Linux Admin to Cyber Defender: The Red vs Blue Team Simulation Bootcamp]]></description><link>https://careerbytecode.substack.com/p/from-linux-admin-to-cyber-defender-the-red-vs-blue-team-simulation-bootcamp</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/from-linux-admin-to-cyber-defender-the-red-vs-blue-team-simulation-bootcamp</guid><dc:creator><![CDATA[CareerByteCode]]></dc:creator><pubDate>Sun, 26 Oct 2025 21:41:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!6pp3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1dc701c-695e-4f8a-b4d3-e080b8782da2_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6pp3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1dc701c-695e-4f8a-b4d3-e080b8782da2_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6pp3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1dc701c-695e-4f8a-b4d3-e080b8782da2_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!6pp3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1dc701c-695e-4f8a-b4d3-e080b8782da2_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!6pp3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1dc701c-695e-4f8a-b4d3-e080b8782da2_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!6pp3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1dc701c-695e-4f8a-b4d3-e080b8782da2_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6pp3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1dc701c-695e-4f8a-b4d3-e080b8782da2_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c1dc701c-695e-4f8a-b4d3-e080b8782da2_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:402697,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/177201576?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1dc701c-695e-4f8a-b4d3-e080b8782da2_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6pp3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1dc701c-695e-4f8a-b4d3-e080b8782da2_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!6pp3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1dc701c-695e-4f8a-b4d3-e080b8782da2_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!6pp3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1dc701c-695e-4f8a-b4d3-e080b8782da2_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!6pp3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1dc701c-695e-4f8a-b4d3-e080b8782da2_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h1><strong>Red vs Blue Team Scenarios &amp; Simulated Attacks</strong></h1><h3><em>From Linux Administration to Cyber Defense Mastery</em></h3>
      <p>
          <a href="https://careerbytecode.substack.com/p/from-linux-admin-to-cyber-defender-the-red-vs-blue-team-simulation-bootcamp">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Hands-On Ethical Hacking & Cyber Defense for Linux Administrators]]></title><description><![CDATA[Practical Offensive & Defensive Linux: Build, Attack, Defend - A 12-Week Lab-First Course for Linux Admins]]></description><link>https://careerbytecode.substack.com/p/hands-on-ethical-hacking-cyber-defense-for-linux-administrators</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/hands-on-ethical-hacking-cyber-defense-for-linux-administrators</guid><dc:creator><![CDATA[CareerByteCode]]></dc:creator><pubDate>Thu, 23 Oct 2025 20:22:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!45H9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da01e47-9753-4598-8188-b059c8f6a347_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!45H9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da01e47-9753-4598-8188-b059c8f6a347_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!45H9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da01e47-9753-4598-8188-b059c8f6a347_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!45H9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da01e47-9753-4598-8188-b059c8f6a347_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!45H9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da01e47-9753-4598-8188-b059c8f6a347_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!45H9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da01e47-9753-4598-8188-b059c8f6a347_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!45H9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da01e47-9753-4598-8188-b059c8f6a347_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7da01e47-9753-4598-8188-b059c8f6a347_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:823591,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/176855773?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da01e47-9753-4598-8188-b059c8f6a347_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!45H9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da01e47-9753-4598-8188-b059c8f6a347_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!45H9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da01e47-9753-4598-8188-b059c8f6a347_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!45H9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da01e47-9753-4598-8188-b059c8f6a347_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!45H9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7da01e47-9753-4598-8188-b059c8f6a347_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h1><strong>Course Target Audience:</strong> </h1><p>Experienced Linux administrators who want a hands-on transition into cybersecurity (ethical hacking, web/app security, network security, hardening, incident response). Students will create their own lab environments (Azure VMs <em>and/or</em> local VMs), run safe offensive exercises against intentionally vulnerable systems, and implement &#8230;</p>
      <p>
          <a href="https://careerbytecode.substack.com/p/hands-on-ethical-hacking-cyber-defense-for-linux-administrators">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Zero to Hero in Generative AI — Build, Deploy & Scale LLM-Powered Apps]]></title><description><![CDATA[An immersive journey from AI concepts to production-grade applications.]]></description><link>https://careerbytecode.substack.com/p/zero-to-hero-in-generative-ai-build-deploy-scale-llm-powered-apps</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/zero-to-hero-in-generative-ai-build-deploy-scale-llm-powered-apps</guid><dc:creator><![CDATA[CareerByteCode]]></dc:creator><pubDate>Sun, 19 Oct 2025 11:08:25 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!XMlU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cbc129-f20e-4f56-9fab-b89659fefa0d_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XMlU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cbc129-f20e-4f56-9fab-b89659fefa0d_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XMlU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cbc129-f20e-4f56-9fab-b89659fefa0d_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!XMlU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cbc129-f20e-4f56-9fab-b89659fefa0d_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!XMlU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cbc129-f20e-4f56-9fab-b89659fefa0d_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!XMlU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cbc129-f20e-4f56-9fab-b89659fefa0d_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XMlU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cbc129-f20e-4f56-9fab-b89659fefa0d_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c7cbc129-f20e-4f56-9fab-b89659fefa0d_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:886057,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/176549287?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cbc129-f20e-4f56-9fab-b89659fefa0d_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XMlU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cbc129-f20e-4f56-9fab-b89659fefa0d_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!XMlU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cbc129-f20e-4f56-9fab-b89659fefa0d_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!XMlU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cbc129-f20e-4f56-9fab-b89659fefa0d_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!XMlU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7cbc129-f20e-4f56-9fab-b89659fefa0d_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h2>&#127775; <strong>Course Overview</strong></h2><p>This course is designed to help learners <strong>master Generative AI from the ground up</strong>, combining theory, real-world applications, and end-to-end projects.</p><p>You&#8217;ll start by understanding <strong>AI, Machine Learning, and Deep Learning fundamentals</strong>, then move into <strong>LLMs, LangChain, Hugging Face, Vector Databases</strong>, and <strong>AI-powered app deployment</strong>.</p><p>By the end&#8230;</p>
      <p>
          <a href="https://careerbytecode.substack.com/p/zero-to-hero-in-generative-ai-build-deploy-scale-llm-powered-apps">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[From Beginner to Pro: The Ultimate Linux System Administration Crash Course]]></title><description><![CDATA[Master Linux System Administration in 18 Weeks &#8212; From Zero to Real-Time Server Management]]></description><link>https://careerbytecode.substack.com/p/linux-administration-for-the-real-world-practical-skills-for-cloud-and-devops-engineers</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/linux-administration-for-the-real-world-practical-skills-for-cloud-and-devops-engineers</guid><dc:creator><![CDATA[CareerByteCode]]></dc:creator><pubDate>Sun, 12 Oct 2025 20:19:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!2myy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa3dc0e-be33-47e7-a67e-f441ab3a613a_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2myy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa3dc0e-be33-47e7-a67e-f441ab3a613a_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2myy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa3dc0e-be33-47e7-a67e-f441ab3a613a_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!2myy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa3dc0e-be33-47e7-a67e-f441ab3a613a_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!2myy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa3dc0e-be33-47e7-a67e-f441ab3a613a_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!2myy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa3dc0e-be33-47e7-a67e-f441ab3a613a_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2myy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa3dc0e-be33-47e7-a67e-f441ab3a613a_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eaa3dc0e-be33-47e7-a67e-f441ab3a613a_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:294440,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa3dc0e-be33-47e7-a67e-f441ab3a613a_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!2myy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa3dc0e-be33-47e7-a67e-f441ab3a613a_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!2myy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa3dc0e-be33-47e7-a67e-f441ab3a613a_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!2myy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa3dc0e-be33-47e7-a67e-f441ab3a613a_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!2myy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feaa3dc0e-be33-47e7-a67e-f441ab3a613a_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h3>&#128216; Course Overview</h3><p>This <strong>18-week Linux System Administration Crash Course</strong> is designed to transform beginners into confident system administrators capable of managing, automating, securing, and troubleshooting real-world Linux servers.</p><p>Students will gain <strong>hands-on experience</strong> with real Linux environments, mastering everything from basic shell commands to kernel tuning, system hardening, and automation scripting.<br>By the end of this course, students will be ready to perform system admin tasks in enterprise environments and prepare for Linux certification paths (RHCSA, LFCS, CompTIA Linux+).</p><div><hr></div><h2>&#128467;&#65039; <strong>Week-by-Week Syllabus</strong></h2><div><hr></div><h3><strong>Week 1 &#8211; Introduction to Linux</strong></h3><ul><li><p>History, architecture, and distributions (RHEL, Ubuntu, CentOS)</p></li><li><p>Understanding the Linux kernel, shell, and file system</p></li><li><p>The Linux boot process and system targets</p></li><li><p>Installing and exploring Linux environments<br>&#129504; <em>Outcome:</em> Understand how Linux works internally and interact with the shell confidently.</p></li></ul><div><hr></div><h3><strong>Week 2 &#8211; Linux File System &amp; Directory Structure</strong></h3><ul><li><p>Linux file hierarchy and directory roles</p></li><li><p>Navigating paths (absolute &amp; relative)</p></li><li><p>Mounting/unmounting partitions</p></li><li><p><code>/etc/fstab</code> and persistent mounts</p></li><li><p>File operations and management<br>&#129504; <em>Outcome:</em> Manage files, directories, and storage mounts effectively.</p></li></ul><div><hr></div><h3><strong>Week 3 &#8211; File Permissions and Ownership</strong></h3><ul><li><p>Understanding Linux permissions (rwx)</p></li><li><p>Using <code>chmod</code>, <code>chown</code>, and <code>chgrp</code></p></li><li><p>Special permissions (SUID, SGID, Sticky Bit)</p></li><li><p>Default permissions (<code>umask</code>)<br>&#129504; <em>Outcome:</em> Secure files using correct permission models.</p></li></ul><div><hr></div><h3><strong>Week 4 &#8211; Linux Command Line Essentials</strong></h3><ul><li><p>Viewing and filtering content (<code>cat</code>, <code>grep</code>, <code>awk</code>, <code>sed</code>)</p></li><li><p>Piping, redirection, and command chaining</p></li><li><p>Searching and text manipulation<br>&#129504; <em>Outcome:</em> Gain command-line mastery for daily admin tasks.</p></li></ul><div><hr></div><h3><strong>Week 5 &#8211; User and Group Administration</strong></h3><ul><li><p>Creating and managing users &amp; groups</p></li><li><p>Understanding <code>/etc/passwd</code>, <code>/etc/shadow</code></p></li><li><p>Configuring sudo permissions</p></li><li><p>Managing user profiles and shells<br>&#129504; <em>Outcome:</em> Handle user access and privilege control securely.</p></li></ul><div><hr></div><h3><strong>Week 6 &#8211; Process and Job Management</strong></h3><ul><li><p>Understanding processes and PIDs</p></li><li><p>Background/foreground jobs</p></li><li><p>Managing processes with <code>ps</code>, <code>top</code>, <code>kill</code></p></li><li><p>Scheduling tasks using <code>cron</code> and <code>at</code><br>&#129504; <em>Outcome:</em> Monitor and control system processes efficiently.</p></li></ul><div><hr></div><h3><strong>Week 7 &#8211; Software and Package Management</strong></h3><ul><li><p>Package managers: <code>apt</code>, <code>yum</code>, <code>dnf</code>, <code>rpm</code></p></li><li><p>Installing, updating, and removing software</p></li><li><p>Managing repositories</p></li><li><p>Compiling software from source<br>&#129504; <em>Outcome:</em> Install and maintain Linux software reliably.</p></li></ul><div><hr></div><h3><strong>Week 8 &#8211; Disk, Storage &amp; File System Management</strong></h3><ul><li><p>Disk partitioning (<code>lsblk</code>, <code>fdisk</code>)</p></li><li><p>Creating and mounting filesystems (<code>mkfs</code>, <code>mount</code>)</p></li><li><p>LVM concepts (PV, VG, LV)</p></li><li><p>Disk quotas and RAID fundamentals<br>&#129504; <em>Outcome:</em> Administer Linux storage safely and efficiently.</p></li></ul><div><hr></div><h3><strong>Week 9 &#8211; System Startup and Services</strong></h3><ul><li><p>Understanding <code>systemd</code> and init systems</p></li><li><p>Starting/stopping/enabling services</p></li><li><p>Boot targets and runlevels</p></li><li><p>Troubleshooting failed services<br>&#129504; <em>Outcome:</em> Manage service lifecycles and system boots confidently.</p></li></ul><div><hr></div><h3><strong>Week 10 &#8211; Networking in Linux</strong></h3><ul><li><p>Configuring IPs and DNS (<code>ip</code>, <code>nmcli</code>)</p></li><li><p>Testing connectivity (<code>ping</code>, <code>ss</code>, <code>traceroute</code>)</p></li><li><p>SSH configuration and key management</p></li><li><p>Basic web &amp; file transfers (HTTP, FTP, SCP)<br>&#129504; <em>Outcome:</em> Configure and troubleshoot Linux networking.</p></li></ul><div><hr></div><h3><strong>Week 11 &#8211; Logging and System Monitoring</strong></h3><ul><li><p>Linux log architecture and log files (<code>/var/log</code>)</p></li><li><p>Viewing logs (<code>journalctl</code>, <code>dmesg</code>)</p></li><li><p>Log rotation (<code>logrotate</code>)</p></li><li><p>Monitoring tools (<code>top</code>, <code>vmstat</code>, <code>iostat</code>)<br>&#129504; <em>Outcome:</em> Monitor performance and analyze system events effectively.</p></li></ul><div><hr></div><h3><strong>Week 12 &#8211; Backup and Recovery</strong></h3><ul><li><p>Backup strategies (full, incremental)</p></li><li><p>Using <code>tar</code>, <code>rsync</code>, <code>cron</code> for automation</p></li><li><p>Data restoration procedures</p></li><li><p>System rescue &amp; recovery modes<br>&#129504; <em>Outcome:</em> Design and execute reliable backup systems.</p></li></ul><div><hr></div><h3><strong>Week 13 &#8211; Linux Security and Hardening</strong></h3><ul><li><p>SSH hardening and key-based access</p></li><li><p>Sudo and least privilege principles</p></li><li><p>Firewalls (<code>ufw</code>, <code>firewalld</code>, <code>iptables</code>)</p></li><li><p>SELinux/AppArmor basics</p></li><li><p>Auditing system events (<code>auditd</code>)<br>&#129504; <em>Outcome:</em> Secure and harden Linux systems using best practices.</p></li></ul><div><hr></div><h3><strong>Week 14 &#8211; Performance Tuning and Troubleshooting</strong></h3><ul><li><p>Analyzing CPU, memory, and I/O bottlenecks</p></li><li><p>Using <code>vmstat</code>, <code>iostat</code>, and <code>free</code></p></li><li><p>Tuning kernel parameters (<code>sysctl</code>)</p></li><li><p>Swap and GRUB recovery<br>&#129504; <em>Outcome:</em> Diagnose and optimize system performance.</p></li></ul><div><hr></div><h3><strong>Week 15 &#8211; Bash Scripting &amp; Automation</strong></h3><ul><li><p>Writing shell scripts and using shebang</p></li><li><p>Variables, loops, conditionals, and functions</p></li><li><p>Debugging scripts (<code>set -x</code>)</p></li><li><p>Automating admin tasks (backups, cleanup)<br>&#129504; <em>Outcome:</em> Automate repetitive operations with Bash scripts.</p></li></ul><div><hr></div><h3><strong>Week 16 &#8211; Git for Linux Administrators</strong></h3><ul><li><p>Introduction to Git &amp; version control</p></li><li><p>Managing config files in Git</p></li><li><p>Branching, merging, and restoring files</p></li><li><p><code>.gitignore</code> and automated Git backups<br>&#129504; <em>Outcome:</em> Use Git to safely version and manage system configurations.</p></li></ul><div><hr></div><h3><strong>Week 17 &#8211; Advanced Linux Administration</strong></h3><ul><li><p>Kernel management and upgrades</p></li><li><p>GRUB customization (boot control)</p></li><li><p>System limits (<code>ulimit</code>, <code>/etc/security/limits.conf</code>)</p></li><li><p>Time sync (Chrony/NTP)</p></li><li><p>System tuning with <code>sysctl</code><br>&#129504; <em>Outcome:</em> Handle kernel-level and system tuning operations confidently.</p></li></ul><div><hr></div><h3><strong>Week 18 &#8211; Real-Time Administration Use Cases</strong></h3><ul><li><p>Server patching automation</p></li><li><p>Log cleanup and rotation scripts</p></li><li><p>User lifecycle and access management</p></li><li><p>Backup validation</p></li><li><p>Root Cause Analysis (RCA)<br>&#129504; <em>Outcome:</em> Apply all skills in real-world administrative workflows.</p></li></ul><div><hr></div><h2>&#129513; <strong>Learning Outcomes &#8211; What Students Will Learn</strong></h2><p>After completing this 18-week course, students will be able to:</p><p>&#9989; <strong>System Operation &amp; Management</strong></p><ul><li><p>Understand Linux architecture and command-line fundamentals</p></li><li><p>Manage file systems, storage, users, and services</p></li></ul><p>&#9989; <strong>Automation &amp; Optimization</strong></p><ul><li><p>Write Bash scripts for automation</p></li><li><p>Configure cron jobs for scheduled tasks</p></li><li><p>Tune performance parameters using sysctl and ulimit</p></li></ul><p>&#9989; <strong>Security &amp; Networking</strong></p><ul><li><p>Harden systems with SSH keys, firewalls, and SELinux</p></li><li><p>Secure user privileges and monitor access logs</p></li><li><p>Configure and troubleshoot network connectivity</p></li></ul><p>&#9989; <strong>Monitoring &amp; Recovery</strong></p><ul><li><p>Analyze system logs and troubleshoot issues</p></li><li><p>Perform backup, restore, and recovery operations</p></li><li><p>Identify root causes of downtime or performance degradation</p></li></ul><p>&#9989; <strong>Version Control &amp; Advanced Administration</strong></p><ul><li><p>Track configuration changes using Git</p></li><li><p>Manage kernel modules, GRUB, and system boot targets</p></li><li><p>Automate patching and routine maintenance</p></li></ul><div><hr></div><h2>&#127919; <strong>By the End of This Course, Students Will:</strong></h2><ul><li><p>Be confident to administer Linux servers independently.</p></li><li><p>Be able to manage production systems safely.</p></li><li><p>Automate daily sysadmin tasks using Bash scripting.</p></li><li><p>Troubleshoot, optimize, and secure enterprise-grade systems.</p></li><li><p>Be ready for <strong>RHCSA, LFCS, or Linux+</strong> certifications.</p></li></ul><div><hr></div><h2>&#129520; <strong>Tools and Technologies Covered</strong></h2><ul><li><p>Distributions: Ubuntu, CentOS, RHEL</p></li><li><p>Core Utilities: <code>bash</code>, <code>grep</code>, <code>awk</code>, <code>sed</code>, <code>vim</code></p></li><li><p>Service Managers: <code>systemd</code>, <code>cron</code>, <code>logrotate</code></p></li><li><p>Package Managers: <code>apt</code>, <code>yum</code>, <code>dnf</code>, <code>rpm</code></p></li><li><p>Network Tools: <code>ip</code>, <code>ss</code>, <code>nmcli</code>, <code>scp</code>, <code>ping</code></p></li><li><p>Security Tools: <code>ufw</code>, <code>firewalld</code>, <code>iptables</code>, <code>auditd</code></p></li><li><p>Performance Tools: <code>top</code>, <code>vmstat</code>, <code>iostat</code>, <code>free</code>, <code>df</code></p></li><li><p>Version Control: <code>git</code>, <code>.gitignore</code>, Git branches</p></li><li><p>Automation: <code>bash</code>, <code>cron</code>, <code>rsync</code>, <code>tar</code>, <code>sysctl</code></p></li></ul><div><hr></div><h2>&#129534; <strong>Certification of Completion</strong></h2><p>At the end of the 18-week program, participants will receive a<br><strong>&#8220;CareerByteCode Linux System Administrator&#8221;</strong> certificate<br>signifying mastery of foundational and real-world Linux administration skills.</p><div><hr></div><p></p><h2>Chapter 1 &#8212; Introduction to Linux (Week 1)</h2><p><strong>Objective (simple):</strong> Understand what Linux is, why people use different distributions, what the kernel and shell are, how the system boots at a high level, and how to peek around your installed Linux distribution.</p><p>I&#8217;ll start with <strong>Chapter 1</strong> (Week 1 &#8212; <em>Introduction to Linux</em>) exactly as you asked: </p><blockquote><p><strong>How to run these examples</strong></p><ul><li><p>Open a terminal on any Linux machine (Ubuntu/RHEL/CentOS VM is perfect).</p></li><li><p>I will use <code>/tmp/linux_course/week1</code> as a safe working folder so nothing system-critical is changed.</p></li><li><p>Copy/paste each code block into the terminal. Commands are safe and non-destructive. Some commands (like <code>dmesg</code>) might show different output on different systems &#8212; that&#8217;s fine.</p></li></ul></blockquote><div><hr></div><h2>1. What is Linux? &#8212; Layman explanation</h2><p>Imagine a car. The <strong>kernel</strong> is the engine it talks to the metal (hardware) and makes things move. The rest of the car (steering wheel, seats, radio) is the userland programs and tools you interact with. Linux is the <em>engine</em> (kernel) plus a huge group of people who build and share cars (distributions) with different seats and radios (apps, packaging, defaults).</p><p>A <strong>distribution</strong> (distro) is like a specific car model Ubuntu, RHEL, CentOS, Fedora, Debian all share the Linux <em>engine</em> but package different apps and support levels.</p><div><hr></div><h2>2. Linux architecture &#8212; simple mapping</h2><ul><li><p><strong>Kernel</strong>: engine &#8212; manages CPU, memory, devices.</p></li><li><p><strong>User space</strong>: everything outside kernel &#8212; shells, programs, GUI.</p></li><li><p><strong>Shell</strong>: the steering wheel the driver uses to control the car &#8212; <code>bash</code>, <code>zsh</code>.</p></li><li><p><strong>Init/system manager</strong>: car ignition system that starts everything &#8212; <code>systemd</code> or older <code>init</code>.</p></li><li><p><strong>File system</strong>: how you store things in the trunk and glovebox &#8212; <code>/etc</code>, <code>/usr</code>, <code>/var</code>, <code>/home</code>.</p></li></ul><div><hr></div><h2>3. Boot process overview &#8212; plain steps</h2><ol><li><p><strong>Power on &#8594; UEFI/BIOS</strong>: the basic electronics turn on and look for boot device.</p></li><li><p><strong>Bootloader (GRUB)</strong>: like the car key that chooses which engine/configuration to load.</p></li><li><p><strong>Kernel loads</strong>: kernel (engine) runs and mounts a temporary root.</p></li><li><p><strong>Init/system manager (systemd)</strong>: starts services (networking, display, etc.) and user sessions.</p></li><li><p><strong>Login prompt / graphical login</strong>: you sit in the driver seat and start using the system.</p></li></ol><div><hr></div><h2>4. Shell vs terminal</h2><ul><li><p><strong>Terminal</strong>: the vehicle&#8217;s dashboard screen (a program that shows text).</p></li><li><p><strong>Shell</strong>: the command interpreter that reads what you type and runs programs. Example shells: <code>bash</code>, <code>zsh</code>, <code>sh</code>.</p></li></ul><div><hr></div><h2>5. Checking distro and system facts (simple)</h2><p>Linux distributions keep an <code>/etc/os-release</code> file describing themselves. You can read that along with <code>uname</code> (kernel info).</p><div><hr></div><h2>Quick reference &#8212; commands table (copyable explanation)</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tXpX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3850ccf-bbad-4f0e-82ca-5b669edbdce4_630x292.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tXpX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3850ccf-bbad-4f0e-82ca-5b669edbdce4_630x292.png 424w, https://substackcdn.com/image/fetch/$s_!tXpX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3850ccf-bbad-4f0e-82ca-5b669edbdce4_630x292.png 848w, https://substackcdn.com/image/fetch/$s_!tXpX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3850ccf-bbad-4f0e-82ca-5b669edbdce4_630x292.png 1272w, https://substackcdn.com/image/fetch/$s_!tXpX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3850ccf-bbad-4f0e-82ca-5b669edbdce4_630x292.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tXpX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3850ccf-bbad-4f0e-82ca-5b669edbdce4_630x292.png" width="630" height="292" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c3850ccf-bbad-4f0e-82ca-5b669edbdce4_630x292.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:292,&quot;width&quot;:630,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:22863,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3850ccf-bbad-4f0e-82ca-5b669edbdce4_630x292.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tXpX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3850ccf-bbad-4f0e-82ca-5b669edbdce4_630x292.png 424w, https://substackcdn.com/image/fetch/$s_!tXpX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3850ccf-bbad-4f0e-82ca-5b669edbdce4_630x292.png 848w, https://substackcdn.com/image/fetch/$s_!tXpX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3850ccf-bbad-4f0e-82ca-5b669edbdce4_630x292.png 1272w, https://substackcdn.com/image/fetch/$s_!tXpX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc3850ccf-bbad-4f0e-82ca-5b669edbdce4_630x292.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>Make a working folder (run this first)</h2><pre><code><code># create working folder (safe)
mkdir -p /tmp/linux_course/week1
cd /tmp/linux_course/week1
pwd   # should show /tmp/linux_course/week1
</code></code></pre><div><hr></div><h2>Example 1 &#8212; Check kernel and distro info (copy-paste runnable)</h2><pre><code><code># Example 1: Check kernel &amp; distro info
echo &#8220;=== uname -a ===&#8221;
uname -a

echo
echo &#8220;=== /etc/os-release (if present) ===&#8221;
if [ -f /etc/os-release ]; then
  cat /etc/os-release
else
  echo &#8220;/etc/os-release not found on this system&#8221;
fi

echo
echo &#8220;=== sample output stored to file ===&#8221;
uname -a &gt; kernel_info.txt
cat kernel_info.txt
</code></code></pre><p><strong>What this does:</strong> shows the kernel version &amp; distro. The file <code>kernel_info.txt</code> will contain the kernel line.</p><div><hr></div><h2>Example 2 &#8212; Explore basic file system layout (create sample files &amp; table)</h2><p>We will create a tiny mock of the FHS in <code>/tmp/linux_course/week1/demo_fhs</code> to play with.</p><pre><code><code># Example 2: create small demo FHS structure (safe place)
BASE=/tmp/linux_course/week1/demo_fhs
rm -rf &#8220;$BASE&#8221;
mkdir -p &#8220;$BASE&#8221;/{etc,usr,bin,var,home,tmp}
echo &#8220;root config file&#8221; &gt; &#8220;$BASE/etc/passwd.example&#8221;
echo &#8220;system binary&#8221;  &gt; &#8220;$BASE/bin/hello.sh&#8221;
chmod +x &#8220;$BASE/bin/hello.sh&#8221;
cat &gt; &#8220;$BASE/bin/hello.sh&#8221; &lt;&lt;&#8217;EOF&#8217;
#!/bin/sh
echo &#8220;Hello from demo_fhs /bin/hello.sh&#8221;
EOF

# Show tree-like listing (without tree command)
echo &#8220;Contents of demo_fhs:&#8221;
ls -lR &#8220;$BASE&#8221; | sed -n &#8216;1,200p&#8217;

# Run the demo binary
&#8220;$BASE/bin/hello.sh&#8221;
</code></code></pre><p><strong>What this does:</strong> sets up an example filesystem tree you can inspect. This simulates <code>/etc</code>, <code>/bin</code>, etc., without touching system directories.</p><div><hr></div><h2>Example 3 &#8212; Shell basics: variables, simple script, environment</h2><pre><code><code># Example 3: shell basics
cat &gt; /tmp/linux_course/week1/var_demo.sh &lt;&lt;&#8217;SH&#8217;
#!/bin/bash
# A tiny script to show variables and environment use

MYNAME=&#8221;Student&#8221;
echo &#8220;Hello, $MYNAME. Today is $(date +%A).&#8221;

# export a variable
export COURSE=&#8221;Linux Basics&#8221;
echo &#8220;COURSE is set to: $COURSE&#8221;

# read input if available
if [ -t 0 ]; then
  echo &#8220;No piped input. (Run: echo &#8216;some text&#8217; | ./var_demo.sh )&#8221;
else
  echo &#8220;Piped input was:&#8221;
  cat -
fi
SH

chmod +x /tmp/linux_course/week1/var_demo.sh
# Run it normally
/tmp/linux_course/week1/var_demo.sh

# Run with piped input to test reading from STDIN:
echo &#8220;this is piped text&#8221; | /tmp/linux_course/week1/var_demo.sh
</code></code></pre><p><strong>What this does:</strong> shows variables, exporting, date expansion, and reading piped input.</p><div><hr></div><h2>Example 4 &#8212; Look at boot parameters &amp; simple explanation</h2><pre><code><code># Example 4: Boot parameters and dmesg sample (non-root safe)
echo &#8220;=== /proc/cmdline (kernel boot parameters) ===&#8221;
if [ -f /proc/cmdline ]; then
  cat /proc/cmdline
else
  echo &#8220;/proc/cmdline not available&#8221;
fi

echo
echo &#8220;=== first 20 kernel messages (dmesg may require root to see everything) ===&#8221;
dmesg | head -n 20 || true
</code></code></pre><p><strong>Note:</strong> <code>dmesg</code> sometimes requires root to see full kernel message buffer; normal users will still see many messages. This demonstrates how kernel communicates during boot.</p><div><hr></div><h2>Example 5 &#8212; Identify your shell and try simple shell commands</h2><pre><code><code># Example 5: shell identity and common commands
echo &#8220;Your current shell is: $SHELL&#8221;
echo &#8220;Which shells exist on this system (show /etc/shells):&#8221;
if [ -f /etc/shells ]; then
  cat /etc/shells
else
  echo &#8220;/etc/shells not present&#8221;
fi

# Try simple commands: list root &amp; home (non-destructive)
echo
echo &#8220;--- ls / ---&#8221;
ls -l / | sed -n &#8216;1,50p&#8217;

echo
echo &#8220;--- ls ~ (your home) ---&#8221;
ls -la ~ | sed -n &#8216;1,50p&#8217;
</code></code></pre><div><hr></div><h2>Example 6 &#8212; Check which package manager exists (shows distro family)</h2><pre><code><code># Example 6: check package manager (non-destructive)
echo &#8220;Checking package manager presence...&#8221;
for cmd in apt dnf yum rpm dpkg zypper pacman; do
  which $cmd &gt;/dev/null 2&gt;&amp;1 &amp;&amp; echo &#8220;Found: $cmd&#8221; || true
done

# Also show /etc/os-release again to correlate
echo
echo &#8220;If apt found &#8594; Debian/Ubuntu family; if yum/dnf/rpm found &#8594; RHEL/CentOS family&#8221;
cat /etc/os-release 2&gt;/dev/null || true
</code></code></pre><div><hr></div><h2>Example 7 &#8212; Create a small &#8220;cheat sheet&#8221; CSV table to practice reading files</h2><pre><code><code># Example 7: create a CSV with basic command cheats and show it
cat &gt; /tmp/linux_course/week1/cheats.csv &lt;&lt;&#8217;CSV&#8217;
Command,Description,Example
uname -a,Show kernel info,uname -a
cat /etc/os-release,Show distro info,cat /etc/os-release
ls -la,List files with details,ls -la /tmp
echo $SHELL,Show current shell,echo $SHELL
dmesg | head,Show kernel messages,dmesg | head -n 5
CSV

echo &#8220;Cheat sheet created at /tmp/linux_course/week1/cheats.csv&#8221;
column -s, -t /tmp/linux_course/week1/cheats.csv || cat /tmp/linux_course/week1/cheats.csv
</code></code></pre><p><code>column</code> beautifies the CSV into a table; if <code>column</code> isn&#8217;t present, the CSV is still readable via <code>cat</code>.</p><div><hr></div><h2>Minimal Troubleshooting tips (layman)</h2><ul><li><p>If a command says &#8220;permission denied&#8221;, it usually means you tried to touch a system file &#8212; use your personal folder like <code>/tmp</code> or your home folder.</p></li><li><p>If a command is &#8220;command not found&#8221;, your distro may not have that tool installed yet &#8212; e.g., <code>tree</code> or <code>column</code> may be missing. Use <code>apt install tree</code> on Ubuntu or <code>yum install tree</code> on RHEL if you want them (requires root).</p></li><li><p>If <code>dmesg</code> shows nothing as non-root, try <code>sudo dmesg</code> (some distros restrict kernel log access).</p></li></ul><div><hr></div><h2>10 Hands-On Exercises (step by step &#8212; one at a time)</h2><p>Do these in <code>/tmp/linux_course/week1</code> (I&#8217;ve already created it).</p><ol><li><p><strong>Create the course folder</strong> &#8212; run:</p></li></ol><pre><code><code>mkdir -p /tmp/linux_course/week1/mywork
cd /tmp/linux_course/week1/mywork
pwd
</code></code></pre><ol><li><p><em>Goal:</em> ensure you&#8217;re inside the course folder.</p></li><li><p><strong>Read distro file</strong> &#8212; show the distro name:</p></li></ol><pre><code><code>cat /etc/os-release
</code></code></pre><ol><li><p><em>Write down the NAME and VERSION fields.</em></p></li><li><p><strong>Create a personal README</strong> &#8212; create a file <code>README.md</code> with your name, distro, and date:</p></li></ol><pre><code><code>cat &gt; README.md &lt;&lt;&#8217;MD&#8217;
# Week1 - My Intro
Name: &lt;Your Name&gt;
Distro:
Date:
MD

# then open it to edit using nano/vim or echo commands to fill fields.
sed -n &#8216;1,200p&#8217; README.md
</code></code></pre><ol><li><p><strong>Show kernel info &amp; save</strong>:</p></li></ol><pre><code><code>uname -a &gt; my_kernel.txt
cat my_kernel.txt
</code></code></pre><ol><li><p><strong>Make a small script</strong> &#8212; create <code>hello_name.sh</code> that prompts for your name and says hi:</p></li></ol><pre><code><code>cat &gt; hello_name.sh &lt;&lt;&#8217;SH&#8217;
#!/bin/bash
read -p &#8220;What&#8217;s your name? &#8220; n
echo &#8220;Hello, $n &#8212; welcome to Linux Week 1!&#8221;
SH
chmod +x hello_name.sh
./hello_name.sh
</code></code></pre><ol><li><p><strong>Simulate FHS</strong> &#8212; create directories <code>/tmp/linux_course/week1/demo2/{etc,bin,home}</code> and add sample files; list them.</p></li><li><p><strong>Inspect boot cmdline</strong> &#8212; run:</p></li></ol><pre><code><code>cat /proc/cmdline
</code></code></pre><ol><li><p><em>Note what parameters are present.</em></p></li><li><p><strong>Check available shells</strong> &#8212; run:</p></li></ol><pre><code><code>cat /etc/shells
echo &#8220;Your shell is: $SHELL&#8221;
</code></code></pre><ol><li><p><strong>Create a cheat CSV and show as table</strong>:</p></li></ol><pre><code><code>cp /tmp/linux_course/week1/cheats.csv ./my_cheats.csv
column -s, -t my_cheats.csv || cat my_cheats.csv
</code></code></pre><ol><li><p><strong>Document everything</strong> &#8212; zip your work:</p></li></ol><pre><code><code>cd /tmp/linux_course/week1
tar czvf week1_submission.tar.gz mywork demo_fhs cheats.csv kernel_info.txt README.md
ls -l week1_submission.tar.gz
</code></code></pre><p>Each exercise is deliberately non-destructive and runs in <code>/tmp</code>.</p><div><hr></div><h2>10 Assessment Questions (mix of theory &amp; short practical)</h2><p>Answer these in short sentences or run the commands where applicable.</p><ol><li><p>What is the Linux kernel in one or two sentences?</p></li><li><p>Name three popular Linux distributions and one distinguishing feature of each.</p></li><li><p>What is the difference between a shell and a terminal?</p></li><li><p>Explain the high-level boot steps from power-on to login.</p></li><li><p>What file usually contains human-readable distro information (name &amp; version)? Show the command to read it.</p></li><li><p>What command shows you the kernel version and architecture?</p></li><li><p>How would you check which shell you are using right now (give the command)?</p></li><li><p>What is <code>/proc/cmdline</code> and why is it useful?</p></li><li><p>Create a tiny shell script that prints &#8220;I love Linux&#8221; and explain how to make it executable and run it. (Practical)</p></li><li><p>Why is it safer to do practice in <code>/tmp</code> or in a VM when learning Linux?</p></li></ol><div><hr></div><h1>Chapter 2 &#8211; Linux File System &amp; Directory Structure</h1><p><strong>Week 2 Objective:</strong><br>Understand how the <strong>Linux filesystem</strong> is organized, what each directory means, how to move around, what &#8220;mounting&#8221; is, and how the system remembers attached drives using <code>/etc/fstab</code>.</p><div><hr></div><h2>&#129504; 1. Layman&#8217;s Explanation &#8212; &#8220;The Library Analogy&#8221;</h2><p>Think of a <strong>Linux system like a huge library</strong>:</p><ul><li><p>The <strong>root (</strong><code>/</code><strong>)</strong> is the <strong>main entrance</strong> of the library.</p></li><li><p>Every <strong>section</strong> (like <code>/home</code>, <code>/etc</code>, <code>/usr</code>) is a <strong>different room</strong> holding different types of materials.</p></li><li><p>Each <strong>book</strong> is a <strong>file</strong>, and each <strong>bookshelf</strong> is a <strong>directory</strong> (folder).</p></li><li><p>A <strong>path</strong> (like <code>/home/student/documents/note.txt</code>) is like saying<br>&#8220;Go to the library &#8594; Home Room &#8594; Student shelf &#8594; Documents &#8594; note.txt book.&#8221;</p></li></ul><div><hr></div><h2>&#129513; 2. The Linux Filesystem Hierarchy &#8212; Common Directories</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Pe7p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c0196db-45e1-450f-8b0b-e2f671d6cd62_630x461.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Pe7p!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c0196db-45e1-450f-8b0b-e2f671d6cd62_630x461.png 424w, https://substackcdn.com/image/fetch/$s_!Pe7p!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c0196db-45e1-450f-8b0b-e2f671d6cd62_630x461.png 848w, https://substackcdn.com/image/fetch/$s_!Pe7p!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c0196db-45e1-450f-8b0b-e2f671d6cd62_630x461.png 1272w, https://substackcdn.com/image/fetch/$s_!Pe7p!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c0196db-45e1-450f-8b0b-e2f671d6cd62_630x461.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Pe7p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c0196db-45e1-450f-8b0b-e2f671d6cd62_630x461.png" width="630" height="461" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8c0196db-45e1-450f-8b0b-e2f671d6cd62_630x461.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:461,&quot;width&quot;:630,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:40210,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c0196db-45e1-450f-8b0b-e2f671d6cd62_630x461.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Pe7p!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c0196db-45e1-450f-8b0b-e2f671d6cd62_630x461.png 424w, https://substackcdn.com/image/fetch/$s_!Pe7p!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c0196db-45e1-450f-8b0b-e2f671d6cd62_630x461.png 848w, https://substackcdn.com/image/fetch/$s_!Pe7p!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c0196db-45e1-450f-8b0b-e2f671d6cd62_630x461.png 1272w, https://substackcdn.com/image/fetch/$s_!Pe7p!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c0196db-45e1-450f-8b0b-e2f671d6cd62_630x461.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129517; 3. Absolute vs Relative Paths (simple analogy)</h2><ul><li><p><strong>Absolute path</strong> = full address from the root.<br>&#128073; Example: <code>/home/student/project/script.sh</code></p></li><li><p><strong>Relative path</strong> = shortcut from <em>where you currently are</em>.<br>&#128073; If you&#8217;re already in <code>/home/student</code>, then <code>project/script.sh</code> works fine.</p></li></ul><p>Try this with <code>pwd</code> (print working directory) to know <em>where you are</em>.</p><div><hr></div><h2>&#129521; 4. Mounting (what it means)</h2><p>In Windows, each drive gets a letter (C:, D:).<br>In Linux, <strong>everything joins one big tree</strong>. When you &#8220;mount&#8221; a drive, it&#8217;s like saying:</p><blockquote><p>&#8220;Take this new storage device and hang it inside the big tree at this folder path.&#8221;</p></blockquote><p>When you &#8220;unmount&#8221;, you remove it from that tree &#8212; but data stays safe on the drive.</p><div><hr></div><h2>&#128450;&#65039; 5. <code>/etc/fstab</code> (what it does)</h2><p><code>/etc/fstab</code> is a <strong>memory book</strong> for Linux &#8212; it lists which drives or partitions should be mounted automatically every time the system starts.</p><p>Example line:</p><pre><code><code>UUID=1234-ABCD  /data  ext4  defaults  0  2
</code></code></pre><p>Meaning: &#8220;Mount the drive with UUID 1234-ABCD to <code>/data</code> using the ext4 filesystem with default options.&#8221;</p><div><hr></div><h2>&#129520; Key Commands Table (you can run them safely)</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Gteu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07846f7b-5a00-4194-90fa-1eb693cb3af0_620x409.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Gteu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07846f7b-5a00-4194-90fa-1eb693cb3af0_620x409.png 424w, https://substackcdn.com/image/fetch/$s_!Gteu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07846f7b-5a00-4194-90fa-1eb693cb3af0_620x409.png 848w, https://substackcdn.com/image/fetch/$s_!Gteu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07846f7b-5a00-4194-90fa-1eb693cb3af0_620x409.png 1272w, https://substackcdn.com/image/fetch/$s_!Gteu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07846f7b-5a00-4194-90fa-1eb693cb3af0_620x409.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Gteu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07846f7b-5a00-4194-90fa-1eb693cb3af0_620x409.png" width="620" height="409" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/07846f7b-5a00-4194-90fa-1eb693cb3af0_620x409.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:409,&quot;width&quot;:620,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:32262,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07846f7b-5a00-4194-90fa-1eb693cb3af0_620x409.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Gteu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07846f7b-5a00-4194-90fa-1eb693cb3af0_620x409.png 424w, https://substackcdn.com/image/fetch/$s_!Gteu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07846f7b-5a00-4194-90fa-1eb693cb3af0_620x409.png 848w, https://substackcdn.com/image/fetch/$s_!Gteu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07846f7b-5a00-4194-90fa-1eb693cb3af0_620x409.png 1272w, https://substackcdn.com/image/fetch/$s_!Gteu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07846f7b-5a00-4194-90fa-1eb693cb3af0_620x409.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#9881;&#65039; Example 1 &#8212; Create a Demo File System Tree</h2><pre><code><code># Create a safe workspace
mkdir -p /tmp/linux_course/week2/demo_fs/{etc,usr,bin,home,log,tmp}
echo &#8220;User data file&#8221; &gt; /tmp/linux_course/week2/demo_fs/home/user.txt
echo &#8220;Configuration sample&#8221; &gt; /tmp/linux_course/week2/demo_fs/etc/config.conf
echo &#8220;Binary placeholder&#8221; &gt; /tmp/linux_course/week2/demo_fs/bin/runapp
chmod +x /tmp/linux_course/week2/demo_fs/bin/runapp

# List the created structure
echo &#8220;=== Demo File System ===&#8221;
ls -lR /tmp/linux_course/week2/demo_fs
</code></code></pre><p><strong>Explanation:</strong><br>This mock tree simulates a Linux system but is safe to explore under <code>/tmp</code>.</p><div><hr></div><h2>&#9881;&#65039; Example 2 &#8212; Practice Navigating Paths</h2><pre><code><code>cd /tmp/linux_course/week2/demo_fs
pwd
ls

# Absolute path
cat /tmp/linux_course/week2/demo_fs/etc/config.conf

# Relative path
cd home
cat user.txt
cd ..
pwd
</code></code></pre><p><strong>Concept:</strong><br>Absolute uses <code>/</code> from the start; relative starts from where you are.</p><div><hr></div><h2>&#9881;&#65039; Example 3 &#8212; Symbolic Links (shortcuts)</h2><pre><code><code>cd /tmp/linux_course/week2/demo_fs
ln -s home/user.txt user_link
ls -l user_link
cat user_link
</code></code></pre><p><strong>Explanation:</strong><br><code>ln -s</code> creates a <strong>symbolic link</strong> &#8212; like a shortcut or alias to another file.</p><div><hr></div><h2>&#9881;&#65039; Example 4 &#8212; Create and Mount a Dummy File System (Loopback Mount)</h2><p><em>(no USB needed &#8212; safe virtual test)</em></p><pre><code><code># Create a 20MB dummy file
mkdir -p /tmp/linux_course/week2
cd /tmp/linux_course/week2
dd if=/dev/zero of=mydisk.img bs=1M count=20

# Create an ext4 filesystem inside it
mkfs.ext4 mydisk.img

# Create a mount point and mount it
mkdir -p /tmp/linux_course/week2/mnt_disk
sudo mount -o loop mydisk.img /tmp/linux_course/week2/mnt_disk

# Verify mount
df -h /tmp/linux_course/week2/mnt_disk

# Write a file inside the mounted disk
echo &#8220;Data inside mounted disk&#8221; | sudo tee /tmp/linux_course/week2/mnt_disk/test.txt

# Unmount
sudo umount /tmp/linux_course/week2/mnt_disk
</code></code></pre><p><strong>Explanation:</strong><br>You created a fake disk file, formatted it, mounted it, wrote data, and unmounted it &#8212; all in <code>/tmp</code>.</p><div><hr></div><h2>&#9881;&#65039; Example 5 &#8212; View and Understand <code>/etc/fstab</code> (Read-Only)</h2><pre><code><code># Display only non-comment lines
grep -v &#8216;^#&#8217; /etc/fstab | column -t
</code></code></pre><p><strong>Explanation:</strong><br>Shows which drives are configured to mount at boot. (Don&#8217;t edit this file as a beginner!)</p><div><hr></div><h2>&#129513; Mini Data Table for Understanding <code>df -h</code> Output</h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xGOR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda40d797-4939-45b9-8113-2ac8c790c2a5_669x154.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xGOR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda40d797-4939-45b9-8113-2ac8c790c2a5_669x154.png 424w, https://substackcdn.com/image/fetch/$s_!xGOR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda40d797-4939-45b9-8113-2ac8c790c2a5_669x154.png 848w, https://substackcdn.com/image/fetch/$s_!xGOR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda40d797-4939-45b9-8113-2ac8c790c2a5_669x154.png 1272w, https://substackcdn.com/image/fetch/$s_!xGOR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda40d797-4939-45b9-8113-2ac8c790c2a5_669x154.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xGOR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda40d797-4939-45b9-8113-2ac8c790c2a5_669x154.png" width="669" height="154" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/da40d797-4939-45b9-8113-2ac8c790c2a5_669x154.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:154,&quot;width&quot;:669,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:11115,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda40d797-4939-45b9-8113-2ac8c790c2a5_669x154.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xGOR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda40d797-4939-45b9-8113-2ac8c790c2a5_669x154.png 424w, https://substackcdn.com/image/fetch/$s_!xGOR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda40d797-4939-45b9-8113-2ac8c790c2a5_669x154.png 848w, https://substackcdn.com/image/fetch/$s_!xGOR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda40d797-4939-45b9-8113-2ac8c790c2a5_669x154.png 1272w, https://substackcdn.com/image/fetch/$s_!xGOR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda40d797-4939-45b9-8113-2ac8c790c2a5_669x154.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><p>This is what <code>df -h</code> typically prints &#8212; showing drives and their mount points.</p><div><hr></div><h2>&#129504; 10 Hands-On Exercises (Safe to Try)</h2><ol><li><p>Create a folder <code>/tmp/linux_course/week2/work</code> and move into it.</p></li><li><p>Create 3 directories: <code>config</code>, <code>data</code>, and <code>scripts</code>.</p></li><li><p>Inside <code>data</code>, create 2 files: <code>file1.txt</code>, <code>file2.txt</code> with any text.</p></li><li><p>Copy both files to the <code>config</code> folder using one <code>cp</code> command.</p></li><li><p>Move <code>file2.txt</code> from <code>config</code> to <code>scripts</code> using <code>mv</code>.</p></li><li><p>Create a symbolic link named <code>latest.txt</code> in <code>work/</code> pointing to <code>data/file1.txt</code>.</p></li><li><p>Run <code>ls -l</code> to confirm link points correctly.</p></li><li><p>Run <code>df -h</code> and note which filesystem your <code>/tmp</code> belongs to.</p></li><li><p>View the contents of <code>/etc/fstab</code> and identify your <code>/</code> line.</p></li><li><p>Write a small script named <code>showpath.sh</code> that prints:</p></li></ol><pre><code><code>#!/bin/bash
echo &#8220;You are in $(pwd)&#8221;
echo &#8220;Listing files:&#8221;
ls -l
</code></code></pre><ol><li><p>Then <code>chmod +x showpath.sh</code> and run it.</p></li></ol><div><hr></div><h2>&#129518; 10 Assessment Questions</h2><ol><li><p>In Linux, what symbol represents the root directory?</p></li><li><p>What is the difference between <code>/home</code> and <code>/etc</code> directories?</p></li><li><p>Explain &#8220;absolute path&#8221; vs &#8220;relative path&#8221; with an example.</p></li><li><p>What is mounting in Linux? How is it different from drive letters in Windows?</p></li><li><p>What does <code>/etc/fstab</code> contain?</p></li><li><p>What command shows how much disk space is available on each mounted filesystem?</p></li><li><p>If you run <code>cd ..</code>, what happens?</p></li><li><p>What is the difference between <code>ln</code> and <code>ln -s</code>?</p></li><li><p>How can you check which drives are currently mounted?</p></li><li><p>What happens when you unmount a disk?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 2 Summary:</strong><br>You learned:</p><ul><li><p>The directory structure of Linux (FHS).</p></li><li><p>The difference between absolute and relative paths.</p></li><li><p>What mounting means and how <code>/etc/fstab</code> automates it.</p></li><li><p>Practical file navigation commands and mount simulations.</p></li></ul><div><hr></div><h1>Chapter 3 &#8211; File Permissions and Ownership</h1><p><strong>Week 3 Objective:</strong><br>Understand how Linux controls <strong>who can access what</strong>, how to use commands like <code>chmod</code>, <code>chown</code>, <code>chgrp</code>, and how special permissions (SUID, SGID, Sticky Bit) work.</p><div><hr></div><h2>&#129504; 1. Layman&#8217;s Explanation &#8212; &#8220;The House Analogy&#8221;</h2><p>Think of a <strong>Linux system as a big apartment building</strong>:</p><ul><li><p>Each <strong>file</strong> is like a <strong>room</strong>.</p></li><li><p>Every room has:</p><ul><li><p><strong>Owner</strong> &#8212; the person who lives there.</p></li><li><p><strong>Group</strong> &#8212; friends/family allowed to enter.</p></li><li><p><strong>Others</strong> &#8212; everyone else in the building.</p></li></ul></li><li><p>The <strong>door permissions</strong> decide who can <strong>read</strong>, <strong>write</strong>, or <strong>execute</strong> (enter) the room.</p></li></ul><p>So Linux uses 3 types of permissions for 3 types of people:</p><pre><code><code>r = Read
w = Write
x = Execute

u = User (owner)
g = Group
o = Others
</code></code></pre><div><hr></div><h2>&#129513; 2. Permission Format</h2><p>When you run <code>ls -l</code>, you&#8217;ll see something like this:</p><pre><code><code>-rwxr-xr--
</code></code></pre><p>Let&#8217;s decode:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!r643!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8fbfb3d-3625-45b6-9783-080ce6a03c9d_606x208.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!r643!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8fbfb3d-3625-45b6-9783-080ce6a03c9d_606x208.png 424w, https://substackcdn.com/image/fetch/$s_!r643!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8fbfb3d-3625-45b6-9783-080ce6a03c9d_606x208.png 848w, https://substackcdn.com/image/fetch/$s_!r643!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8fbfb3d-3625-45b6-9783-080ce6a03c9d_606x208.png 1272w, https://substackcdn.com/image/fetch/$s_!r643!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8fbfb3d-3625-45b6-9783-080ce6a03c9d_606x208.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!r643!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8fbfb3d-3625-45b6-9783-080ce6a03c9d_606x208.png" width="606" height="208" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c8fbfb3d-3625-45b6-9783-080ce6a03c9d_606x208.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:208,&quot;width&quot;:606,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:15030,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8fbfb3d-3625-45b6-9783-080ce6a03c9d_606x208.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!r643!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8fbfb3d-3625-45b6-9783-080ce6a03c9d_606x208.png 424w, https://substackcdn.com/image/fetch/$s_!r643!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8fbfb3d-3625-45b6-9783-080ce6a03c9d_606x208.png 848w, https://substackcdn.com/image/fetch/$s_!r643!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8fbfb3d-3625-45b6-9783-080ce6a03c9d_606x208.png 1272w, https://substackcdn.com/image/fetch/$s_!r643!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8fbfb3d-3625-45b6-9783-080ce6a03c9d_606x208.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129518; 3. Numeric Representation (Octal Mode)</h2><p>Each permission has a numeric value:</p><p>Permission Value Read (r) 4 Write (w) 2 Execute (x) 1</p><p>Example:</p><ul><li><p><code>rwx</code> = 4+2+1 = 7</p></li><li><p><code>rw-</code> = 4+2 = 6</p></li><li><p><code>r--</code> = 4 = 4</p></li></ul><p>So <code>chmod 755 file</code> means:</p><pre><code><code>7 (rwx) for user
5 (r-x) for group
5 (r-x) for others
</code></code></pre><div><hr></div><h2>&#129520; 4. Ownership and Groups</h2><p>Every file belongs to:</p><ul><li><p>A <strong>user (owner)</strong></p></li><li><p>A <strong>group</strong></p></li></ul><p>Commands:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WbuZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f7c420-c094-4379-857b-e58015c7f588_613x167.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WbuZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f7c420-c094-4379-857b-e58015c7f588_613x167.png 424w, https://substackcdn.com/image/fetch/$s_!WbuZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f7c420-c094-4379-857b-e58015c7f588_613x167.png 848w, https://substackcdn.com/image/fetch/$s_!WbuZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f7c420-c094-4379-857b-e58015c7f588_613x167.png 1272w, https://substackcdn.com/image/fetch/$s_!WbuZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f7c420-c094-4379-857b-e58015c7f588_613x167.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WbuZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f7c420-c094-4379-857b-e58015c7f588_613x167.png" width="613" height="167" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/74f7c420-c094-4379-857b-e58015c7f588_613x167.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:167,&quot;width&quot;:613,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:12718,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f7c420-c094-4379-857b-e58015c7f588_613x167.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!WbuZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f7c420-c094-4379-857b-e58015c7f588_613x167.png 424w, https://substackcdn.com/image/fetch/$s_!WbuZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f7c420-c094-4379-857b-e58015c7f588_613x167.png 848w, https://substackcdn.com/image/fetch/$s_!WbuZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f7c420-c094-4379-857b-e58015c7f588_613x167.png 1272w, https://substackcdn.com/image/fetch/$s_!WbuZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74f7c420-c094-4379-857b-e58015c7f588_613x167.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129527; 5. Special Permissions (SUID, SGID, Sticky Bit)</h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iT_m!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133d6429-2a7c-4fac-8dc7-7878a315e595_669x151.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iT_m!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133d6429-2a7c-4fac-8dc7-7878a315e595_669x151.png 424w, https://substackcdn.com/image/fetch/$s_!iT_m!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133d6429-2a7c-4fac-8dc7-7878a315e595_669x151.png 848w, https://substackcdn.com/image/fetch/$s_!iT_m!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133d6429-2a7c-4fac-8dc7-7878a315e595_669x151.png 1272w, https://substackcdn.com/image/fetch/$s_!iT_m!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133d6429-2a7c-4fac-8dc7-7878a315e595_669x151.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iT_m!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133d6429-2a7c-4fac-8dc7-7878a315e595_669x151.png" width="669" height="151" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/133d6429-2a7c-4fac-8dc7-7878a315e595_669x151.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:151,&quot;width&quot;:669,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:15306,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133d6429-2a7c-4fac-8dc7-7878a315e595_669x151.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iT_m!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133d6429-2a7c-4fac-8dc7-7878a315e595_669x151.png 424w, https://substackcdn.com/image/fetch/$s_!iT_m!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133d6429-2a7c-4fac-8dc7-7878a315e595_669x151.png 848w, https://substackcdn.com/image/fetch/$s_!iT_m!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133d6429-2a7c-4fac-8dc7-7878a315e595_669x151.png 1272w, https://substackcdn.com/image/fetch/$s_!iT_m!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F133d6429-2a7c-4fac-8dc7-7878a315e595_669x151.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><p>You&#8217;ll often see:</p><pre><code><code>-rwsr-xr-x   (SUID)
drwxr-sr-x   (SGID)
drwxrwxrwt   (Sticky)
</code></code></pre><div><hr></div><h2>&#129514; Example Environment Setup</h2><pre><code><code># Create safe working area
mkdir -p /tmp/linux_course/week3
cd /tmp/linux_course/week3

# Create some demo users and groups (simulation only)
echo &#8220;Simulating user and group environment...&#8221;
# These won&#8217;t actually add real users without root &#8212; simulation only
mkdir users
touch users/alice.txt users/bob.txt users/shared.txt

# Make them all readable
chmod 644 users/*.txt
ls -l users
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8212; Viewing Permissions</h2><pre><code><code>cd /tmp/linux_course/week3/users
ls -l
</code></code></pre><p>Output looks like:</p><pre><code><code>-rw-r--r-- 1 student student 0 Oct 12 19:30 alice.txt
-rw-r--r-- 1 student student 0 Oct 12 19:30 bob.txt
-rw-r--r-- 1 student student 0 Oct 12 19:30 shared.txt
</code></code></pre><p>Meaning:</p><ul><li><p>User can read/write.</p></li><li><p>Group and others can only read.</p></li></ul><div><hr></div><h2>&#9881;&#65039; Example 2 &#8212; Changing Permissions with <code>chmod</code></h2><pre><code><code># Add execute permission for the owner only
chmod u+x alice.txt
ls -l alice.txt

# Remove read permission for others
chmod o-r bob.txt
ls -l bob.txt

# Give full permissions to everyone (777)
chmod 777 shared.txt
ls -l shared.txt
</code></code></pre><p>&#9989; Try numeric style:</p><pre><code><code>chmod 644 alice.txt   # rw-r--r--
chmod 755 shared.txt  # rwxr-xr-x
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 3 &#8212; Change Ownership with <code>chown</code> and <code>chgrp</code></h2><pre><code><code># Simulate changing ownership
touch demo1.txt
sudo chown root demo1.txt
ls -l demo1.txt

# Change both user and group
sudo chown root:root demo1.txt
ls -l demo1.txt
</code></code></pre><p>&#128161; If you don&#8217;t have <code>sudo</code>, just note the syntax &#8212; it needs admin rights.</p><div><hr></div><h2>&#9881;&#65039; Example 4 &#8212; umask (default permission template)</h2><pre><code><code>umask   # Show current value

# Example: create file and directory
touch fileA
mkdir dirA
ls -l fileA dirA
</code></code></pre><p>Typical default umask = <code>0022</code>, meaning:</p><ul><li><p>New files get <code>rw-r--r--</code></p></li><li><p>New dirs get <code>rwxr-xr-x</code></p></li></ul><p>You can test by changing umask:</p><pre><code><code>umask 0077
touch fileB
ls -l fileB
</code></code></pre><p>Now only the owner has access.</p><div><hr></div><h2>&#9881;&#65039; Example 5 &#8212; Special Permissions (SUID, SGID, Sticky)</h2><pre><code><code># Create demo scripts
cd /tmp/linux_course/week3
echo -e &#8216;#!/bin/bash\necho &#8220;Running as $(whoami)&#8221;&#8217; &gt; suid_demo.sh
chmod 755 suid_demo.sh

# Set SUID bit (on script - demonstration)
chmod u+s suid_demo.sh
ls -l suid_demo.sh
</code></code></pre><p>Notice the &#8220;s&#8221; instead of &#8220;x&#8221; on the user permission column.</p><p>&#9989; SGID and Sticky examples:</p><pre><code><code># SGID
mkdir groupdir
chmod 2775 groupdir
ls -ld groupdir

# Sticky bit
mkdir stickydir
chmod 1777 stickydir
ls -ld stickydir
</code></code></pre><div><hr></div><h2>&#129521; Example Permission Table</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!m4P1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50a50c4c-4ecf-44b9-8b2a-116a351a6fda_597x246.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!m4P1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50a50c4c-4ecf-44b9-8b2a-116a351a6fda_597x246.png 424w, https://substackcdn.com/image/fetch/$s_!m4P1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50a50c4c-4ecf-44b9-8b2a-116a351a6fda_597x246.png 848w, https://substackcdn.com/image/fetch/$s_!m4P1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50a50c4c-4ecf-44b9-8b2a-116a351a6fda_597x246.png 1272w, https://substackcdn.com/image/fetch/$s_!m4P1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50a50c4c-4ecf-44b9-8b2a-116a351a6fda_597x246.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!m4P1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50a50c4c-4ecf-44b9-8b2a-116a351a6fda_597x246.png" width="597" height="246" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/50a50c4c-4ecf-44b9-8b2a-116a351a6fda_597x246.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:246,&quot;width&quot;:597,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:15235,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50a50c4c-4ecf-44b9-8b2a-116a351a6fda_597x246.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!m4P1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50a50c4c-4ecf-44b9-8b2a-116a351a6fda_597x246.png 424w, https://substackcdn.com/image/fetch/$s_!m4P1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50a50c4c-4ecf-44b9-8b2a-116a351a6fda_597x246.png 848w, https://substackcdn.com/image/fetch/$s_!m4P1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50a50c4c-4ecf-44b9-8b2a-116a351a6fda_597x246.png 1272w, https://substackcdn.com/image/fetch/$s_!m4P1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50a50c4c-4ecf-44b9-8b2a-116a351a6fda_597x246.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129513; 10 Hands-On Exercises</h2><p>Perform these inside <code>/tmp/linux_course/week3</code>.</p><ol><li><p>Create 3 files: <code>report.txt</code>, <code>data.txt</code>, <code>script.sh</code>.</p></li><li><p>Use <code>chmod</code> to make:</p><ul><li><p><code>report.txt</code> readable/writable by you only.</p></li><li><p><code>data.txt</code> readable by everyone.</p></li><li><p><code>script.sh</code> executable by everyone.</p></li></ul></li><li><p>Check with <code>ls -l</code>.</p></li><li><p>Use numeric permissions to make <code>report.txt</code> = <code>600</code>, <code>data.txt</code> = <code>644</code>, <code>script.sh</code> = <code>755</code>.</p></li><li><p>Create a folder <code>secure_dir</code> and make it accessible only to you (<code>700</code>).</p></li><li><p>Run <code>umask</code> and note the output.</p></li><li><p>Change umask temporarily to <code>077</code> and create a new file; check its default permissions.</p></li><li><p>Create directory <code>group_project</code>, run <code>chmod 2775 group_project</code>, and explain the SGID effect.</p></li><li><p>Create directory <code>shared_area</code>, run <code>chmod 1777 shared_area</code> &#8212; what does Sticky Bit do?</p></li><li><p>Create <code>example.sh</code> script that prints <code>whoami</code>, add SUID (<code>chmod u+s example.sh</code>), then <code>ls -l</code> to observe change.</p></li></ol><div><hr></div><h2>&#129504; 10 Assessment Questions</h2><ol><li><p>What do the letters <code>r</code>, <code>w</code>, and <code>x</code> stand for in file permissions?</p></li><li><p>Who are the three categories of users in Linux permissions?</p></li><li><p>Convert the permission string <code>-rw-r--r--</code> into numeric form.</p></li><li><p>What command is used to change ownership of a file?</p></li><li><p>How do you remove write permission for &#8220;others&#8221; on a file?</p></li><li><p>What does <code>chmod 755 script.sh</code> mean in words?</p></li><li><p>What does SUID do? Give one real-world example.</p></li><li><p>Why is the Sticky Bit important for directories like <code>/tmp</code>?</p></li><li><p>What does the command <code>umask 077</code> change?</p></li><li><p>What command lists all files with their permissions?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 3 Summary</strong><br>You learned:</p><ul><li><p>What file permissions mean (user, group, others).</p></li><li><p>How to use <code>chmod</code>, <code>chown</code>, and <code>chgrp</code>.</p></li><li><p>Numeric permission codes (like 644, 755).</p></li><li><p>Special permissions: SUID, SGID, Sticky Bit.</p></li><li><p>How to view and modify default permissions with <code>umask</code>.</p></li></ul><div><hr></div><h1>Chapter 4 &#8211; Linux Command Line Essentials</h1><p><strong>Week 4 Objective:</strong><br>Learn how to navigate, search, filter, manipulate text, and combine commands efficiently using <strong>pipes</strong>, <strong>redirection</strong>, and powerful utilities like <code>grep</code>, <code>find</code>, <code>awk</code>, and <code>sed</code>.</p><div><hr></div><h2>&#129504; 1. Layman&#8217;s Explanation &#8212; &#8220;The Power of Words&#8221;</h2><p>Think of the Linux command line like a <strong>kitchen</strong> &#127859;</p><ul><li><p>Each <strong>command</strong> is a <strong>tool</strong> (knife, pan, blender).</p></li><li><p>Each <strong>file</strong> is an <strong>ingredient</strong>.</p></li><li><p>You can <strong>connect tools</strong> together with <strong>pipes (</strong><code>|</code><strong>)</strong> &#8212; like sending chopped veggies straight from knife to pan!</p></li><li><p>You can <strong>redirect output (</strong><code>&gt;</code><strong>)</strong> &#8212; like saving your finished dish into a container.</p></li></ul><p>The goal: learn to <strong>combine simple commands</strong> to do complex tasks easily.</p><div><hr></div><h2>&#129513; 2. The Most Common File Viewing Commands</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rfM3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F162b10d4-4477-4141-b124-a8d690d7ae63_648x247.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rfM3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F162b10d4-4477-4141-b124-a8d690d7ae63_648x247.png 424w, https://substackcdn.com/image/fetch/$s_!rfM3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F162b10d4-4477-4141-b124-a8d690d7ae63_648x247.png 848w, https://substackcdn.com/image/fetch/$s_!rfM3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F162b10d4-4477-4141-b124-a8d690d7ae63_648x247.png 1272w, https://substackcdn.com/image/fetch/$s_!rfM3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F162b10d4-4477-4141-b124-a8d690d7ae63_648x247.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rfM3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F162b10d4-4477-4141-b124-a8d690d7ae63_648x247.png" width="648" height="247" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/162b10d4-4477-4141-b124-a8d690d7ae63_648x247.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:247,&quot;width&quot;:648,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:17291,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F162b10d4-4477-4141-b124-a8d690d7ae63_648x247.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rfM3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F162b10d4-4477-4141-b124-a8d690d7ae63_648x247.png 424w, https://substackcdn.com/image/fetch/$s_!rfM3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F162b10d4-4477-4141-b124-a8d690d7ae63_648x247.png 848w, https://substackcdn.com/image/fetch/$s_!rfM3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F162b10d4-4477-4141-b124-a8d690d7ae63_648x247.png 1272w, https://substackcdn.com/image/fetch/$s_!rfM3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F162b10d4-4477-4141-b124-a8d690d7ae63_648x247.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129521; 3. Searching &amp; Filtering Data</h2><h3><code>grep</code> (Global Regular Expression Print)</h3><p>Used to search inside files.</p><p>Example:</p><pre><code><code>grep &#8220;error&#8221; /var/log/syslog
</code></code></pre><p>Finds all lines containing the word <em>error</em>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CFxh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95ff9a65-b44c-4803-9cde-722366c16df4_658x173.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CFxh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95ff9a65-b44c-4803-9cde-722366c16df4_658x173.png 424w, https://substackcdn.com/image/fetch/$s_!CFxh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95ff9a65-b44c-4803-9cde-722366c16df4_658x173.png 848w, https://substackcdn.com/image/fetch/$s_!CFxh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95ff9a65-b44c-4803-9cde-722366c16df4_658x173.png 1272w, https://substackcdn.com/image/fetch/$s_!CFxh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95ff9a65-b44c-4803-9cde-722366c16df4_658x173.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CFxh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95ff9a65-b44c-4803-9cde-722366c16df4_658x173.png" width="658" height="173" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/95ff9a65-b44c-4803-9cde-722366c16df4_658x173.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:173,&quot;width&quot;:658,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:13463,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95ff9a65-b44c-4803-9cde-722366c16df4_658x173.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CFxh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95ff9a65-b44c-4803-9cde-722366c16df4_658x173.png 424w, https://substackcdn.com/image/fetch/$s_!CFxh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95ff9a65-b44c-4803-9cde-722366c16df4_658x173.png 848w, https://substackcdn.com/image/fetch/$s_!CFxh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95ff9a65-b44c-4803-9cde-722366c16df4_658x173.png 1272w, https://substackcdn.com/image/fetch/$s_!CFxh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95ff9a65-b44c-4803-9cde-722366c16df4_658x173.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129513; 4. Redirection and Pipes</h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bl9Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F235e92e9-ff27-4455-b912-ba8fc5d441a5_622x240.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bl9Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F235e92e9-ff27-4455-b912-ba8fc5d441a5_622x240.png 424w, https://substackcdn.com/image/fetch/$s_!bl9Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F235e92e9-ff27-4455-b912-ba8fc5d441a5_622x240.png 848w, https://substackcdn.com/image/fetch/$s_!bl9Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F235e92e9-ff27-4455-b912-ba8fc5d441a5_622x240.png 1272w, https://substackcdn.com/image/fetch/$s_!bl9Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F235e92e9-ff27-4455-b912-ba8fc5d441a5_622x240.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bl9Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F235e92e9-ff27-4455-b912-ba8fc5d441a5_622x240.png" width="622" height="240" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/235e92e9-ff27-4455-b912-ba8fc5d441a5_622x240.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:240,&quot;width&quot;:622,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:17244,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F235e92e9-ff27-4455-b912-ba8fc5d441a5_622x240.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bl9Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F235e92e9-ff27-4455-b912-ba8fc5d441a5_622x240.png 424w, https://substackcdn.com/image/fetch/$s_!bl9Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F235e92e9-ff27-4455-b912-ba8fc5d441a5_622x240.png 848w, https://substackcdn.com/image/fetch/$s_!bl9Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F235e92e9-ff27-4455-b912-ba8fc5d441a5_622x240.png 1272w, https://substackcdn.com/image/fetch/$s_!bl9Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F235e92e9-ff27-4455-b912-ba8fc5d441a5_622x240.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129518; 5. Text Manipulation Tools</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cgWi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55ae5a91-2e9d-4ac4-ab84-69d20099effc_642x249.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cgWi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55ae5a91-2e9d-4ac4-ab84-69d20099effc_642x249.png 424w, https://substackcdn.com/image/fetch/$s_!cgWi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55ae5a91-2e9d-4ac4-ab84-69d20099effc_642x249.png 848w, https://substackcdn.com/image/fetch/$s_!cgWi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55ae5a91-2e9d-4ac4-ab84-69d20099effc_642x249.png 1272w, https://substackcdn.com/image/fetch/$s_!cgWi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55ae5a91-2e9d-4ac4-ab84-69d20099effc_642x249.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cgWi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55ae5a91-2e9d-4ac4-ab84-69d20099effc_642x249.png" width="642" height="249" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/55ae5a91-2e9d-4ac4-ab84-69d20099effc_642x249.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:249,&quot;width&quot;:642,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:19194,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55ae5a91-2e9d-4ac4-ab84-69d20099effc_642x249.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cgWi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55ae5a91-2e9d-4ac4-ab84-69d20099effc_642x249.png 424w, https://substackcdn.com/image/fetch/$s_!cgWi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55ae5a91-2e9d-4ac4-ab84-69d20099effc_642x249.png 848w, https://substackcdn.com/image/fetch/$s_!cgWi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55ae5a91-2e9d-4ac4-ab84-69d20099effc_642x249.png 1272w, https://substackcdn.com/image/fetch/$s_!cgWi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55ae5a91-2e9d-4ac4-ab84-69d20099effc_642x249.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h1>&#128187; Let&#8217;s Practice (All Examples Runnable)</h1><h3>Setup:</h3><pre><code><code>mkdir -p /tmp/linux_course/week4
cd /tmp/linux_course/week4
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; Create Sample Data</h2><pre><code><code>cat &gt; employees.txt &lt;&lt;&#8217;EOF&#8217;
ID,Name,Department,Salary
1,John,IT,5000
2,Jane,HR,5500
3,Raj,Finance,6000
4,Meena,IT,6200
5,Ali,Sales,4800
6,Chen,IT,7000
EOF
</code></code></pre><p>&#9989; Check:</p><pre><code><code>cat employees.txt
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; View Files</h2><pre><code><code>echo &#8220;=== Using cat ===&#8221;
cat employees.txt

echo &#8220;=== Using head ===&#8221;
head -n 3 employees.txt

echo &#8220;=== Using tail ===&#8221;
tail -n 2 employees.txt

echo &#8220;=== Using less ===&#8221;
less employees.txt
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Searching with grep</h2><pre><code><code># Find who works in IT
grep &#8220;IT&#8221; employees.txt

# Ignore case
grep -i &#8220;it&#8221; employees.txt

# Show line numbers
grep -n &#8220;Finance&#8221; employees.txt

# Exclude HR
grep -v &#8220;HR&#8221; employees.txt
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; Cut, Sort, and Uniq</h2><pre><code><code># Extract the Department column (3rd field)
cut -d&#8217;,&#8217; -f3 employees.txt

# Sort departments alphabetically
cut -d&#8217;,&#8217; -f3 employees.txt | sort

# Show unique departments only
cut -d&#8217;,&#8217; -f3 employees.txt | sort | uniq
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; Using awk for Simple Reports</h2><pre><code><code># Print name and salary
awk -F&#8217;,&#8217; &#8216;{print $2, $4}&#8217; employees.txt

# Print all IT employees only
awk -F&#8217;,&#8217; &#8216;$3==&#8221;IT&#8221; {print $2, $3, $4}&#8217; employees.txt

# Calculate total salary
awk -F&#8217;,&#8217; &#8216;NR&gt;1 {sum+=$4} END {print &#8220;Total Salary:&#8221;, sum}&#8217; employees.txt

# Find average salary
awk -F&#8217;,&#8217; &#8216;NR&gt;1 {sum+=$4; count++} END {print &#8220;Average Salary:&#8221;, sum/count}&#8217; employees.txt
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; sed (Find and Replace)</h2><pre><code><code># Replace &#8216;IT&#8217; with &#8216;Tech&#8217; and save to new file
sed &#8216;s/IT/Tech/g&#8217; employees.txt &gt; updated.txt
cat updated.txt

# Delete header line
sed &#8216;1d&#8217; employees.txt

# Add prefix to each line
sed &#8216;s/^/Employee: /&#8217; employees.txt
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; Pipes &amp; Redirection Together</h2><pre><code><code># List all shell scripts in /bin and count them
ls /bin | grep &#8220;\.sh&#8221; | wc -l

# Save IT department employees to a separate file
grep &#8220;IT&#8221; employees.txt &gt; it_team.txt
cat it_team.txt

# Append HR employees at the end
grep &#8220;HR&#8221; employees.txt &gt;&gt; it_team.txt
cat it_team.txt
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; Combine Tools: Find + Grep</h2><pre><code><code># Create a few text files
echo &#8220;Linux Rocks&#8221; &gt; note1.txt
echo &#8220;DevOps uses Linux&#8221; &gt; note2.txt
echo &#8220;Python is fun&#8221; &gt; note3.txt

# Find all .txt files containing &#8220;Linux&#8221;
find . -name &#8220;*.txt&#8221; | xargs grep &#8220;Linux&#8221;
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Redirect Errors</h2><pre><code><code># Try accessing non-existent folder
ls /no/such/path 2&gt; error.log

# Show contents of the error log
cat error.log
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; Sort &amp; Filter Combined Example</h2><pre><code><code># Show all salaries sorted in descending order
awk -F&#8217;,&#8217; &#8216;NR&gt;1 {print $4}&#8217; employees.txt | sort -nr

# Show top 3 salaries
awk -F&#8217;,&#8217; &#8216;NR&gt;1 {print $4}&#8217; employees.txt | sort -nr | head -3
</code></code></pre><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><p>Perform these in <code>/tmp/linux_course/week4</code>:</p><ol><li><p>Create a file <code>products.csv</code> with columns: <code>ID,Name,Category,Price</code>.</p></li><li><p>Add at least 5 products manually.</p></li><li><p>Use <code>cat</code> and <code>head</code> to preview it.</p></li><li><p>Find all products belonging to category &#8220;Electronics&#8221; using <code>grep</code>.</p></li><li><p>Use <code>awk</code> to print only Name and Price columns.</p></li><li><p>Use <code>awk</code> to calculate total price of all items.</p></li><li><p>Use <code>cut</code> and <code>sort</code> to show sorted category list (unique).</p></li><li><p>Use <code>sed</code> to replace all commas with tabs and save as <code>tab_products.txt</code>.</p></li><li><p>Create a pipeline that counts how many products cost more than 1000 (hint: <code>awk &#8216;$4&gt;1000&#8217;</code>).</p></li><li><p>Redirect all commands&#8217; output to <code>summary.log</code> for submission.</p></li></ol><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>What is the difference between <code>cat</code> and <code>less</code>?</p></li><li><p>How would you show only the last 5 lines of a file?</p></li><li><p>What does the pipe <code>|</code> do between two commands?</p></li><li><p>Write a command to find all lines containing &#8220;error&#8221; (case-insensitive) in <code>app.log</code>.</p></li><li><p>What is the purpose of <code>cut</code> and <code>sort</code>?</p></li><li><p>Write a command to show unique departments in <code>employees.txt</code>.</p></li><li><p>How can you replace all instances of &#8220;Dev&#8221; with &#8220;Developer&#8221; inside a file?</p></li><li><p>What&#8217;s the difference between <code>&gt;</code> and <code>&gt;&gt;</code>?</p></li><li><p>Write a command that finds all <code>.txt</code> files and searches for &#8220;Linux&#8221; inside them.</p></li><li><p>What is the meaning of <code>awk -F&#8217;,&#8217; &#8216;NR&gt;1 {sum+=$4} END {print sum}&#8217; employees.txt</code>?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 4 Summary</strong><br>You learned:</p><ul><li><p>How to view, search, and manipulate text in Linux.</p></li><li><p>How to redirect, pipe, and filter command outputs.</p></li><li><p>How to use tools like <code>grep</code>, <code>awk</code>, and <code>sed</code> to extract insights.</p></li><li><p>How to combine multiple commands to automate analysis quickly.</p></li></ul><div><hr></div><h1>Chapter 5 &#8211; User and Group Administration</h1><p><strong>Week 5 Objective:</strong><br>Learn how Linux handles <strong>accounts</strong>, <strong>groups</strong>, and <strong>permissions</strong>, and how to manage them using commands and configuration files.</p><div><hr></div><h2>&#129504; 1. Layman&#8217;s Explanation &#8212; &#8220;The Company Analogy&#8221;</h2><p>Think of a <strong>Linux system as a company office</strong>:</p><ul><li><p>Each <strong>user</strong> is an <strong>employee</strong> with their own desk (home directory).</p></li><li><p>Each <strong>group</strong> is a <strong>team</strong> (e.g., Developers, HR).</p></li><li><p>The <strong>administrator (root)</strong> is like the <strong>CEO</strong> &#8212; has all access.</p></li><li><p><code>sudo</code> is like <strong>temporary CEO permission</strong> given to trusted staff.</p></li></ul><p>Every user has a <strong>username</strong>, <strong>password</strong>, <strong>user ID (UID)</strong>, <strong>group ID (GID)</strong>, and <strong>home directory</strong>.</p><div><hr></div><h2>&#129513; 2. Key Files Involved</h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9mG3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea46c3b4-f339-44e1-9359-64c649ede021_587x200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9mG3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea46c3b4-f339-44e1-9359-64c649ede021_587x200.png 424w, https://substackcdn.com/image/fetch/$s_!9mG3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea46c3b4-f339-44e1-9359-64c649ede021_587x200.png 848w, https://substackcdn.com/image/fetch/$s_!9mG3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea46c3b4-f339-44e1-9359-64c649ede021_587x200.png 1272w, https://substackcdn.com/image/fetch/$s_!9mG3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea46c3b4-f339-44e1-9359-64c649ede021_587x200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9mG3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea46c3b4-f339-44e1-9359-64c649ede021_587x200.png" width="587" height="200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ea46c3b4-f339-44e1-9359-64c649ede021_587x200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:200,&quot;width&quot;:587,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:16395,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea46c3b4-f339-44e1-9359-64c649ede021_587x200.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9mG3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea46c3b4-f339-44e1-9359-64c649ede021_587x200.png 424w, https://substackcdn.com/image/fetch/$s_!9mG3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea46c3b4-f339-44e1-9359-64c649ede021_587x200.png 848w, https://substackcdn.com/image/fetch/$s_!9mG3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea46c3b4-f339-44e1-9359-64c649ede021_587x200.png 1272w, https://substackcdn.com/image/fetch/$s_!9mG3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea46c3b4-f339-44e1-9359-64c649ede021_587x200.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129520; 3. Important Commands</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GWeO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F148e1aa7-bc72-4ed7-ab4a-cf44779ef85e_640x417.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GWeO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F148e1aa7-bc72-4ed7-ab4a-cf44779ef85e_640x417.png 424w, https://substackcdn.com/image/fetch/$s_!GWeO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F148e1aa7-bc72-4ed7-ab4a-cf44779ef85e_640x417.png 848w, https://substackcdn.com/image/fetch/$s_!GWeO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F148e1aa7-bc72-4ed7-ab4a-cf44779ef85e_640x417.png 1272w, https://substackcdn.com/image/fetch/$s_!GWeO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F148e1aa7-bc72-4ed7-ab4a-cf44779ef85e_640x417.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GWeO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F148e1aa7-bc72-4ed7-ab4a-cf44779ef85e_640x417.png" width="640" height="417" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/148e1aa7-bc72-4ed7-ab4a-cf44779ef85e_640x417.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:417,&quot;width&quot;:640,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:32494,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F148e1aa7-bc72-4ed7-ab4a-cf44779ef85e_640x417.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!GWeO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F148e1aa7-bc72-4ed7-ab4a-cf44779ef85e_640x417.png 424w, https://substackcdn.com/image/fetch/$s_!GWeO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F148e1aa7-bc72-4ed7-ab4a-cf44779ef85e_640x417.png 848w, https://substackcdn.com/image/fetch/$s_!GWeO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F148e1aa7-bc72-4ed7-ab4a-cf44779ef85e_640x417.png 1272w, https://substackcdn.com/image/fetch/$s_!GWeO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F148e1aa7-bc72-4ed7-ab4a-cf44779ef85e_640x417.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129518; 4. The <code>/etc/passwd</code> Format</h2><p>Each line looks like this:</p><pre><code><code>username:x:UID:GID:Comment:HomeDirectory:Shell
</code></code></pre><p>Example:</p><pre><code><code>bavi:x:1001:1001:Bavithran:/home/bavi:/bin/bash
</code></code></pre><p>Explanation:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oA_x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33bb97d9-4739-43d2-a810-02fb4f6f24f1_572x335.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oA_x!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33bb97d9-4739-43d2-a810-02fb4f6f24f1_572x335.png 424w, https://substackcdn.com/image/fetch/$s_!oA_x!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33bb97d9-4739-43d2-a810-02fb4f6f24f1_572x335.png 848w, https://substackcdn.com/image/fetch/$s_!oA_x!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33bb97d9-4739-43d2-a810-02fb4f6f24f1_572x335.png 1272w, https://substackcdn.com/image/fetch/$s_!oA_x!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33bb97d9-4739-43d2-a810-02fb4f6f24f1_572x335.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oA_x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33bb97d9-4739-43d2-a810-02fb4f6f24f1_572x335.png" width="572" height="335" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/33bb97d9-4739-43d2-a810-02fb4f6f24f1_572x335.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:335,&quot;width&quot;:572,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:16813,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33bb97d9-4739-43d2-a810-02fb4f6f24f1_572x335.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oA_x!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33bb97d9-4739-43d2-a810-02fb4f6f24f1_572x335.png 424w, https://substackcdn.com/image/fetch/$s_!oA_x!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33bb97d9-4739-43d2-a810-02fb4f6f24f1_572x335.png 848w, https://substackcdn.com/image/fetch/$s_!oA_x!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33bb97d9-4739-43d2-a810-02fb4f6f24f1_572x335.png 1272w, https://substackcdn.com/image/fetch/$s_!oA_x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33bb97d9-4739-43d2-a810-02fb4f6f24f1_572x335.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129513; 5. The <code>/etc/group</code> Format</h2><pre><code><code>group_name:x:GID:user1,user2
</code></code></pre><p>Example:</p><pre><code><code>devops:x:1002:bavi,janani
</code></code></pre><div><hr></div><h2>&#128187; Let&#8217;s Practice (Safe Demo Environment)</h2><blockquote><p>We&#8217;ll simulate user/group management in <code>/tmp/linux_course/week5/demo_users</code><br>(not real system users &#8212; safe for non-root users).</p></blockquote><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; Create a Demo Folder for Users</h2><pre><code><code>mkdir -p /tmp/linux_course/week5/demo_users/{home,groups}
cd /tmp/linux_course/week5/demo_users
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; Simulate Adding Users (No Root Needed)</h2><p>We&#8217;ll just create files to represent users.</p><pre><code><code># Create mock user entries
echo &#8220;bavi:x:1001:1001:Bavi:/home/bavi:/bin/bash&#8221; &gt; users.txt
echo &#8220;janani:x:1002:1002:Janani:/home/janani:/bin/bash&#8221; &gt;&gt; users.txt
echo &#8220;vikram:x:1003:1003:Vikram:/home/vikram:/bin/bash&#8221; &gt;&gt; users.txt

cat users.txt
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; View Users and Groups on Real System</h2><pre><code><code># Show first 5 users in /etc/passwd
head -n 5 /etc/passwd

# Show your user info
whoami
id
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; Create Real Groups and Users (requires sudo)</h2><p><em>(Run only if you&#8217;re on a local VM or have admin rights)</em></p><pre><code><code>sudo groupadd devops
sudo useradd -m -s /bin/bash bavi
sudo usermod -aG devops bavi
sudo passwd bavi
id bavi
</code></code></pre><p>Explanation:</p><ul><li><p><code>-m</code> &#8594; creates a home directory.</p></li><li><p><code>-s</code> &#8594; defines shell.</p></li><li><p><code>-aG</code> &#8594; adds user to group.</p></li></ul><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; Manage Passwords and Expiry</h2><pre><code><code># Show password aging policy
sudo chage -l bavi

# Set password to expire in 10 days
sudo chage -E $(date -d &#8220;+10 days&#8221; +%Y-%m-%d) bavi
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; Configuring sudo Permissions</h2><pre><code><code># Add user to sudo group
sudo usermod -aG sudo bavi

# Verify group membership
groups bavi

# Test sudo (if you have privileges)
sudo whoami
</code></code></pre><p><code>/etc/sudoers</code> file controls this. Always use <code>visudo</code> to edit it safely.</p><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; Locking and Unlocking Accounts</h2><pre><code><code># Lock user account
sudo usermod -L bavi

# Unlock user account
sudo usermod -U bavi
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; Creating and Managing Groups</h2><pre><code><code># Create new group
sudo groupadd testers

# Add user to multiple groups
sudo usermod -aG devops,testers bavi

# Show all groups for user
groups bavi
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Deleting Users and Groups</h2><pre><code><code># Delete user
sudo userdel -r bavi

# Delete group
sudo groupdel devops
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; View All Users and Groups (Read-only)</h2><pre><code><code>cut -d: -f1 /etc/passwd | head -n 10
cut -d: -f1 /etc/group | head -n 10
</code></code></pre><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><p>Perform these on your VM or using mock files under <code>/tmp/linux_course/week5</code>:</p><ol><li><p>Create mock files named <code>users.txt</code> and <code>groups.txt</code>.</p></li><li><p>Add 3 users and 2 groups to these files.</p></li><li><p>Use <code>cut</code> to extract usernames from <code>/etc/passwd</code>.</p></li><li><p>Use <code>grep</code> to find your username in <code>/etc/passwd</code>.</p></li><li><p>Run <code>id</code> to display your UID, GID, and group memberships.</p></li><li><p>Create a new group named <code>analytics</code> (mock using <code>echo</code>).</p></li><li><p>Add user <code>raj</code> to group <code>analytics</code>.</p></li><li><p>Use <code>sort</code> and <code>uniq</code> to list unique groups from <code>/etc/group</code>.</p></li><li><p>Write a script <code>list_users.sh</code> that prints:</p></li></ol><pre><code><code>#!/bin/bash
echo &#8220;Total Users: $(wc -l &lt; /etc/passwd)&#8221;
echo &#8220;Users in sudo group:&#8221;
grep sudo /etc/group
</code></code></pre><ol><li><p>Save your script, make it executable (<code>chmod +x list_users.sh</code>), and run it.</p></li></ol><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>Which file stores basic information about all user accounts?</p></li><li><p>What is the difference between <code>/etc/passwd</code> and <code>/etc/shadow</code>?</p></li><li><p>How can you find your username and UID in Linux?</p></li><li><p>Write the command to create a new user named <code>developer</code>.</p></li><li><p>How do you add a user to the <code>sudo</code> group?</p></li><li><p>What does <code>userdel -r</code> do?</p></li><li><p>What command shows which groups you belong to?</p></li><li><p>What is the safest way to edit <code>/etc/sudoers</code>?</p></li><li><p>What happens when you lock a user account using <code>usermod -L</code>?</p></li><li><p>How do you list all existing users on the system?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 5 Summary</strong><br>You learned:</p><ul><li><p>How Linux stores and manages user &amp; group data.</p></li><li><p>Commands for user creation, modification, deletion.</p></li><li><p>Safe <code>sudo</code> configuration.</p></li><li><p>Understanding <code>/etc/passwd</code>, <code>/etc/group</code>, <code>/etc/shadow</code>.</p></li></ul><div><hr></div><p></p><h1>Chapter 6 &#8211; Process and Job Management</h1><p><strong>Week 6 Objective:</strong><br>Understand what a <strong>process</strong> is, how to <strong>monitor</strong>, <strong>kill</strong>, <strong>pause</strong>, <strong>resume</strong>, and <strong>schedule jobs</strong> in Linux.</p><div><hr></div><h2>&#129504; 1. Layman&#8217;s Explanation &#8212; &#8220;The Restaurant Analogy&#8221;</h2><p>Imagine your Linux system as a <strong>restaurant kitchen</strong> &#127869;&#65039;</p><ul><li><p>Each <strong>process</strong> = a <strong>chef cooking a dish</strong> (a running program).</p></li><li><p>Each <strong>PID (Process ID)</strong> = a <strong>badge number</strong> identifying a chef.</p></li><li><p>The <strong>parent process (PPID)</strong> = head chef who started others.</p></li><li><p>The <strong>foreground</strong> process = the chef currently at the counter (your terminal).</p></li><li><p>The <strong>background</strong> process = chefs cooking quietly in the back.</p></li><li><p>The <strong>scheduler</strong> = the manager who decides who cooks first (CPU time).</p></li></ul><div><hr></div><h2>&#129513; 2. Understanding Process States</h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!J9gr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd51de96a-dd52-4ec8-b5a0-868d31d17788_547x237.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!J9gr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd51de96a-dd52-4ec8-b5a0-868d31d17788_547x237.png 424w, https://substackcdn.com/image/fetch/$s_!J9gr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd51de96a-dd52-4ec8-b5a0-868d31d17788_547x237.png 848w, https://substackcdn.com/image/fetch/$s_!J9gr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd51de96a-dd52-4ec8-b5a0-868d31d17788_547x237.png 1272w, https://substackcdn.com/image/fetch/$s_!J9gr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd51de96a-dd52-4ec8-b5a0-868d31d17788_547x237.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!J9gr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd51de96a-dd52-4ec8-b5a0-868d31d17788_547x237.png" width="547" height="237" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d51de96a-dd52-4ec8-b5a0-868d31d17788_547x237.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:237,&quot;width&quot;:547,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:13803,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd51de96a-dd52-4ec8-b5a0-868d31d17788_547x237.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!J9gr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd51de96a-dd52-4ec8-b5a0-868d31d17788_547x237.png 424w, https://substackcdn.com/image/fetch/$s_!J9gr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd51de96a-dd52-4ec8-b5a0-868d31d17788_547x237.png 848w, https://substackcdn.com/image/fetch/$s_!J9gr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd51de96a-dd52-4ec8-b5a0-868d31d17788_547x237.png 1272w, https://substackcdn.com/image/fetch/$s_!J9gr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd51de96a-dd52-4ec8-b5a0-868d31d17788_547x237.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129520; 3. Important Commands</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!M1K1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71a616f0-8db1-44f4-9684-da3cffed4899_653x471.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!M1K1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71a616f0-8db1-44f4-9684-da3cffed4899_653x471.png 424w, https://substackcdn.com/image/fetch/$s_!M1K1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71a616f0-8db1-44f4-9684-da3cffed4899_653x471.png 848w, https://substackcdn.com/image/fetch/$s_!M1K1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71a616f0-8db1-44f4-9684-da3cffed4899_653x471.png 1272w, https://substackcdn.com/image/fetch/$s_!M1K1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71a616f0-8db1-44f4-9684-da3cffed4899_653x471.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!M1K1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71a616f0-8db1-44f4-9684-da3cffed4899_653x471.png" width="653" height="471" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/71a616f0-8db1-44f4-9684-da3cffed4899_653x471.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:471,&quot;width&quot;:653,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:36502,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71a616f0-8db1-44f4-9684-da3cffed4899_653x471.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!M1K1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71a616f0-8db1-44f4-9684-da3cffed4899_653x471.png 424w, https://substackcdn.com/image/fetch/$s_!M1K1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71a616f0-8db1-44f4-9684-da3cffed4899_653x471.png 848w, https://substackcdn.com/image/fetch/$s_!M1K1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71a616f0-8db1-44f4-9684-da3cffed4899_653x471.png 1272w, https://substackcdn.com/image/fetch/$s_!M1K1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71a616f0-8db1-44f4-9684-da3cffed4899_653x471.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129513; 4. Process Hierarchy &#8211; Example</h2><p>Every process starts from <strong>PID 1</strong> (<code>systemd</code> or <code>init</code>):</p><pre><code><code>systemd (PID 1)
 &#9500;&#9472;&#9472; sshd
 &#9500;&#9472;&#9472; bash
 &#9474;   &#9492;&#9472;&#9472; vim
 &#9500;&#9472;&#9472; apache2
 &#9492;&#9472;&#9472; cron
</code></code></pre><p>Use <code>pstree</code> to see this structure in action.</p><div><hr></div><h1>&#128187; Let&#8217;s Practice (Runnable Examples)</h1><h3>Setup</h3><pre><code><code>mkdir -p /tmp/linux_course/week6
cd /tmp/linux_course/week6
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; See All Processes</h2><pre><code><code>echo &#8220;=== Using ps ===&#8221;
ps aux | head -10

echo &#8220;=== Using ps -ef ===&#8221;
ps -ef | head -10
</code></code></pre><p>&#128161; <code>ps aux</code> = BSD format; <code>ps -ef</code> = UNIX format. Both show who owns the process, PID, CPU%, MEM%, etc.</p><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; View Process Tree</h2><pre><code><code>pstree -p | head -20
</code></code></pre><p>This shows the relationship between parent and child processes.</p><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Start Background and Foreground Jobs</h2><pre><code><code># Foreground job (runs in front)
sleep 10

# Background job
sleep 60 &amp;

# Check job list
jobs

# Bring job to foreground
fg %1
</code></code></pre><p>Explanation:</p><ul><li><p><code>sleep 60 &amp;</code> runs in the background.</p></li><li><p><code>jobs</code> lists active jobs.</p></li><li><p><code>fg</code> brings one back to the terminal.</p></li></ul><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; Killing a Process</h2><pre><code><code># Run a long process
sleep 1000 &amp;
ps aux | grep sleep

# Note its PID and kill it
PID=$(pgrep -f &#8220;sleep 1000&#8221;)
echo &#8220;Killing PID: $PID&#8221;
kill $PID
</code></code></pre><p>If the process refuses to die:</p><pre><code><code>kill -9 $PID
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; Process Priorities (nice / renice)</h2><p>Every process has a <strong>nice value</strong> between <strong>-20 (high priority)</strong> and <strong>+19 (low priority)</strong>.</p><pre><code><code># Run a CPU task with low priority
nice -n 10 bash -c &#8216;for i in {1..50000}; do :; done&#8217; &amp;

# Find its PID
ps -eo pid,ni,comm | grep bash

# Change its priority
sudo renice -n -5 -p &lt;PID&gt;
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; Monitor Processes (top and htop)</h2><pre><code><code>top
</code></code></pre><p>Press:</p><ul><li><p><code>q</code> &#8594; quit</p></li><li><p><code>P</code> &#8594; sort by CPU</p></li><li><p><code>M</code> &#8594; sort by memory</p></li></ul><p>For a modern UI (if installed):</p><pre><code><code>htop
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; Scheduling Tasks with <code>cron</code></h2><pre><code><code># Open crontab for current user
crontab -e
</code></code></pre><p>Add a line:</p><pre><code><code>* * * * * echo &#8220;Hello from cron at $(date)&#8221; &gt;&gt; /tmp/linux_course/week6/cron_log.txt
</code></code></pre><p>This runs every minute.</p><p>To list all scheduled jobs:</p><pre><code><code>crontab -l
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; One-Time Task with <code>at</code></h2><pre><code><code># Schedule a message in 2 minutes
echo &#8220;echo &#8216;Task ran at $(date)&#8217; &gt;&gt; /tmp/linux_course/week6/at_log.txt&#8221; | at now + 2 minutes
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Monitoring Resource Usage with ps and top</h2><pre><code><code># Show top 5 CPU-consuming processes
ps -eo pid,comm,%cpu --sort=-%cpu | head -6

# Show top 5 memory-consuming processes
ps -eo pid,comm,%mem --sort=-%mem | head -6
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; Automate Process Check Script</h2><pre><code><code>cat &gt; process_check.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
echo &#8220;=== Process Report on $(date) ===&#8221;
ps -eo pid,comm,%cpu,%mem --sort=-%cpu | head -10
EOF
chmod +x process_check.sh
./process_check.sh
</code></code></pre><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><ol><li><p>Run <code>ps aux</code> and note your terminal&#8217;s PID and parent PID.</p></li><li><p>Run a <code>sleep 30 &amp;</code> background job and bring it to the foreground.</p></li><li><p>Create two background processes (<code>sleep 100</code>, <code>sleep 200</code>) and list them using <code>jobs</code>.</p></li><li><p>Use <code>kill</code> to stop one of them.</p></li><li><p>Start a CPU-intensive process with <code>nice -n 15</code>, then check its priority using <code>ps -l</code>.</p></li><li><p>Change its priority using <code>renice -n 5 -p &lt;PID&gt;</code>.</p></li><li><p>View all running processes sorted by memory usage (<code>ps -eo %mem,cmd --sort=-%mem</code>).</p></li><li><p>Schedule a cron job that appends <code>System Alive!</code> to a file every 2 minutes.</p></li><li><p>Schedule a one-time <code>at</code> job that prints &#8220;Lunch break!&#8221; after 3 minutes.</p></li><li><p>Write a script <code>cleanup.sh</code> that kills all <code>sleep</code> processes automatically.</p></li></ol><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>What is a process in Linux?</p></li><li><p>What is the difference between a foreground and background process?</p></li><li><p>How do you list all running processes on the system?</p></li><li><p>What is a PID and how can you find it?</p></li><li><p>What command displays a process hierarchy?</p></li><li><p>What is the difference between <code>kill</code> and <code>pkill</code>?</p></li><li><p>What does the command <code>nice -n 10</code> do?</p></li><li><p>How do you schedule a task to run every day at 6 PM?</p></li><li><p>What command lists currently scheduled cron jobs?</p></li><li><p>What does the <code>at</code> command do?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 6 Summary</strong><br>You learned:</p><ul><li><p>What processes are and how they&#8217;re structured.</p></li><li><p>How to manage and monitor processes using <code>ps</code>, <code>top</code>, <code>kill</code>, etc.</p></li><li><p>How to schedule tasks with <code>cron</code> and <code>at</code>.</p></li><li><p>How to adjust process priorities with <code>nice</code> and <code>renice</code>.</p></li></ul><div><hr></div><p></p><h1>Chapter 7 &#8211; Software and Package Management</h1><p><strong>Week 7 Objective:</strong><br>Learn how to install, update, and manage packages on both <strong>Debian/Ubuntu</strong> (using <code>apt</code>) and <strong>RHEL/CentOS/Fedora</strong> (using <code>yum</code>, <code>dnf</code>, and <code>rpm</code>).<br>You&#8217;ll also understand repositories, package info, and software compilation.</p><div><hr></div><h2>&#129504; 1. Layman&#8217;s Explanation &#8212; &#8220;The App Store Analogy&#8221;</h2><p>Think of your <strong>Linux system as a smartphone</strong> &#128241;</p><ul><li><p><code>apt</code><strong>, </strong><code>yum</code><strong>, and </strong><code>dnf</code> are like your <strong>App Store</strong> managers.</p></li><li><p><strong>Packages</strong> are the apps.</p></li><li><p><strong>Repositories (repos)</strong> are the online stores where these apps are kept.</p></li><li><p><code>rpm</code><strong> or </strong><code>dpkg</code> are like manual app installers (.apk or .exe).</p></li><li><p><strong>Dependencies</strong> are the libraries needed for an app to run (like needing Java before installing a Java app).</p></li></ul><div><hr></div><h2>&#129513; 2. Package Types by Distribution</h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cCZt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e8acd9f-88c6-474a-bb32-731646641a86_692x125.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cCZt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e8acd9f-88c6-474a-bb32-731646641a86_692x125.png 424w, https://substackcdn.com/image/fetch/$s_!cCZt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e8acd9f-88c6-474a-bb32-731646641a86_692x125.png 848w, https://substackcdn.com/image/fetch/$s_!cCZt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e8acd9f-88c6-474a-bb32-731646641a86_692x125.png 1272w, https://substackcdn.com/image/fetch/$s_!cCZt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e8acd9f-88c6-474a-bb32-731646641a86_692x125.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cCZt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e8acd9f-88c6-474a-bb32-731646641a86_692x125.png" width="692" height="125" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9e8acd9f-88c6-474a-bb32-731646641a86_692x125.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:125,&quot;width&quot;:692,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:13876,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e8acd9f-88c6-474a-bb32-731646641a86_692x125.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cCZt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e8acd9f-88c6-474a-bb32-731646641a86_692x125.png 424w, https://substackcdn.com/image/fetch/$s_!cCZt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e8acd9f-88c6-474a-bb32-731646641a86_692x125.png 848w, https://substackcdn.com/image/fetch/$s_!cCZt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e8acd9f-88c6-474a-bb32-731646641a86_692x125.png 1272w, https://substackcdn.com/image/fetch/$s_!cCZt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e8acd9f-88c6-474a-bb32-731646641a86_692x125.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129520; 3. Common Commands</h2><h3>&#128998; Debian/Ubuntu (<code>apt</code> / <code>dpkg</code>)</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8pG3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41e8a7e-d156-4cda-a6ee-a272b5acae9e_591x361.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8pG3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41e8a7e-d156-4cda-a6ee-a272b5acae9e_591x361.png 424w, https://substackcdn.com/image/fetch/$s_!8pG3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41e8a7e-d156-4cda-a6ee-a272b5acae9e_591x361.png 848w, https://substackcdn.com/image/fetch/$s_!8pG3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41e8a7e-d156-4cda-a6ee-a272b5acae9e_591x361.png 1272w, https://substackcdn.com/image/fetch/$s_!8pG3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41e8a7e-d156-4cda-a6ee-a272b5acae9e_591x361.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8pG3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41e8a7e-d156-4cda-a6ee-a272b5acae9e_591x361.png" width="591" height="361" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f41e8a7e-d156-4cda-a6ee-a272b5acae9e_591x361.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:361,&quot;width&quot;:591,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:24977,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41e8a7e-d156-4cda-a6ee-a272b5acae9e_591x361.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8pG3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41e8a7e-d156-4cda-a6ee-a272b5acae9e_591x361.png 424w, https://substackcdn.com/image/fetch/$s_!8pG3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41e8a7e-d156-4cda-a6ee-a272b5acae9e_591x361.png 848w, https://substackcdn.com/image/fetch/$s_!8pG3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41e8a7e-d156-4cda-a6ee-a272b5acae9e_591x361.png 1272w, https://substackcdn.com/image/fetch/$s_!8pG3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff41e8a7e-d156-4cda-a6ee-a272b5acae9e_591x361.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h3>&#128997; RHEL/CentOS/Fedora (<code>yum</code> / <code>dnf</code> / <code>rpm</code>)</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qFPS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cdba596-2708-4e9f-98ef-2333b945f8f8_598x390.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qFPS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cdba596-2708-4e9f-98ef-2333b945f8f8_598x390.png 424w, https://substackcdn.com/image/fetch/$s_!qFPS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cdba596-2708-4e9f-98ef-2333b945f8f8_598x390.png 848w, https://substackcdn.com/image/fetch/$s_!qFPS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cdba596-2708-4e9f-98ef-2333b945f8f8_598x390.png 1272w, https://substackcdn.com/image/fetch/$s_!qFPS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cdba596-2708-4e9f-98ef-2333b945f8f8_598x390.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qFPS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cdba596-2708-4e9f-98ef-2333b945f8f8_598x390.png" width="598" height="390" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6cdba596-2708-4e9f-98ef-2333b945f8f8_598x390.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:390,&quot;width&quot;:598,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:25076,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cdba596-2708-4e9f-98ef-2333b945f8f8_598x390.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qFPS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cdba596-2708-4e9f-98ef-2333b945f8f8_598x390.png 424w, https://substackcdn.com/image/fetch/$s_!qFPS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cdba596-2708-4e9f-98ef-2333b945f8f8_598x390.png 848w, https://substackcdn.com/image/fetch/$s_!qFPS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cdba596-2708-4e9f-98ef-2333b945f8f8_598x390.png 1272w, https://substackcdn.com/image/fetch/$s_!qFPS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6cdba596-2708-4e9f-98ef-2333b945f8f8_598x390.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129513; 4. Repositories Explained</h2><p>Repositories are like <strong>warehouses</strong> of software.<br>They contain thousands of packages and metadata.</p><p>Config files for repos are stored in:</p><ul><li><p><code>/etc/apt/sources.list</code> and <code>/etc/apt/sources.list.d/</code> (Debian/Ubuntu)</p></li><li><p><code>/etc/yum.repos.d/*.repo</code> (RHEL/CentOS)</p></li></ul><p>Example (RHEL):</p><pre><code><code>[base]
name=BaseOS
baseurl=http://mirror.centos.org/centos/8/BaseOS/x86_64/os/
enabled=1
gpgcheck=1
</code></code></pre><div><hr></div><h1>&#128187; Let&#8217;s Practice (Runnable Examples)</h1><p>Create a safe workspace:</p><pre><code><code>mkdir -p /tmp/linux_course/week7
cd /tmp/linux_course/week7
</code></code></pre><p><em>(These commands are read-only or safe to execute on any system.)</em></p><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; Check Distro Family</h2><pre><code><code>cat /etc/os-release
</code></code></pre><p>Output might contain:</p><pre><code><code>ID=ubuntu
ID_LIKE=debian
</code></code></pre><p>or</p><pre><code><code>ID=&#8221;rhel&#8221;
ID_LIKE=&#8221;fedora&#8221;
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; List Installed Packages</h2><p>For Ubuntu/Debian:</p><pre><code><code>dpkg -l | head -10
</code></code></pre><p>For RHEL/CentOS:</p><pre><code><code>yum list installed | head -10
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Search and Install Software</h2><p><em>(Run only if you have sudo privileges; safe to read otherwise)</em></p><pre><code><code># Search for curl
apt search curl    # Ubuntu/Debian
yum search curl    # RHEL/CentOS

# Install curl
sudo apt install curl -y
# OR
sudo yum install curl -y
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; Get Information About a Package</h2><pre><code><code>apt show curl 2&gt;/dev/null || yum info curl
</code></code></pre><p>You&#8217;ll see version, dependencies, and description.</p><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; Remove and Reinstall a Package</h2><pre><code><code>sudo apt remove curl -y 2&gt;/dev/null || sudo yum remove curl -y
sudo apt install curl -y 2&gt;/dev/null || sudo yum install curl -y
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; List Package Files</h2><pre><code><code>dpkg -L curl 2&gt;/dev/null || rpm -ql curl
</code></code></pre><p>Shows which files were installed by that package.</p><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; Download a Package Without Installing</h2><pre><code><code>apt download curl 2&gt;/dev/null || yumdownloader curl
ls
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; Install Software from Source (safe demo)</h2><p>We&#8217;ll simulate this with a tiny &#8220;Hello World&#8221; C program.</p><pre><code><code>cat &gt; hello.c &lt;&lt;&#8217;EOF&#8217;
#include &lt;stdio.h&gt;
int main() {
    printf(&#8221;Hello from compiled program!\n&#8221;);
    return 0;
}
EOF

# Compile
gcc hello.c -o hello
./hello
</code></code></pre><p>If <code>gcc</code> isn&#8217;t installed:</p><pre><code><code>sudo apt install build-essential -y 2&gt;/dev/null || sudo yum groupinstall &#8220;Development Tools&#8221; -y
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Check Repository Configuration</h2><pre><code><code># Ubuntu/Debian
cat /etc/apt/sources.list | head -n 10

# RHEL/CentOS
ls /etc/yum.repos.d/
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; Verify Package Integrity</h2><pre><code><code># Verify if curl is properly installed
dpkg -V curl 2&gt;/dev/null || rpm -V curl
</code></code></pre><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><ol><li><p>Check your Linux distro using <code>/etc/os-release</code>.</p></li><li><p>Use <code>dpkg -l</code> or <code>yum list installed</code> to view 10 installed packages.</p></li><li><p>Search for &#8220;git&#8221; and &#8220;wget&#8221; using <code>apt search</code> or <code>yum search</code>.</p></li><li><p>Install <code>wget</code> and verify it&#8217;s working (<code>wget --version</code>).</p></li><li><p>Remove and reinstall <code>wget</code>.</p></li><li><p>Display full package info using <code>apt show wget</code> or <code>yum info wget</code>.</p></li><li><p>List all files installed by <code>wget</code> (<code>dpkg -L wget</code> or <code>rpm -ql wget</code>).</p></li><li><p>Create and compile a <code>hello.c</code> program using <code>gcc</code>.</p></li><li><p>Run <code>ls /etc/yum.repos.d/</code> or view <code>/etc/apt/sources.list</code>.</p></li><li><p>Create a small shell script named <code>pkg_report.sh</code> that prints:</p></li></ol><pre><code><code>#!/bin/bash
echo &#8220;=== Package Summary ===&#8221;
dpkg -l | wc -l 2&gt;/dev/null || yum list installed | wc -l
echo &#8220;Total packages installed&#8221;
</code></code></pre><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>What is the difference between a package and a repository?</p></li><li><p>Which file extension is used for packages in Ubuntu vs RHEL?</p></li><li><p>What is the command to install software in Ubuntu?</p></li><li><p>How do you remove software in RHEL?</p></li><li><p>What command lists all installed packages?</p></li><li><p>What does <code>apt update</code> do?</p></li><li><p>What is the difference between <code>yum</code> and <code>dnf</code>?</p></li><li><p>How do you check which files belong to a package?</p></li><li><p>What command can compile source code manually?</p></li><li><p>Where are repository configuration files stored in RHEL/CentOS?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 7 Summary</strong><br>You learned:</p><ul><li><p>How Linux installs and manages software.</p></li><li><p>Package formats (<code>.deb</code> and <code>.rpm</code>).</p></li><li><p>Commands for installing, removing, and verifying packages.</p></li><li><p>How repositories work and how to compile software from source.</p></li></ul><div><hr></div><h1>Chapter 8 &#8211; Disk, Storage &amp; File System Management</h1><p><strong>Week 8 Objective:</strong><br>Learn how Linux sees storage devices, how to list them, format and mount them, manage virtual disks with <strong>LVM</strong>, understand <strong>/etc/fstab</strong>, quotas, and the idea of <strong>RAID</strong> &#8212; all without risking your data.</p><div><hr></div><h2>&#129504; 1. Layman&#8217;s Explanation &#8212; &#8220;The Warehouse Analogy&#8221;</h2><p>Imagine your computer as a <strong>warehouse</strong> &#127981;:</p><ul><li><p>The <strong>building</strong> = your physical disk.</p></li><li><p><strong>Rooms (partitions)</strong> = different sections inside the warehouse.</p></li><li><p><strong>Shelves (file systems)</strong> = how things are arranged (ext4, xfs, etc).</p></li><li><p><strong>Labels (mount points)</strong> = the doors through which you access a room (<code>/mnt</code>, <code>/home</code>).</p></li><li><p><strong>LVM</strong> = movable walls &#8212; you can resize rooms without rebuilding the whole warehouse.</p></li></ul><div><hr></div><h2>&#129513; 2. Basic Terminology</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!js_h!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b01c556-f5c0-427a-8727-4d4b64a46bd5_663x287.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!js_h!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b01c556-f5c0-427a-8727-4d4b64a46bd5_663x287.png 424w, https://substackcdn.com/image/fetch/$s_!js_h!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b01c556-f5c0-427a-8727-4d4b64a46bd5_663x287.png 848w, https://substackcdn.com/image/fetch/$s_!js_h!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b01c556-f5c0-427a-8727-4d4b64a46bd5_663x287.png 1272w, https://substackcdn.com/image/fetch/$s_!js_h!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b01c556-f5c0-427a-8727-4d4b64a46bd5_663x287.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!js_h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b01c556-f5c0-427a-8727-4d4b64a46bd5_663x287.png" width="663" height="287" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5b01c556-f5c0-427a-8727-4d4b64a46bd5_663x287.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:287,&quot;width&quot;:663,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:25990,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b01c556-f5c0-427a-8727-4d4b64a46bd5_663x287.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!js_h!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b01c556-f5c0-427a-8727-4d4b64a46bd5_663x287.png 424w, https://substackcdn.com/image/fetch/$s_!js_h!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b01c556-f5c0-427a-8727-4d4b64a46bd5_663x287.png 848w, https://substackcdn.com/image/fetch/$s_!js_h!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b01c556-f5c0-427a-8727-4d4b64a46bd5_663x287.png 1272w, https://substackcdn.com/image/fetch/$s_!js_h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b01c556-f5c0-427a-8727-4d4b64a46bd5_663x287.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129520; 3. Safe Read-Only Inspection Commands</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1Hkx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F048531ff-15d4-4eb1-be0a-12e044ec8bbc_563x246.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1Hkx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F048531ff-15d4-4eb1-be0a-12e044ec8bbc_563x246.png 424w, https://substackcdn.com/image/fetch/$s_!1Hkx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F048531ff-15d4-4eb1-be0a-12e044ec8bbc_563x246.png 848w, https://substackcdn.com/image/fetch/$s_!1Hkx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F048531ff-15d4-4eb1-be0a-12e044ec8bbc_563x246.png 1272w, https://substackcdn.com/image/fetch/$s_!1Hkx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F048531ff-15d4-4eb1-be0a-12e044ec8bbc_563x246.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1Hkx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F048531ff-15d4-4eb1-be0a-12e044ec8bbc_563x246.png" width="563" height="246" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/048531ff-15d4-4eb1-be0a-12e044ec8bbc_563x246.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:246,&quot;width&quot;:563,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:15952,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F048531ff-15d4-4eb1-be0a-12e044ec8bbc_563x246.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1Hkx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F048531ff-15d4-4eb1-be0a-12e044ec8bbc_563x246.png 424w, https://substackcdn.com/image/fetch/$s_!1Hkx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F048531ff-15d4-4eb1-be0a-12e044ec8bbc_563x246.png 848w, https://substackcdn.com/image/fetch/$s_!1Hkx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F048531ff-15d4-4eb1-be0a-12e044ec8bbc_563x246.png 1272w, https://substackcdn.com/image/fetch/$s_!1Hkx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F048531ff-15d4-4eb1-be0a-12e044ec8bbc_563x246.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h1>&#128187; Safe Practice in a Sandbox</h1><h3>Setup</h3><pre><code><code>mkdir -p /tmp/linux_course/week8
cd /tmp/linux_course/week8
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; List Disks and Mounts</h2><pre><code><code>echo &#8220;=== Block devices ===&#8221;
lsblk
echo
echo &#8220;=== Mounted filesystems ===&#8221;
df -hT
</code></code></pre><p><code>lsblk</code> shows hierarchy; <code>df -hT</code> shows space and filesystem type.</p><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; Create a Fake 20 MB Disk (File-based Loop Device)</h2><p><em>(safe; no real disks touched)</em></p><pre><code><code>dd if=/dev/zero of=fake_disk.img bs=1M count=20
ls -lh fake_disk.img
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Format and Mount the Fake Disk</h2><pre><code><code>sudo mkfs.ext4 fake_disk.img
mkdir -p /tmp/linux_course/week8/mnt_fake
sudo mount -o loop fake_disk.img /tmp/linux_course/week8/mnt_fake
df -h /tmp/linux_course/week8/mnt_fake
</code></code></pre><p>&#128161; You just made an <em>ext4 filesystem</em> inside a file and mounted it!</p><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; Write and Read from the Mounted Disk</h2><pre><code><code>echo &#8220;Hello from fake disk $(date)&#8221; | sudo tee /tmp/linux_course/week8/mnt_fake/test.txt
cat /tmp/linux_course/week8/mnt_fake/test.txt
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; Unmount and Verify</h2><pre><code><code>sudo umount /tmp/linux_course/week8/mnt_fake
file fake_disk.img
</code></code></pre><p>Output shows it&#8217;s an <strong>ext4 filesystem image</strong>.</p><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; View / etc / fstab (Read-Only)</h2><pre><code><code>grep -v &#8216;^#&#8217; /etc/fstab | column -t
</code></code></pre><p>Shows which filesystems mount automatically at boot.</p><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; Display UUID and Mount with UUID</h2><pre><code><code>sudo blkid fake_disk.img
# Use UUID to mount again (simulate entry)
UUID=$(sudo blkid -s UUID -o value fake_disk.img)
sudo mount -o loop,uuid=$UUID fake_disk.img /tmp/linux_course/week8/mnt_fake
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; Simulate LVM Workflow (Safe Concept Demo)</h2><p>We&#8217;ll only show the <em>commands</em>; run these <strong>inside a disposable VM</strong> if you want real practice.</p><pre><code><code># (Do not run on production systems)
sudo pvcreate /dev/sdb
sudo vgcreate vgdata /dev/sdb
sudo lvcreate -L 5G -n lvbackup vgdata
sudo mkfs.xfs /dev/vgdata/lvbackup
sudo mount /dev/vgdata/lvbackup /mnt
</code></code></pre><p>Conceptually:</p><ul><li><p>PV = Physical Volume (disk)</p></li><li><p>VG = Volume Group (pool)</p></li><li><p>LV = Logical Volume (mountable &#8220;drive&#8221;)</p></li></ul><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Disk Usage Analysis</h2><pre><code><code>du -sh /var /home /tmp 2&gt;/dev/null | sort -h
</code></code></pre><p>Shows folder sizes in ascending order.</p><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; Quota Concept Demo (Safe Sim)</h2><p>Quotas limit how much storage a user can use.</p><p>Conceptual steps (do inside VM):</p><pre><code><code>sudo apt install quota -y
sudo mount -o usrquota,grpquota /dev/sda1 /
sudo quotacheck -cum /
sudo quotaon /
sudo edquota username
</code></code></pre><div><hr></div><h1>&#129513; 10 Hands-On Exercises (Safe Mode)</h1><ol><li><p>Run <code>lsblk</code> and identify your primary disk.</p></li><li><p>Run <code>df -hT</code> and note mount points and filesystem types.</p></li><li><p>Create a 10 MB fake disk (<code>dd if=/dev/zero of=disk10.img bs=1M count=10</code>).</p></li><li><p>Format it with <code>mkfs.ext4</code> and mount under <code>/tmp/linux_course/week8/mnt10</code>.</p></li><li><p>Copy <code>/etc/hosts</code> into it and verify.</p></li><li><p>Unmount and check its type using <code>file</code>.</p></li><li><p>Run <code>blkid</code> and find its UUID.</p></li><li><p>Open <code>/etc/fstab</code> and locate the line for <code>/</code>.</p></li><li><p>Use <code>du -sh ~</code> to see how much space your home uses.</p></li><li><p>Write a script <code>disk_report.sh</code> that prints:</p></li></ol><pre><code><code>#!/bin/bash
echo &#8220;=== Disk Summary ===&#8221;
df -hT | grep -v tmpfs
echo &#8220;Largest directories:&#8221;
du -sh /* 2&gt;/dev/null | sort -hr | head -5
</code></code></pre><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>What command lists all block devices?</p></li><li><p>What is the difference between a partition and a filesystem?</p></li><li><p>What file determines which disks mount automatically at boot?</p></li><li><p>What does the <code>mount</code> command do?</p></li><li><p>How do you unmount a filesystem safely?</p></li><li><p>What is a loop device and why is it safe for practice?</p></li><li><p>Name three common Linux filesystems.</p></li><li><p>In LVM, what do PV, VG, and LV stand for?</p></li><li><p>What command shows disk usage per directory?</p></li><li><p>What is the main advantage of using LVM?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 8 Summary</strong><br>You learned:</p><ul><li><p>How to inspect and mount disks safely.</p></li><li><p>How to create and test filesystems using loop-back images.</p></li><li><p>The roles of <code>/etc/fstab</code>, UUIDs, and LVM.</p></li><li><p>Concepts of quotas and RAID (theory).</p></li></ul><div><hr></div><h1>Chapter 9 &#8211; System Startup &amp; Services</h1><p><strong>Week 9 Objective:</strong><br>Understand the <strong>boot process</strong>, manage and troubleshoot <strong>system services</strong>, and control which services start automatically.</p><div><hr></div><h2>&#129504; 1 &#8211; Layman&#8217;s Explanation &#8212; &#8220;The Morning Routine Analogy&#8221;</h2><p>Think of your computer as a person waking up in the morning:</p><ol><li><p><strong>BIOS/UEFI</strong> &#8594; Alarm clock rings (power on).</p></li><li><p><strong>Bootloader (GRUB)</strong> &#8594; Chooses which outfit (OS kernel) to wear.</p></li><li><p><strong>Kernel</strong> &#8594; Gets dressed and starts basic body functions (CPU, memory, devices).</p></li><li><p><strong>systemd</strong> &#8594; Morning planner that starts each task in the right order (network, login, GUI).</p></li><li><p><strong>User login</strong> &#8594; You&#8217;re ready for work!</p></li></ol><div><hr></div><h2>&#129513; 2 &#8211; Key Startup Components</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yz2_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6417eacd-f0c4-4392-bec9-91b3c853dc18_639x252.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yz2_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6417eacd-f0c4-4392-bec9-91b3c853dc18_639x252.png 424w, https://substackcdn.com/image/fetch/$s_!yz2_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6417eacd-f0c4-4392-bec9-91b3c853dc18_639x252.png 848w, https://substackcdn.com/image/fetch/$s_!yz2_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6417eacd-f0c4-4392-bec9-91b3c853dc18_639x252.png 1272w, https://substackcdn.com/image/fetch/$s_!yz2_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6417eacd-f0c4-4392-bec9-91b3c853dc18_639x252.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yz2_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6417eacd-f0c4-4392-bec9-91b3c853dc18_639x252.png" width="639" height="252" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6417eacd-f0c4-4392-bec9-91b3c853dc18_639x252.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:252,&quot;width&quot;:639,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:17646,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6417eacd-f0c4-4392-bec9-91b3c853dc18_639x252.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yz2_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6417eacd-f0c4-4392-bec9-91b3c853dc18_639x252.png 424w, https://substackcdn.com/image/fetch/$s_!yz2_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6417eacd-f0c4-4392-bec9-91b3c853dc18_639x252.png 848w, https://substackcdn.com/image/fetch/$s_!yz2_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6417eacd-f0c4-4392-bec9-91b3c853dc18_639x252.png 1272w, https://substackcdn.com/image/fetch/$s_!yz2_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6417eacd-f0c4-4392-bec9-91b3c853dc18_639x252.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129520; 3 &#8211; Important systemd Commands</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lYEF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93d91b95-b88b-4025-bd49-d99fa9ef996f_630x362.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lYEF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93d91b95-b88b-4025-bd49-d99fa9ef996f_630x362.png 424w, https://substackcdn.com/image/fetch/$s_!lYEF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93d91b95-b88b-4025-bd49-d99fa9ef996f_630x362.png 848w, https://substackcdn.com/image/fetch/$s_!lYEF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93d91b95-b88b-4025-bd49-d99fa9ef996f_630x362.png 1272w, https://substackcdn.com/image/fetch/$s_!lYEF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93d91b95-b88b-4025-bd49-d99fa9ef996f_630x362.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lYEF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93d91b95-b88b-4025-bd49-d99fa9ef996f_630x362.png" width="630" height="362" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/93d91b95-b88b-4025-bd49-d99fa9ef996f_630x362.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:362,&quot;width&quot;:630,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:27169,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93d91b95-b88b-4025-bd49-d99fa9ef996f_630x362.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lYEF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93d91b95-b88b-4025-bd49-d99fa9ef996f_630x362.png 424w, https://substackcdn.com/image/fetch/$s_!lYEF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93d91b95-b88b-4025-bd49-d99fa9ef996f_630x362.png 848w, https://substackcdn.com/image/fetch/$s_!lYEF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93d91b95-b88b-4025-bd49-d99fa9ef996f_630x362.png 1272w, https://substackcdn.com/image/fetch/$s_!lYEF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93d91b95-b88b-4025-bd49-d99fa9ef996f_630x362.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h1>&#128187; Safe Practice Examples</h1><h3>Setup</h3><pre><code><code>mkdir -p /tmp/linux_course/week9
cd /tmp/linux_course/week9
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; View Boot Time and Critical Path</h2><pre><code><code>systemd-analyze
systemd-analyze blame | head -15
</code></code></pre><p>Shows total boot time and which services took longest.</p><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; List Active Services</h2><pre><code><code>systemctl list-units --type=service | head -20
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Inspect a Specific Service</h2><pre><code><code>systemctl status ssh 2&gt;/dev/null || systemctl status systemd-journald
</code></code></pre><p>Scroll with arrows / press <code>q</code> to quit.</p><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; Start, Stop, Restart a Service</h2><p><em>(Try this only with a harmless service like cron or ssh if present.)</em></p><pre><code><code>sudo systemctl restart cron 2&gt;/dev/null || sudo systemctl restart ssh
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; Enable and Disable at Boot</h2><pre><code><code>sudo systemctl enable cron
sudo systemctl disable cron
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; Check Default Boot Target</h2><pre><code><code>systemctl get-default
</code></code></pre><p>Common targets:</p><ul><li><p><code>multi-user.target</code> &#8594; console mode</p></li><li><p><code>graphical.target</code> &#8594; GUI mode</p></li></ul><p>Change temporarily:</p><pre><code><code>sudo systemctl isolate multi-user.target
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; View Failed Services</h2><pre><code><code>systemctl --failed
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; Examine Logs with journalctl</h2><pre><code><code># Show messages from this boot
journalctl -b | head -20

# Show logs for a unit
journalctl -u ssh | tail -20
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Create a Custom Service (Unit File Demo)</h2><pre><code><code>cat &gt; hello.service &lt;&lt;&#8217;EOF&#8217;
[Unit]
Description=Simple Hello Service

[Service]
ExecStart=/bin/echo &#8220;Hello from systemd!&#8221;
Type=oneshot

[Install]
WantedBy=multi-user.target
EOF

sudo cp hello.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl start hello.service
sudo systemctl status hello.service
</code></code></pre><p>&#128161; This creates a service that prints a message and exits.</p><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; Simulate Boot Troubleshooting</h2><pre><code><code># View kernel boot messages
dmesg | head -20

# Show last reboot info
last reboot | head -5
</code></code></pre><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><ol><li><p>Run <code>systemd-analyze</code> and note your boot time.</p></li><li><p>List the 10 slowest boot services (<code>systemd-analyze blame | head -10</code>).</p></li><li><p>View the status of <code>cron</code> or <code>ssh</code> service.</p></li><li><p>Restart that service and verify it is active.</p></li><li><p>Enable the service to start at boot, then disable it.</p></li><li><p>Use <code>systemctl get-default</code> to see current target.</p></li><li><p>Switch to <code>multi-user.target</code> and then back to <code>graphical.target</code> (if applicable).</p></li><li><p>View all failed services.</p></li><li><p>Create and run the custom <code>hello.service</code> demo.</p></li><li><p>Use <code>journalctl -b | grep error</code> to list boot-time errors.</p></li></ol><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>What is the first process started by the Linux kernel?</p></li><li><p>What does <code>systemctl status sshd</code> show?</p></li><li><p>How do you list all running services?</p></li><li><p>What command shows the system&#8217;s default boot target?</p></li><li><p>How can you change the default boot target permanently?</p></li><li><p>Which file defines a custom service (unit file)?</p></li><li><p>What does <code>sudo systemctl enable nginx</code> do?</p></li><li><p>How can you view logs for a specific service?</p></li><li><p>What does <code>systemctl --failed</code> display?</p></li><li><p>Why is <code>systemd-analyze blame</code> useful for admins?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 9 Summary</strong><br>You learned:</p><ul><li><p>The entire Linux boot sequence and systemd&#8217;s role.</p></li><li><p>How to start, stop, enable, and inspect services.</p></li><li><p>How to analyze boot performance and troubleshoot failed units.</p></li><li><p>How to create a custom systemd service.</p></li></ul><div><hr></div><h1>Chapter 10 &#8211; Networking in Linux</h1><p><strong>Week 10 Objective:</strong><br>Understand how Linux handles networking, from interface configuration to connectivity testing, SSH access, and simple web/file transfers.</p><div><hr></div><h2>&#129504; 1 &#8211; Layman&#8217;s Explanation &#8212; &#8220;The Postal System Analogy&#8221;</h2><p>Think of the internet as a <strong>global postal network</strong>:</p><ul><li><p>Each <strong>computer</strong> is a <strong>house</strong>.</p></li><li><p>Its <strong>IP address</strong> is the <strong>street address</strong>.</p></li><li><p><strong>Packets</strong> are the <strong>letters</strong> you send.</p></li><li><p><strong>Routers</strong> are the <strong>post offices</strong> forwarding letters.</p></li><li><p><strong>DNS</strong> is the <strong>phone book</strong> translating names into addresses.</p></li></ul><div><hr></div><h2>&#129513; 2 &#8211; Key Concepts</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Joys!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2e122fa-39cd-4485-a196-41f490d03e56_677x284.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Joys!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2e122fa-39cd-4485-a196-41f490d03e56_677x284.png 424w, https://substackcdn.com/image/fetch/$s_!Joys!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2e122fa-39cd-4485-a196-41f490d03e56_677x284.png 848w, https://substackcdn.com/image/fetch/$s_!Joys!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2e122fa-39cd-4485-a196-41f490d03e56_677x284.png 1272w, https://substackcdn.com/image/fetch/$s_!Joys!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2e122fa-39cd-4485-a196-41f490d03e56_677x284.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Joys!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2e122fa-39cd-4485-a196-41f490d03e56_677x284.png" width="677" height="284" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e2e122fa-39cd-4485-a196-41f490d03e56_677x284.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:284,&quot;width&quot;:677,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:26555,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2e122fa-39cd-4485-a196-41f490d03e56_677x284.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Joys!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2e122fa-39cd-4485-a196-41f490d03e56_677x284.png 424w, https://substackcdn.com/image/fetch/$s_!Joys!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2e122fa-39cd-4485-a196-41f490d03e56_677x284.png 848w, https://substackcdn.com/image/fetch/$s_!Joys!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2e122fa-39cd-4485-a196-41f490d03e56_677x284.png 1272w, https://substackcdn.com/image/fetch/$s_!Joys!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2e122fa-39cd-4485-a196-41f490d03e56_677x284.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129520; 3 &#8211; Common Networking Commands</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yPn1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facae6b3b-68c1-4611-961b-8e769152e700_660x406.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yPn1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facae6b3b-68c1-4611-961b-8e769152e700_660x406.png 424w, https://substackcdn.com/image/fetch/$s_!yPn1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facae6b3b-68c1-4611-961b-8e769152e700_660x406.png 848w, https://substackcdn.com/image/fetch/$s_!yPn1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facae6b3b-68c1-4611-961b-8e769152e700_660x406.png 1272w, https://substackcdn.com/image/fetch/$s_!yPn1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facae6b3b-68c1-4611-961b-8e769152e700_660x406.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yPn1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facae6b3b-68c1-4611-961b-8e769152e700_660x406.png" width="660" height="406" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/acae6b3b-68c1-4611-961b-8e769152e700_660x406.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:406,&quot;width&quot;:660,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:27649,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facae6b3b-68c1-4611-961b-8e769152e700_660x406.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yPn1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facae6b3b-68c1-4611-961b-8e769152e700_660x406.png 424w, https://substackcdn.com/image/fetch/$s_!yPn1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facae6b3b-68c1-4611-961b-8e769152e700_660x406.png 848w, https://substackcdn.com/image/fetch/$s_!yPn1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facae6b3b-68c1-4611-961b-8e769152e700_660x406.png 1272w, https://substackcdn.com/image/fetch/$s_!yPn1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Facae6b3b-68c1-4611-961b-8e769152e700_660x406.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h1>&#128187; Safe Practice Examples</h1><h3>Setup</h3><pre><code><code>mkdir -p /tmp/linux_course/week10
cd /tmp/linux_course/week10
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; View Interfaces and Addresses</h2><pre><code><code>ip addr show | grep -E &#8216;inet | ^[0-9]&#8217;
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; Display Routing Table</h2><pre><code><code>ip route
</code></code></pre><p>Shows default gateway and network paths.</p><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Check Connectivity</h2><pre><code><code>ping -c 4 8.8.8.8
ping -c 4 google.com
</code></code></pre><p><code>-c 4</code> = stop after 4 pings.</p><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; Test DNS Resolution</h2><pre><code><code>nslookup openai.com || dig openai.com +short
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; Show and Change Hostname</h2><pre><code><code>hostname
sudo hostnamectl set-hostname linuxstudent
hostnamectl status
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; Show Listening Ports and Services</h2><pre><code><code>sudo ss -tuln | head -n 10
</code></code></pre><p>Shows TCP/UDP ports and bound processes.</p><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; Check Firewall Status (if available)</h2><pre><code><code>sudo ufw status 2&gt;/dev/null || sudo firewall-cmd --state 2&gt;/dev/null || echo &#8220;No firewall tool detected&#8221;
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; Transfer Files Between Systems (via SSH)</h2><p><em>(Needs another machine or VM with SSH enabled)</em></p><pre><code><code>scp hello.txt user@remotehost:/tmp/
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Run a Simple Web Server (Lab Demo)</h2><pre><code><code>echo &#8220;&lt;h1&gt;Hello Linux Networking&lt;/h1&gt;&#8221; &gt; index.html
python3 -m http.server 8080 &amp;
curl http://localhost:8080
</code></code></pre><p>Stop it:</p><pre><code><code>pkill -f &#8220;http.server&#8221;
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; Inspect Network Interfaces with nmcli (if available)</h2><pre><code><code>nmcli device status
</code></code></pre><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><ol><li><p>Show all interfaces with <code>ip addr</code>.</p></li><li><p>Display routing table using <code>ip route</code>.</p></li><li><p>Find your default gateway.</p></li><li><p>Ping <code>8.8.8.8</code> and <code>google.com</code> &#8212; note any difference.</p></li><li><p>Use <code>nslookup</code> to resolve <code>openai.com</code>.</p></li><li><p>Check your hostname with <code>hostnamectl</code>.</p></li><li><p>View open ports using <code>ss -tuln</code>.</p></li><li><p>Start the temporary Python web server and fetch its page using <code>curl</code>.</p></li><li><p>Stop the web server process.</p></li><li><p>Write a script <code>net_report.sh</code> that prints:</p></li></ol><pre><code><code>#!/bin/bash
echo &#8220;=== Network Report on $(date) ===&#8221;
hostname -f
ip addr show | grep inet
echo &#8220;Default Gateway:&#8221;
ip route | grep default
echo &#8220;DNS Check:&#8221;
nslookup openai.com | grep Address
</code></code></pre><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>What command shows all network interfaces and IP addresses?</p></li><li><p>What does <code>ip route</code> display?</p></li><li><p>How can you test connectivity to another host?</p></li><li><p>What is the purpose of a default gateway?</p></li><li><p>How do you resolve a hostname to an IP address?</p></li><li><p>What command shows the current system hostname?</p></li><li><p>What command lists listening network ports?</p></li><li><p>What tool starts a temporary HTTP server in Python 3?</p></li><li><p>What is the difference between <code>ping 8.8.8.8</code> and <code>ping google.com</code>?</p></li><li><p>What is the function of <code>nmcli</code>?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 10 Summary</strong><br>You learned how to:</p><ul><li><p>Inspect network interfaces and routes.</p></li><li><p>Test connectivity and DNS resolution.</p></li><li><p>Manage hostnames and view ports.</p></li><li><p>Run simple web/file transfer tests securely.</p></li></ul><div><hr></div><p></p><h1>Chapter 11 &#8211; Logging and System Monitoring</h1><p><strong>Week 11 Objective:</strong><br>Understand how Linux handles system logs, how to view them using <code>journalctl</code>, analyze <code>/var/log</code> files, set up log rotation, and monitor live system performance.</p><div><hr></div><h2>&#129504; 1 &#8211; Layman&#8217;s Explanation &#8212; &#8220;The Security Camera Analogy&#8221;</h2><p>Think of Linux as a <strong>smart building</strong>:</p><ul><li><p><strong>Logs</strong> are your <strong>CCTV recordings</strong> &#8212; every door open, alarm, or visitor gets recorded.</p></li><li><p><strong>journalctl</strong> is your <strong>control room monitor</strong>, showing live footage.</p></li><li><p><strong>logrotate</strong> is the <strong>security clerk</strong> that archives old footage.</p></li><li><p><strong>Monitoring tools (top, vmstat)</strong> are your <strong>building health sensors</strong> &#8212; checking temperature (CPU), air pressure (RAM), and power (disk I/O).</p></li></ul><div><hr></div><h2>&#129513; 2 &#8211; Key Log Types</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!otZo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8405c6f6-dbaa-4924-8c13-09431007b05d_649x288.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!otZo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8405c6f6-dbaa-4924-8c13-09431007b05d_649x288.png 424w, https://substackcdn.com/image/fetch/$s_!otZo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8405c6f6-dbaa-4924-8c13-09431007b05d_649x288.png 848w, https://substackcdn.com/image/fetch/$s_!otZo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8405c6f6-dbaa-4924-8c13-09431007b05d_649x288.png 1272w, https://substackcdn.com/image/fetch/$s_!otZo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8405c6f6-dbaa-4924-8c13-09431007b05d_649x288.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!otZo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8405c6f6-dbaa-4924-8c13-09431007b05d_649x288.png" width="649" height="288" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8405c6f6-dbaa-4924-8c13-09431007b05d_649x288.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:288,&quot;width&quot;:649,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:25176,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8405c6f6-dbaa-4924-8c13-09431007b05d_649x288.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!otZo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8405c6f6-dbaa-4924-8c13-09431007b05d_649x288.png 424w, https://substackcdn.com/image/fetch/$s_!otZo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8405c6f6-dbaa-4924-8c13-09431007b05d_649x288.png 848w, https://substackcdn.com/image/fetch/$s_!otZo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8405c6f6-dbaa-4924-8c13-09431007b05d_649x288.png 1272w, https://substackcdn.com/image/fetch/$s_!otZo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8405c6f6-dbaa-4924-8c13-09431007b05d_649x288.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129520; 3 &#8211; Important Commands</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4h8j!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ae6a4b-92cf-46b3-b498-f5152886f2b9_628x397.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4h8j!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ae6a4b-92cf-46b3-b498-f5152886f2b9_628x397.png 424w, https://substackcdn.com/image/fetch/$s_!4h8j!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ae6a4b-92cf-46b3-b498-f5152886f2b9_628x397.png 848w, https://substackcdn.com/image/fetch/$s_!4h8j!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ae6a4b-92cf-46b3-b498-f5152886f2b9_628x397.png 1272w, https://substackcdn.com/image/fetch/$s_!4h8j!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ae6a4b-92cf-46b3-b498-f5152886f2b9_628x397.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4h8j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ae6a4b-92cf-46b3-b498-f5152886f2b9_628x397.png" width="628" height="397" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f8ae6a4b-92cf-46b3-b498-f5152886f2b9_628x397.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:397,&quot;width&quot;:628,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:27829,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ae6a4b-92cf-46b3-b498-f5152886f2b9_628x397.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4h8j!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ae6a4b-92cf-46b3-b498-f5152886f2b9_628x397.png 424w, https://substackcdn.com/image/fetch/$s_!4h8j!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ae6a4b-92cf-46b3-b498-f5152886f2b9_628x397.png 848w, https://substackcdn.com/image/fetch/$s_!4h8j!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ae6a4b-92cf-46b3-b498-f5152886f2b9_628x397.png 1272w, https://substackcdn.com/image/fetch/$s_!4h8j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8ae6a4b-92cf-46b3-b498-f5152886f2b9_628x397.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h1>&#128187; Safe Practice Examples</h1><h3>Setup</h3><pre><code><code>mkdir -p /tmp/linux_course/week11
cd /tmp/linux_course/week11
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; Explore Log Files</h2><pre><code><code>ls /var/log | head -20
</code></code></pre><p>You&#8217;ll see logs like <code>syslog</code>, <code>auth.log</code>, <code>dmesg</code>, <code>kern.log</code>, <code>apt</code>.</p><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; View System Logs</h2><pre><code><code>sudo journalctl -b | head -20
</code></code></pre><p>Shows logs from the current boot session.</p><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Filter Logs by Service</h2><pre><code><code>sudo journalctl -u ssh | tail -20
</code></code></pre><p>Shows only SSH-related logs.</p><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; Follow Logs in Real-Time</h2><pre><code><code>sudo journalctl -f
</code></code></pre><p>Press <code>Ctrl + C</code> to stop following.</p><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; Show Only Errors and Warnings</h2><pre><code><code>sudo journalctl -p 3 -b | head -20
</code></code></pre><p>Priority <code>3</code> = errors;<br><code>4</code> = warnings;<br><code>5</code> = notices.</p><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; View Authentication Logs</h2><pre><code><code>sudo cat /var/log/auth.log | grep &#8220;Accepted&#8221;
</code></code></pre><p>Lists successful logins via SSH or terminal.</p><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; Kernel Logs</h2><pre><code><code>dmesg | tail -20
</code></code></pre><p>Shows recent hardware or driver messages.</p><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; Log Rotation (Safe Simulation)</h2><pre><code><code>sudo cat /etc/logrotate.conf | head -10
sudo ls /etc/logrotate.d/ | head -5
</code></code></pre><p>&#128161; <code>logrotate</code> automatically compresses and archives old logs (e.g., <code>syslog.1.gz</code>).</p><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Monitor System Resources (top &amp; vmstat)</h2><pre><code><code>top
# Press q to quit
</code></code></pre><p>Or:</p><pre><code><code>vmstat 2 5
</code></code></pre><p>Shows CPU, memory, and I/O stats every 2 seconds (5 times).</p><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; Disk and Memory Monitoring</h2><pre><code><code>free -h
df -h
iostat 2 3 2&gt;/dev/null || echo &#8220;Install sysstat for iostat&#8221;
</code></code></pre><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><ol><li><p>Run <code>ls /var/log</code> and list 10 log files.</p></li><li><p>Use <code>journalctl -b | head -20</code> to view current boot logs.</p></li><li><p>View the last 20 SSH-related messages using <code>journalctl -u ssh | tail</code>.</p></li><li><p>Show all error messages from the current boot (<code>journalctl -p 3 -b</code>).</p></li><li><p>Display all authentication logs containing &#8220;Failed password&#8221;.</p></li><li><p>Use <code>dmesg</code> to view the last 10 hardware messages.</p></li><li><p>Check your <code>logrotate</code> configuration (<code>cat /etc/logrotate.conf</code>).</p></li><li><p>Run <code>top</code> and identify the highest CPU-using process.</p></li><li><p>Run <code>df -h</code> to view free disk space.</p></li><li><p>Write a script <code>sys_report.sh</code>:</p></li></ol><pre><code><code>#!/bin/bash
echo &#8220;=== System Health Report ===&#8221;
date
echo
echo &#8220;--- Disk Usage ---&#8221;
df -h | grep -v tmpfs
echo
echo &#8220;--- Memory ---&#8221;
free -h
echo
echo &#8220;--- Top CPU Consumers ---&#8221;
ps -eo pid,comm,%cpu --sort=-%cpu | head -6
</code></code></pre><ol><li><p>Then <code>chmod +x sys_report.sh</code> and run it.</p></li></ol><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>Where are most Linux logs stored?</p></li><li><p>What command shows logs for a specific systemd service?</p></li><li><p>How do you view only the latest logs as they happen?</p></li><li><p>What is <code>logrotate</code> used for?</p></li><li><p>What is the function of <code>/var/log/auth.log</code>?</p></li><li><p>Which command shows kernel messages?</p></li><li><p>How do you check system logs for errors only?</p></li><li><p>What does the command <code>vmstat 2 5</code> do?</p></li><li><p>What is the difference between <code>df</code> and <code>free</code>?</p></li><li><p>What tool is used for viewing live CPU/memory processes interactively?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 11 Summary</strong><br>You learned:</p><ul><li><p>How Linux logging works (<code>journalctl</code>, <code>/var/log</code>, <code>dmesg</code>).</p></li><li><p>How to find errors and monitor logs in real time.</p></li><li><p>How to rotate logs automatically.</p></li><li><p>How to monitor CPU, memory, and disk usage with <code>top</code>, <code>vmstat</code>, and <code>df</code>.</p></li></ul><div><hr></div><h1>Chapter 12 &#8211; Backup and Recovery</h1><p><strong>Week 12 Objective:</strong><br>Learn how to create and restore backups using tools like <code>tar</code>, <code>rsync</code>, and <code>cron</code>.<br>Understand backup strategies, scheduling, and basic recovery principles.</p><div><hr></div><h2>&#129504; 1 &#8211; Layman&#8217;s Explanation &#8212; &#8220;The Library Analogy&#8221;</h2><p>Think of your server as a <strong>library</strong> &#128218;:</p><ul><li><p>The <strong>books</strong> = your files and data.</p></li><li><p>The <strong>backup</strong> = photocopies stored safely elsewhere.</p></li><li><p>The <strong>restore</strong> = bringing those copies back when something goes wrong.</p></li><li><p>The <strong>cron job</strong> = the librarian who automatically makes those photocopies every night.</p></li></ul><p>Without backups, one accidental delete = disaster.<br>With backups, you just smile and restore. &#128526;</p><div><hr></div><h2>&#129513; 2 &#8211; Backup Strategy Types</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JTVq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86e4b4d2-8907-4c41-b61a-c7179a91c38f_633x272.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JTVq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86e4b4d2-8907-4c41-b61a-c7179a91c38f_633x272.png 424w, https://substackcdn.com/image/fetch/$s_!JTVq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86e4b4d2-8907-4c41-b61a-c7179a91c38f_633x272.png 848w, https://substackcdn.com/image/fetch/$s_!JTVq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86e4b4d2-8907-4c41-b61a-c7179a91c38f_633x272.png 1272w, https://substackcdn.com/image/fetch/$s_!JTVq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86e4b4d2-8907-4c41-b61a-c7179a91c38f_633x272.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JTVq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86e4b4d2-8907-4c41-b61a-c7179a91c38f_633x272.png" width="633" height="272" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/86e4b4d2-8907-4c41-b61a-c7179a91c38f_633x272.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:272,&quot;width&quot;:633,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:27389,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86e4b4d2-8907-4c41-b61a-c7179a91c38f_633x272.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JTVq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86e4b4d2-8907-4c41-b61a-c7179a91c38f_633x272.png 424w, https://substackcdn.com/image/fetch/$s_!JTVq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86e4b4d2-8907-4c41-b61a-c7179a91c38f_633x272.png 848w, https://substackcdn.com/image/fetch/$s_!JTVq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86e4b4d2-8907-4c41-b61a-c7179a91c38f_633x272.png 1272w, https://substackcdn.com/image/fetch/$s_!JTVq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86e4b4d2-8907-4c41-b61a-c7179a91c38f_633x272.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129520; 3 &#8211; Essential Backup Tools</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!phc-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F911539d6-fc6a-4265-adfd-5b058170cbb5_647x284.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!phc-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F911539d6-fc6a-4265-adfd-5b058170cbb5_647x284.png 424w, https://substackcdn.com/image/fetch/$s_!phc-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F911539d6-fc6a-4265-adfd-5b058170cbb5_647x284.png 848w, https://substackcdn.com/image/fetch/$s_!phc-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F911539d6-fc6a-4265-adfd-5b058170cbb5_647x284.png 1272w, https://substackcdn.com/image/fetch/$s_!phc-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F911539d6-fc6a-4265-adfd-5b058170cbb5_647x284.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!phc-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F911539d6-fc6a-4265-adfd-5b058170cbb5_647x284.png" width="647" height="284" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/911539d6-fc6a-4265-adfd-5b058170cbb5_647x284.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:284,&quot;width&quot;:647,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:23970,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F911539d6-fc6a-4265-adfd-5b058170cbb5_647x284.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!phc-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F911539d6-fc6a-4265-adfd-5b058170cbb5_647x284.png 424w, https://substackcdn.com/image/fetch/$s_!phc-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F911539d6-fc6a-4265-adfd-5b058170cbb5_647x284.png 848w, https://substackcdn.com/image/fetch/$s_!phc-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F911539d6-fc6a-4265-adfd-5b058170cbb5_647x284.png 1272w, https://substackcdn.com/image/fetch/$s_!phc-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F911539d6-fc6a-4265-adfd-5b058170cbb5_647x284.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h1>&#128187; Safe Practice Examples</h1><h3>Setup</h3><pre><code><code>mkdir -p /tmp/linux_course/week12/source
mkdir -p /tmp/linux_course/week12/backups
cd /tmp/linux_course/week12
</code></code></pre><p>Create sample files:</p><pre><code><code>echo &#8220;Config File&#8221; &gt; source/config.txt
echo &#8220;Data File&#8221; &gt; source/data.log
ls source
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; Create a TAR Backup</h2><pre><code><code>tar -cvf backups/mybackup.tar source/
</code></code></pre><ul><li><p><code>c</code> = create</p></li><li><p><code>v</code> = verbose (show files)</p></li><li><p><code>f</code> = filename</p></li></ul><p>Verify:</p><pre><code><code>tar -tf backups/mybackup.tar
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; Compress Backup</h2><pre><code><code>gzip backups/mybackup.tar
ls backups/
</code></code></pre><p>File becomes <code>mybackup.tar.gz</code>.</p><p>To uncompress:</p><pre><code><code>gunzip backups/mybackup.tar.gz
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Restore from TAR Backup</h2><pre><code><code>rm -rf source
tar -xvf backups/mybackup.tar -C .
ls source/
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; Using rsync for Incremental Backups</h2><pre><code><code>mkdir -p /tmp/linux_course/week12/remote_backup
rsync -av source/ remote_backup/
</code></code></pre><p>Modify a file and re-run:</p><pre><code><code>echo &#8220;Updated line&#8221; &gt;&gt; source/config.txt
rsync -av source/ remote_backup/
</code></code></pre><p>&#9989; Only changed files get re-copied.</p><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; Automate Backup with Cron (Safe Demo)</h2><pre><code><code>crontab -l 2&gt;/dev/null
(crontab -l 2&gt;/dev/null; echo &#8220;0 2 * * * tar -czf /tmp/linux_course/week12/backups/auto_$(date +\%F).tar.gz /tmp/linux_course/week12/source&#8221;) | crontab -
</code></code></pre><p>This schedules a backup every day at <strong>2 AM</strong>.</p><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; Verify Backups</h2><pre><code><code>tar -tf backups/mybackup.tar | grep config
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; Simulate Remote Copy (scp)</h2><p><em>(Won&#8217;t actually connect &#8212; safe to read example only)</em></p><pre><code><code>scp backups/mybackup.tar user@192.168.1.100:/backup/
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; Partial Restore</h2><p>Extract only one file:</p><pre><code><code>tar -xvf backups/mybackup.tar source/config.txt
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Backup Verification Script</h2><pre><code><code>cat &gt; verify_backup.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
tar -tf backups/mybackup.tar &gt; /dev/null
if [ $? -eq 0 ]; then
  echo &#8220;Backup verified successfully &#9989;&#8221;
else
  echo &#8220;Backup corrupted &#10060;&#8221;
fi
EOF
chmod +x verify_backup.sh
./verify_backup.sh
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; Understanding Rescue Mode (Theory)</h2><p>If the system won&#8217;t boot:</p><ol><li><p>Boot from a <strong>Live Linux ISO</strong>.</p></li><li><p>Mount your main partition manually (e.g., <code>/mnt</code>).</p></li><li><p>Chroot into it: <code>chroot /mnt</code>.</p></li><li><p>Repair files, reinstall bootloader, or copy data out.</p></li></ol><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><ol><li><p>Create a <code>project/</code> directory with 3 files and back it up as <code>project_backup.tar</code>.</p></li><li><p>List files inside the TAR without extracting.</p></li><li><p>Extract only one file from the archive.</p></li><li><p>Compress the archive using <code>gzip</code>.</p></li><li><p>Create another folder and use <code>rsync</code> to copy data into it.</p></li><li><p>Modify one file and re-run <code>rsync</code>; observe changed files only.</p></li><li><p>Schedule a cron job to back up <code>/tmp/linux_course/week12/source</code> every minute (for test).</p></li><li><p>Verify the latest TAR file using <code>tar -tf</code>.</p></li><li><p>Write a script <code>daily_backup.sh</code> that creates a timestamped compressed backup.</p></li><li><p>Restore all files from your backup and verify integrity.</p></li></ol><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>What is the difference between full, incremental, and differential backups?</p></li><li><p>Which command is used to create a compressed archive of a directory?</p></li><li><p>How do you view the contents of a <code>.tar</code> file without extracting it?</p></li><li><p>What is the main advantage of <code>rsync</code> over <code>cp</code>?</p></li><li><p>What is the command to copy files securely to another host?</p></li><li><p>How can backups be automated daily at 2 AM?</p></li><li><p>How do you extract only one file from a TAR archive?</p></li><li><p>What does the <code>cron</code> field <code>0 2 * * *</code> mean?</p></li><li><p>What is the purpose of rescue mode?</p></li><li><p>Write a one-liner that backs up <code>/etc</code> into <code>/backup/etc_$(date +%F).tar.gz</code>.</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 12 Summary</strong><br>You learned:</p><ul><li><p>How to create, compress, and restore backups using <code>tar</code> and <code>rsync</code>.</p></li><li><p>How to automate backups using <code>cron</code>.</p></li><li><p>How to simulate remote backups using <code>scp</code>.</p></li><li><p>What to do in system recovery or rescue mode.</p></li></ul><div><hr></div><h1>Chapter 12 &#8211; Backup and Recovery</h1><p><strong>Week 12 Objective:</strong><br>Learn how to create and restore backups using tools like <code>tar</code>, <code>rsync</code>, and <code>cron</code>.<br>Understand backup strategies, scheduling, and basic recovery principles.</p><div><hr></div><h2>&#129504; 1 &#8211; Layman&#8217;s Explanation &#8212; &#8220;The Library Analogy&#8221;</h2><p>Think of your server as a <strong>library</strong> &#128218;:</p><ul><li><p>The <strong>books</strong> = your files and data.</p></li><li><p>The <strong>backup</strong> = photocopies stored safely elsewhere.</p></li><li><p>The <strong>restore</strong> = bringing those copies back when something goes wrong.</p></li><li><p>The <strong>cron job</strong> = the librarian who automatically makes those photocopies every night.</p></li></ul><p>Without backups, one accidental delete = disaster.<br>With backups, you just smile and restore. &#128526;</p><div><hr></div><h2>&#129513; 2 &#8211; Backup Strategy Types</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!83fC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdb93d7c-2200-451c-9a59-22ca6180dfd5_632x288.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!83fC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdb93d7c-2200-451c-9a59-22ca6180dfd5_632x288.png 424w, https://substackcdn.com/image/fetch/$s_!83fC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdb93d7c-2200-451c-9a59-22ca6180dfd5_632x288.png 848w, https://substackcdn.com/image/fetch/$s_!83fC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdb93d7c-2200-451c-9a59-22ca6180dfd5_632x288.png 1272w, https://substackcdn.com/image/fetch/$s_!83fC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdb93d7c-2200-451c-9a59-22ca6180dfd5_632x288.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!83fC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdb93d7c-2200-451c-9a59-22ca6180dfd5_632x288.png" width="632" height="288" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bdb93d7c-2200-451c-9a59-22ca6180dfd5_632x288.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:288,&quot;width&quot;:632,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:27633,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdb93d7c-2200-451c-9a59-22ca6180dfd5_632x288.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!83fC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdb93d7c-2200-451c-9a59-22ca6180dfd5_632x288.png 424w, https://substackcdn.com/image/fetch/$s_!83fC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdb93d7c-2200-451c-9a59-22ca6180dfd5_632x288.png 848w, https://substackcdn.com/image/fetch/$s_!83fC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdb93d7c-2200-451c-9a59-22ca6180dfd5_632x288.png 1272w, https://substackcdn.com/image/fetch/$s_!83fC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbdb93d7c-2200-451c-9a59-22ca6180dfd5_632x288.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129520; 3 &#8211; Essential Backup Tools</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hZar!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95fc2924-1462-4067-b3ab-65aa65ecb961_656x290.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hZar!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95fc2924-1462-4067-b3ab-65aa65ecb961_656x290.png 424w, https://substackcdn.com/image/fetch/$s_!hZar!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95fc2924-1462-4067-b3ab-65aa65ecb961_656x290.png 848w, https://substackcdn.com/image/fetch/$s_!hZar!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95fc2924-1462-4067-b3ab-65aa65ecb961_656x290.png 1272w, https://substackcdn.com/image/fetch/$s_!hZar!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95fc2924-1462-4067-b3ab-65aa65ecb961_656x290.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hZar!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95fc2924-1462-4067-b3ab-65aa65ecb961_656x290.png" width="656" height="290" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/95fc2924-1462-4067-b3ab-65aa65ecb961_656x290.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:290,&quot;width&quot;:656,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:24198,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95fc2924-1462-4067-b3ab-65aa65ecb961_656x290.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hZar!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95fc2924-1462-4067-b3ab-65aa65ecb961_656x290.png 424w, https://substackcdn.com/image/fetch/$s_!hZar!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95fc2924-1462-4067-b3ab-65aa65ecb961_656x290.png 848w, https://substackcdn.com/image/fetch/$s_!hZar!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95fc2924-1462-4067-b3ab-65aa65ecb961_656x290.png 1272w, https://substackcdn.com/image/fetch/$s_!hZar!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95fc2924-1462-4067-b3ab-65aa65ecb961_656x290.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h1>&#128187; Safe Practice Examples</h1><h3>Setup</h3><pre><code><code>mkdir -p /tmp/linux_course/week12/source
mkdir -p /tmp/linux_course/week12/backups
cd /tmp/linux_course/week12
</code></code></pre><p>Create sample files:</p><pre><code><code>echo &#8220;Config File&#8221; &gt; source/config.txt
echo &#8220;Data File&#8221; &gt; source/data.log
ls source
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; Create a TAR Backup</h2><pre><code><code>tar -cvf backups/mybackup.tar source/
</code></code></pre><ul><li><p><code>c</code> = create</p></li><li><p><code>v</code> = verbose (show files)</p></li><li><p><code>f</code> = filename</p></li></ul><p>Verify:</p><pre><code><code>tar -tf backups/mybackup.tar
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; Compress Backup</h2><pre><code><code>gzip backups/mybackup.tar
ls backups/
</code></code></pre><p>File becomes <code>mybackup.tar.gz</code>.</p><p>To uncompress:</p><pre><code><code>gunzip backups/mybackup.tar.gz
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Restore from TAR Backup</h2><pre><code><code>rm -rf source
tar -xvf backups/mybackup.tar -C .
ls source/
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; Using rsync for Incremental Backups</h2><pre><code><code>mkdir -p /tmp/linux_course/week12/remote_backup
rsync -av source/ remote_backup/
</code></code></pre><p>Modify a file and re-run:</p><pre><code><code>echo &#8220;Updated line&#8221; &gt;&gt; source/config.txt
rsync -av source/ remote_backup/
</code></code></pre><p>&#9989; Only changed files get re-copied.</p><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; Automate Backup with Cron (Safe Demo)</h2><pre><code><code>crontab -l 2&gt;/dev/null
(crontab -l 2&gt;/dev/null; echo &#8220;0 2 * * * tar -czf /tmp/linux_course/week12/backups/auto_$(date +\%F).tar.gz /tmp/linux_course/week12/source&#8221;) | crontab -
</code></code></pre><p>This schedules a backup every day at <strong>2 AM</strong>.</p><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; Verify Backups</h2><pre><code><code>tar -tf backups/mybackup.tar | grep config
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; Simulate Remote Copy (scp)</h2><p><em>(Won&#8217;t actually connect &#8212; safe to read example only)</em></p><pre><code><code>scp backups/mybackup.tar user@192.168.1.100:/backup/
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; Partial Restore</h2><p>Extract only one file:</p><pre><code><code>tar -xvf backups/mybackup.tar source/config.txt
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Backup Verification Script</h2><pre><code><code>cat &gt; verify_backup.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
tar -tf backups/mybackup.tar &gt; /dev/null
if [ $? -eq 0 ]; then
  echo &#8220;Backup verified successfully &#9989;&#8221;
else
  echo &#8220;Backup corrupted &#10060;&#8221;
fi
EOF
chmod +x verify_backup.sh
./verify_backup.sh
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; Understanding Rescue Mode (Theory)</h2><p>If the system won&#8217;t boot:</p><ol><li><p>Boot from a <strong>Live Linux ISO</strong>.</p></li><li><p>Mount your main partition manually (e.g., <code>/mnt</code>).</p></li><li><p>Chroot into it: <code>chroot /mnt</code>.</p></li><li><p>Repair files, reinstall bootloader, or copy data out.</p></li></ol><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><ol><li><p>Create a <code>project/</code> directory with 3 files and back it up as <code>project_backup.tar</code>.</p></li><li><p>List files inside the TAR without extracting.</p></li><li><p>Extract only one file from the archive.</p></li><li><p>Compress the archive using <code>gzip</code>.</p></li><li><p>Create another folder and use <code>rsync</code> to copy data into it.</p></li><li><p>Modify one file and re-run <code>rsync</code>; observe changed files only.</p></li><li><p>Schedule a cron job to back up <code>/tmp/linux_course/week12/source</code> every minute (for test).</p></li><li><p>Verify the latest TAR file using <code>tar -tf</code>.</p></li><li><p>Write a script <code>daily_backup.sh</code> that creates a timestamped compressed backup.</p></li><li><p>Restore all files from your backup and verify integrity.</p></li></ol><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>What is the difference between full, incremental, and differential backups?</p></li><li><p>Which command is used to create a compressed archive of a directory?</p></li><li><p>How do you view the contents of a <code>.tar</code> file without extracting it?</p></li><li><p>What is the main advantage of <code>rsync</code> over <code>cp</code>?</p></li><li><p>What is the command to copy files securely to another host?</p></li><li><p>How can backups be automated daily at 2 AM?</p></li><li><p>How do you extract only one file from a TAR archive?</p></li><li><p>What does the <code>cron</code> field <code>0 2 * * *</code> mean?</p></li><li><p>What is the purpose of rescue mode?</p></li><li><p>Write a one-liner that backs up <code>/etc</code> into <code>/backup/etc_$(date +%F).tar.gz</code>.</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 12 Summary</strong><br>You learned:</p><ul><li><p>How to create, compress, and restore backups using <code>tar</code> and <code>rsync</code>.</p></li><li><p>How to automate backups using <code>cron</code>.</p></li><li><p>How to simulate remote backups using <code>scp</code>.</p></li><li><p>What to do in system recovery or rescue mode.</p></li></ul><div><hr></div><h1>Chapter 13 &#8211; Linux Security and Hardening</h1><p><strong>Week 13 Objective:</strong><br>Learn how to secure Linux systems through SSH hardening, sudo control, firewalls, SELinux/AppArmor, file-level protection, and auditing.</p><div><hr></div><h2>&#129504; 1 &#8211; Layman&#8217;s Explanation &#8212; &#8220;The Castle Analogy&#8221;</h2><p>Imagine your Linux system as a <strong>castle</strong> &#127984;:</p><ul><li><p><strong>Walls</strong> = firewalls (block unwanted visitors)</p></li><li><p><strong>Keys</strong> = SSH keys (secure entry)</p></li><li><p><strong>Guards</strong> = sudo rules (who can do what)</p></li><li><p><strong>Surveillance cameras</strong> = audit logs (who did what)</p></li><li><p><strong>Locked rooms</strong> = SELinux (restrict what processes can access)</p></li></ul><div><hr></div><h2>&#129513; 2 &#8211; Linux Security Layers</h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sFpE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44251e52-6ead-41e0-8a7d-9aabeb4e09b1_647x235.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sFpE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44251e52-6ead-41e0-8a7d-9aabeb4e09b1_647x235.png 424w, https://substackcdn.com/image/fetch/$s_!sFpE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44251e52-6ead-41e0-8a7d-9aabeb4e09b1_647x235.png 848w, https://substackcdn.com/image/fetch/$s_!sFpE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44251e52-6ead-41e0-8a7d-9aabeb4e09b1_647x235.png 1272w, https://substackcdn.com/image/fetch/$s_!sFpE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44251e52-6ead-41e0-8a7d-9aabeb4e09b1_647x235.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sFpE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44251e52-6ead-41e0-8a7d-9aabeb4e09b1_647x235.png" width="647" height="235" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/44251e52-6ead-41e0-8a7d-9aabeb4e09b1_647x235.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:235,&quot;width&quot;:647,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:20051,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44251e52-6ead-41e0-8a7d-9aabeb4e09b1_647x235.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!sFpE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44251e52-6ead-41e0-8a7d-9aabeb4e09b1_647x235.png 424w, https://substackcdn.com/image/fetch/$s_!sFpE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44251e52-6ead-41e0-8a7d-9aabeb4e09b1_647x235.png 848w, https://substackcdn.com/image/fetch/$s_!sFpE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44251e52-6ead-41e0-8a7d-9aabeb4e09b1_647x235.png 1272w, https://substackcdn.com/image/fetch/$s_!sFpE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44251e52-6ead-41e0-8a7d-9aabeb4e09b1_647x235.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><div><hr></div><h1>&#128187; Let&#8217;s Begin Practically</h1><h3>Setup</h3><pre><code><code>mkdir -p /tmp/linux_course/week13
cd /tmp/linux_course/week13
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; Check Current Users &amp; SSH Access</h2><pre><code><code>whoami
who
last | head -5
</code></code></pre><p>Shows who is logged in and recent logins.</p><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; SSH Configuration (Safe Read-Only Check)</h2><p>View SSH server settings:</p><pre><code><code>sudo grep -E &#8220;Port|PermitRootLogin|PasswordAuthentication&#8221; /etc/ssh/sshd_config
</code></code></pre><p>&#9989; Recommended values:</p><pre><code><code>Port 22
PermitRootLogin no
PasswordAuthentication no
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Generate and Use SSH Keys</h2><p><em>(Safe to run on your own system)</em></p><pre><code><code>ssh-keygen -t rsa -b 4096 -C &#8220;bavi@careerbytecode&#8221;
</code></code></pre><p>This creates:</p><pre><code><code>~/.ssh/id_rsa (private key)
~/.ssh/id_rsa.pub (public key)
</code></code></pre><p>To copy key to a remote server:</p><pre><code><code>ssh-copy-id user@server_ip
</code></code></pre><p>Then login passwordlessly:</p><pre><code><code>ssh user@server_ip
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; Sudo Configuration</h2><p>List sudo users:</p><pre><code><code>sudo grep &#8216;sudo&#8217; /etc/group
</code></code></pre><p>Give user sudo rights:</p><pre><code><code>sudo usermod -aG sudo bavi
</code></code></pre><p>Safely test:</p><pre><code><code>sudo whoami
</code></code></pre><p>&#9989; Output: <code>root</code></p><p>View sudo logs:</p><pre><code><code>sudo cat /var/log/auth.log | grep sudo | tail
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; Using Firewalls (ufw or firewalld)</h2><h3>For Ubuntu/Debian:</h3><pre><code><code>sudo ufw status
sudo ufw allow 22/tcp
sudo ufw enable
</code></code></pre><h3>For RHEL/CentOS:</h3><pre><code><code>sudo firewall-cmd --state
sudo firewall-cmd --add-service=ssh --permanent
sudo firewall-cmd --reload
</code></code></pre><p>List rules:</p><pre><code><code>sudo iptables -L -n | head
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; SELinux/AppArmor Overview (Read-Only)</h2><p>Check SELinux status:</p><pre><code><code>getenforce 2&gt;/dev/null || echo &#8220;SELinux not installed&#8221;
</code></code></pre><p>Modes:</p><ul><li><p><strong>Enforcing:</strong> Strict security</p></li><li><p><strong>Permissive:</strong> Logs violations</p></li><li><p><strong>Disabled:</strong> Not active</p></li></ul><p>AppArmor alternative:</p><pre><code><code>sudo aa-status 2&gt;/dev/null || echo &#8220;AppArmor not installed&#8221;
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; Secure File Permissions</h2><p>Create secure file:</p><pre><code><code>echo &#8220;Secret credentials&#8221; &gt; secret.txt
chmod 600 secret.txt
ls -l secret.txt
</code></code></pre><p>Only the file owner can read/write.</p><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; File Integrity Check (sha256sum)</h2><pre><code><code>sha256sum secret.txt &gt; hash.txt
echo &#8220;Secret credentials changed&#8221; &gt; secret.txt
sha256sum -c hash.txt
</code></code></pre><p>&#9989; Alerts if file has been altered.</p><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Auditing with auditd</h2><p>Install (if available):</p><pre><code><code>sudo apt install auditd -y 2&gt;/dev/null || sudo yum install audit -y 2&gt;/dev/null
sudo systemctl enable --now auditd
</code></code></pre><p>Monitor <code>/etc/passwd</code> changes:</p><pre><code><code>sudo auditctl -w /etc/passwd -p wa -k passwd_changes
sudo ausearch -k passwd_changes
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; Security Check Script</h2><pre><code><code>cat &gt; system_check.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
echo &#8220;=== SECURITY CHECK REPORT ===&#8221;
echo &#8220;Date: $(date)&#8221;
echo
echo &#8220;[1] Active Users:&#8221;
who
echo
echo &#8220;[2] Sudo Users:&#8221;
grep sudo /etc/group
echo
echo &#8220;[3] SSH Config Summary:&#8221;
grep -E &#8220;Port|PermitRootLogin|PasswordAuthentication&#8221; /etc/ssh/sshd_config
echo
echo &#8220;[4] Firewall Status:&#8221;
sudo ufw status 2&gt;/dev/null || sudo firewall-cmd --list-all 2&gt;/dev/null
echo
echo &#8220;[5] SELinux Status:&#8221;
getenforce 2&gt;/dev/null || echo &#8220;AppArmor/SELinux not active&#8221;
EOF
chmod +x system_check.sh
./system_check.sh
</code></code></pre><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><ol><li><p>Run <code>who</code> and <code>last</code> to view logged-in users.</p></li><li><p>Open <code>/etc/ssh/sshd_config</code> (read-only) and check if root login is disabled.</p></li><li><p>Generate an SSH key using <code>ssh-keygen</code>.</p></li><li><p>Copy your public key to a remote or local test server (<code>ssh-copy-id</code>).</p></li><li><p>Add your user to the <code>sudo</code> group and verify <code>sudo whoami</code>.</p></li><li><p>Enable your firewall and allow only port 22 (SSH).</p></li><li><p>Check SELinux/AppArmor status using <code>getenforce</code> or <code>aa-status</code>.</p></li><li><p>Create a file <code>secure.txt</code> and set permission <code>chmod 600</code>.</p></li><li><p>Generate SHA checksum for <code>secure.txt</code> and verify it later.</p></li><li><p>Run the <code>system_check.sh</code> script and review the output.</p></li></ol><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>What is the purpose of disabling <code>PermitRootLogin</code> in SSH?</p></li><li><p>What&#8217;s the difference between <code>PasswordAuthentication</code> and <code>KeyAuthentication</code> in SSH?</p></li><li><p>How can you safely give a user administrative privileges?</p></li><li><p>What is the command to allow port 80 in ufw?</p></li><li><p>What is SELinux and what are its modes?</p></li><li><p>How can you verify if a file has been modified using a hash?</p></li><li><p>What does auditd do?</p></li><li><p>What command lists all active firewall rules?</p></li><li><p>What does <code>chmod 600</code> mean?</p></li><li><p>Why should logs like <code>/var/log/auth.log</code> be regularly monitored?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 13 Summary</strong><br>You learned how to:</p><ul><li><p>Secure SSH access using key authentication.</p></li><li><p>Configure sudo and least-privilege access.</p></li><li><p>Manage firewall rules (ufw/firewalld/iptables).</p></li><li><p>Check SELinux/AppArmor enforcement.</p></li><li><p>Audit and verify system integrity.</p></li></ul><div><hr></div><h1>Chapter 14 &#8211; Performance Tuning and Troubleshooting</h1><p><strong>Week 14 Objective:</strong><br>Learn how to identify, analyze, and optimize performance issues in Linux using built-in tools and safe kernel parameter tuning.</p><div><hr></div><h2>&#129504; 1 &#8211; Layman&#8217;s Explanation &#8212; &#8220;The Car Analogy&#8221;</h2><p>Think of Linux like a <strong>car</strong> &#128663;:</p><ul><li><p><strong>CPU</strong> = engine horsepower.</p></li><li><p><strong>Memory (RAM)</strong> = fuel tank.</p></li><li><p><strong>Disk I/O</strong> = tires&#8217; grip on the road.</p></li><li><p><strong>Kernel</strong> = onboard computer managing everything.</p></li><li><p><strong>sysctl</strong> = dashboard tuning knobs to adjust engine performance.</p></li></ul><p>If the car slows down &#8212; you check the <strong>engine</strong>, <strong>fuel</strong>, or <strong>road</strong>; same logic for servers!</p><div><hr></div><h2>&#129513; 2 &#8211; Common Causes of Poor Performance</h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LQZ5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d7de86d-d377-41a5-a843-c27a5f0f5f86_625x234.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LQZ5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d7de86d-d377-41a5-a843-c27a5f0f5f86_625x234.png 424w, https://substackcdn.com/image/fetch/$s_!LQZ5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d7de86d-d377-41a5-a843-c27a5f0f5f86_625x234.png 848w, https://substackcdn.com/image/fetch/$s_!LQZ5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d7de86d-d377-41a5-a843-c27a5f0f5f86_625x234.png 1272w, https://substackcdn.com/image/fetch/$s_!LQZ5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d7de86d-d377-41a5-a843-c27a5f0f5f86_625x234.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LQZ5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d7de86d-d377-41a5-a843-c27a5f0f5f86_625x234.png" width="625" height="234" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3d7de86d-d377-41a5-a843-c27a5f0f5f86_625x234.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:234,&quot;width&quot;:625,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:19799,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d7de86d-d377-41a5-a843-c27a5f0f5f86_625x234.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LQZ5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d7de86d-d377-41a5-a843-c27a5f0f5f86_625x234.png 424w, https://substackcdn.com/image/fetch/$s_!LQZ5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d7de86d-d377-41a5-a843-c27a5f0f5f86_625x234.png 848w, https://substackcdn.com/image/fetch/$s_!LQZ5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d7de86d-d377-41a5-a843-c27a5f0f5f86_625x234.png 1272w, https://substackcdn.com/image/fetch/$s_!LQZ5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d7de86d-d377-41a5-a843-c27a5f0f5f86_625x234.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129520; 3 &#8211; Key Diagnostic Tools</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KzBW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F826bc648-c789-4fc5-85f0-998807d321e1_627x285.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KzBW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F826bc648-c789-4fc5-85f0-998807d321e1_627x285.png 424w, https://substackcdn.com/image/fetch/$s_!KzBW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F826bc648-c789-4fc5-85f0-998807d321e1_627x285.png 848w, https://substackcdn.com/image/fetch/$s_!KzBW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F826bc648-c789-4fc5-85f0-998807d321e1_627x285.png 1272w, https://substackcdn.com/image/fetch/$s_!KzBW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F826bc648-c789-4fc5-85f0-998807d321e1_627x285.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KzBW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F826bc648-c789-4fc5-85f0-998807d321e1_627x285.png" width="627" height="285" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/826bc648-c789-4fc5-85f0-998807d321e1_627x285.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:285,&quot;width&quot;:627,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:19462,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F826bc648-c789-4fc5-85f0-998807d321e1_627x285.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!KzBW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F826bc648-c789-4fc5-85f0-998807d321e1_627x285.png 424w, https://substackcdn.com/image/fetch/$s_!KzBW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F826bc648-c789-4fc5-85f0-998807d321e1_627x285.png 848w, https://substackcdn.com/image/fetch/$s_!KzBW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F826bc648-c789-4fc5-85f0-998807d321e1_627x285.png 1272w, https://substackcdn.com/image/fetch/$s_!KzBW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F826bc648-c789-4fc5-85f0-998807d321e1_627x285.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h1>&#128187; Safe Practice Environment</h1><pre><code><code>mkdir -p /tmp/linux_course/week14
cd /tmp/linux_course/week14
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; Checking System Load</h2><pre><code><code>uptime
</code></code></pre><p>Output:</p><pre><code><code>20:00:01 up 5 days, 3:12, 2 users, load average: 0.35, 0.50, 0.40
</code></code></pre><p>&#128161; <strong>Load average</strong> = number of running/waiting processes.<br>Rule of thumb:</p><ul><li><p>1.0 = fully used single core.</p></li><li><p>On 4-core CPU, up to 4.0 is acceptable.</p></li></ul><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; Monitor CPU and Memory</h2><pre><code><code>top
</code></code></pre><ul><li><p><code>P</code> &#8594; sort by CPU</p></li><li><p><code>M</code> &#8594; sort by memory</p></li><li><p><code>q</code> &#8594; quit</p></li></ul><p>Alternative:</p><pre><code><code>vmstat 2 5
</code></code></pre><p>Shows CPU idle, wait time, and swap activity every 2 seconds (5 times).</p><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Memory Analysis</h2><pre><code><code>free -h
</code></code></pre><p>Displays total, used, and free RAM including swap.</p><p>To see swap activity:</p><pre><code><code>swapon --show
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; Disk I/O Monitoring</h2><pre><code><code>df -hT
iostat -x 2 3 2&gt;/dev/null || echo &#8220;Install sysstat package for iostat&#8221;
</code></code></pre><ul><li><p><code>df</code> &#8594; disk space usage</p></li><li><p><code>iostat</code> &#8594; read/write activity</p></li></ul><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; Find Largest Disk Usage</h2><pre><code><code>du -ah /var | sort -rh | head -10
</code></code></pre><p>Lists top 10 space-consuming files.</p><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; Monitor Kernel Messages</h2><pre><code><code>dmesg | tail -20
</code></code></pre><p>Shows hardware or system warnings (e.g., &#8220;Out of memory&#8221; or &#8220;I/O error&#8221;).</p><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; System Resource Limits</h2><pre><code><code>ulimit -a
</code></code></pre><p>Shows user limits (max file size, open files, etc.)</p><p>To temporarily increase file limit:</p><pre><code><code>ulimit -n 4096
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; Tune Kernel Parameters Safely</h2><p>Check a value:</p><pre><code><code>sysctl net.ipv4.ip_forward
</code></code></pre><p>Enable IP forwarding temporarily:</p><pre><code><code>sudo sysctl -w net.ipv4.ip_forward=1
</code></code></pre><p>Make it persistent (demo only):</p><pre><code><code>echo &#8220;net.ipv4.ip_forward = 1&#8221; | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Check Process Tree and Zombie Processes</h2><pre><code><code>pstree -p | head -15
ps aux | grep &#8216;Z&#8217;
</code></code></pre><p>Zombie (<code>Z</code>) = process finished but parent didn&#8217;t clean up.</p><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; System Health Script</h2><pre><code><code>cat &gt; perf_check.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
echo &#8220;=== System Performance Report ===&#8221;
date
echo &#8220;--- CPU Load ---&#8221;
uptime
echo
echo &#8220;--- Memory ---&#8221;
free -h
echo
echo &#8220;--- Disk Usage ---&#8221;
df -h | grep -v tmpfs
echo
echo &#8220;--- Top 5 CPU-consuming Processes ---&#8221;
ps -eo pid,comm,%cpu --sort=-%cpu | head -6
EOF
chmod +x perf_check.sh
./perf_check.sh
</code></code></pre><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><ol><li><p>Run <code>uptime</code> and note the load average.</p></li><li><p>Use <code>top</code> and identify the process using most CPU.</p></li><li><p>Use <code>free -h</code> to check available memory.</p></li><li><p>Run <code>vmstat 2 5</code> and watch for swap activity.</p></li><li><p>Check disk usage with <code>df -hT</code>.</p></li><li><p>Find top 5 largest files under <code>/var</code> using <code>du</code>.</p></li><li><p>View kernel messages using <code>dmesg | tail</code>.</p></li><li><p>Use <code>ulimit -a</code> to check open file limits.</p></li><li><p>Temporarily enable IP forwarding with <code>sysctl -w</code>.</p></li><li><p>Run your <code>perf_check.sh</code> report script.</p></li></ol><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>What does &#8220;load average&#8221; represent?</p></li><li><p>How do you check free and used memory?</p></li><li><p>What is the function of the <code>vmstat</code> command?</p></li><li><p>How do you monitor disk I/O in Linux?</p></li><li><p>What command lists the top 10 largest files?</p></li><li><p>What is a zombie process?</p></li><li><p>What does the command <code>ulimit -a</code> show?</p></li><li><p>How can you temporarily modify a kernel parameter?</p></li><li><p>What command displays kernel log messages?</p></li><li><p>What tool helps you identify the process using most CPU?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 14 Summary</strong><br>You learned:</p><ul><li><p>How to measure CPU, memory, and I/O performance.</p></li><li><p>How to interpret load averages.</p></li><li><p>How to view kernel logs and tune sysctl safely.</p></li><li><p>How to automate performance checks with a script.</p></li></ul><div><hr></div><h1>Chapter 15 &#8211; Bash Scripting &amp; Automation &#129504;&#128187;</h1><p>This chapter transforms you from a <em>command runner</em> into a <em>command creator</em>.<br>You&#8217;ll learn how to <strong>automate repetitive admin tasks</strong>, write reusable scripts, and handle files, loops, conditionals, and functions.</p><p>All examples are safe to execute under <code>/tmp/linux_course/week15</code>.</p><div><hr></div><h2>&#128467;&#65039; Week 15 Objective</h2><p>Learn how to write, execute, and debug <strong>Bash shell scripts</strong> to automate Linux tasks like backups, user creation, and cleanup.</p><div><hr></div><h2>&#129504; 1 &#8211; Layman&#8217;s Explanation &#8212; &#8220;The Robot Assistant Analogy&#8221;</h2><p>Imagine Bash as your <strong>personal robot assistant</strong> &#129302;:</p><ul><li><p>You <strong>teach</strong> it by writing instructions (scripts).</p></li><li><p>It <strong>remembers and executes</strong> them line by line.</p></li><li><p>If you give it logic (<code>if</code>, <code>for</code>, <code>while</code>), it makes decisions on its own.</p></li><li><p>If something goes wrong, you can <strong>debug</strong> and fix its instructions.</p></li></ul><div><hr></div><h2>&#129513; 2 &#8211; What Is a Bash Script?</h2><p>A <strong>Bash script</strong> is just a text file with commands that run automatically.</p><h3>Basic Example:</h3><pre><code><code>#!/bin/bash
echo &#8220;Hello, Linux World!&#8221;
</code></code></pre><p><code>#!/bin/bash</code> &#8212; called a <strong>shebang</strong>, tells the OS which interpreter to use.</p><p>To make it executable:</p><pre><code><code>chmod +x hello.sh
./hello.sh
</code></code></pre><p>&#9989; Output:</p><pre><code><code>Hello, Linux World!
</code></code></pre><div><hr></div><h2>&#129520; 3 &#8211; Script Essentials Cheat Sheet</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OvrC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda90c000-be0a-4fbe-ad4f-eb490e083a0d_655x405.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OvrC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda90c000-be0a-4fbe-ad4f-eb490e083a0d_655x405.png 424w, https://substackcdn.com/image/fetch/$s_!OvrC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda90c000-be0a-4fbe-ad4f-eb490e083a0d_655x405.png 848w, https://substackcdn.com/image/fetch/$s_!OvrC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda90c000-be0a-4fbe-ad4f-eb490e083a0d_655x405.png 1272w, https://substackcdn.com/image/fetch/$s_!OvrC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda90c000-be0a-4fbe-ad4f-eb490e083a0d_655x405.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OvrC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda90c000-be0a-4fbe-ad4f-eb490e083a0d_655x405.png" width="655" height="405" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/da90c000-be0a-4fbe-ad4f-eb490e083a0d_655x405.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:405,&quot;width&quot;:655,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:29404,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda90c000-be0a-4fbe-ad4f-eb490e083a0d_655x405.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OvrC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda90c000-be0a-4fbe-ad4f-eb490e083a0d_655x405.png 424w, https://substackcdn.com/image/fetch/$s_!OvrC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda90c000-be0a-4fbe-ad4f-eb490e083a0d_655x405.png 848w, https://substackcdn.com/image/fetch/$s_!OvrC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda90c000-be0a-4fbe-ad4f-eb490e083a0d_655x405.png 1272w, https://substackcdn.com/image/fetch/$s_!OvrC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fda90c000-be0a-4fbe-ad4f-eb490e083a0d_655x405.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h1>&#128187; Practice Setup</h1><pre><code><code>mkdir -p /tmp/linux_course/week15
cd /tmp/linux_course/week15
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; Hello Script</h2><pre><code><code>cat &gt; hello.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
echo &#8220;Hello, $(whoami)! Welcome to Bash scripting.&#8221;
EOF
chmod +x hello.sh
./hello.sh
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; Variables and User Input</h2><pre><code><code>cat &gt; userinfo.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
echo &#8220;Enter your name:&#8221;
read name
echo &#8220;Enter your favorite color:&#8221;
read color
echo &#8220;Hello $name, your favorite color is $color.&#8221;
EOF
chmod +x userinfo.sh
./userinfo.sh
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Conditional Statements</h2><pre><code><code>cat &gt; check_disk.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
usage=$(df / | tail -1 | awk &#8216;{print $5}&#8217; | sed &#8216;s/%//&#8217;)
if [ $usage -gt 80 ]; then
  echo &#8220;&#9888;&#65039; Disk usage is high: ${usage}%&#8221;
else
  echo &#8220;&#9989; Disk usage is normal: ${usage}%&#8221;
fi
EOF
chmod +x check_disk.sh
./check_disk.sh
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; For Loop</h2><pre><code><code>cat &gt; loop_demo.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
for i in {1..5}
do
  echo &#8220;Iteration $i&#8221;
  sleep 1
done
EOF
chmod +x loop_demo.sh
./loop_demo.sh
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; While Loop with Counter</h2><pre><code><code>cat &gt; countdown.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
count=5
while [ $count -gt 0 ]
do
  echo &#8220;Counting down: $count&#8221;
  ((count--))
  sleep 1
done
echo &#8220;&#128640; Blast off!&#8221;
EOF
chmod +x countdown.sh
./countdown.sh
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; Command-Line Arguments</h2><pre><code><code>cat &gt; greet.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
echo &#8220;Hello $1, welcome to $2!&#8221;
EOF
chmod +x greet.sh
./greet.sh Bavi Linux
</code></code></pre><p>&#9989; Output:</p><pre><code><code>Hello Bavi, welcome to Linux!
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; Functions</h2><pre><code><code>cat &gt; math.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
add() {
  echo &#8220;Sum: $(($1 + $2))&#8221;
}
multiply() {
  echo &#8220;Product: $(($1 * $2))&#8221;
}

add 5 7
multiply 3 4
EOF
chmod +x math.sh
./math.sh
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; Backup Script (Real-World Example)</h2><pre><code><code>cat &gt; auto_backup.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
src=&#8221;/etc&#8221;
dest=&#8221;/tmp/linux_course/week15/backup_$(date +%F_%H-%M-%S).tar.gz&#8221;
echo &#8220;Backing up $src to $dest&#8221;
sudo tar -czf $dest $src 2&gt;/dev/null &amp;&amp; echo &#8220;&#9989; Backup done!&#8221;
EOF
chmod +x auto_backup.sh
./auto_backup.sh
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Automation with Cron</h2><pre><code><code>(crontab -l 2&gt;/dev/null; echo &#8220;0 * * * * /tmp/linux_course/week15/auto_backup.sh&#8221;) | crontab -
crontab -l
</code></code></pre><p>This runs your backup every hour.</p><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; Debugging Mode</h2><pre><code><code>cat &gt; debug_demo.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
set -x
x=10
y=5
z=$((x * y))
echo &#8220;Result: $z&#8221;
set +x
EOF
chmod +x debug_demo.sh
./debug_demo.sh
</code></code></pre><p>&#128161; Use <code>set -x</code> to trace script execution.</p><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><ol><li><p>Write a script that prints &#8220;System Report&#8221; with current date and uptime.</p></li><li><p>Write a script that takes two numbers as arguments and prints their sum.</p></li><li><p>Create a loop that prints numbers 1&#8211;10.</p></li><li><p>Create a countdown timer using <code>while</code>.</p></li><li><p>Write a script that checks disk usage and sends a warning if &gt; 70%.</p></li><li><p>Write a function that calculates square of a number.</p></li><li><p>Write a script that asks for your name and greets you with the current time.</p></li><li><p>Automate cleanup of <code>/tmp</code> older than 7 days (demo with dummy files).</p></li><li><p>Use cron to schedule a script every day at midnight.</p></li><li><p>Debug a script using <code>set -x</code> and fix an intentional typo.</p></li></ol><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>What is the purpose of the <code>#!/bin/bash</code> line?</p></li><li><p>How do you make a script executable?</p></li><li><p>What command reads input from the user?</p></li><li><p>How do you pass parameters to a script?</p></li><li><p>What does <code>$1</code> represent inside a script?</p></li><li><p>How do you write an if-else condition in Bash?</p></li><li><p>How can you run a script every day automatically?</p></li><li><p>What command enables debugging mode?</p></li><li><p>How do you define and call a function in Bash?</p></li><li><p>What is the benefit of automating routine tasks using Bash?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 15 Summary</strong><br>You learned:</p><ul><li><p>How to write and run Bash scripts.</p></li><li><p>How to use variables, conditionals, loops, and functions.</p></li><li><p>How to schedule and debug scripts.</p></li><li><p>How to automate real-world admin tasks like backups.</p></li></ul><div><hr></div><h1>Chapter 16 &#8211; Git for Linux Administrators</h1><p><strong>Week 16 Objective:</strong><br>Learn version control fundamentals using Git &#8212; initializing repositories, committing changes, branching, pushing to remote, and using Git to manage Linux configuration and automation scripts.</p><div><hr></div><h2>&#129504; 1 &#8211; Layman&#8217;s Explanation &#8212; &#8220;The Time Machine Analogy&#8221;</h2><p>Think of Git as a <strong>time machine for your files</strong> &#128368;&#65039;</p><ul><li><p>Every time you change a file and commit it &#8212; you take a <strong>snapshot</strong>.</p></li><li><p>You can <strong>travel back in time</strong> to see what changed and when.</p></li><li><p>If something breaks, you just <strong>rollback</strong> to an older version.</p></li><li><p>For Linux admins, Git protects config files (<code>/etc</code>, scripts, backups) from mistakes.</p></li></ul><div><hr></div><h2>&#129513; 2 &#8211; Key Git Concepts for Admins</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vbsc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833815b9-43c1-4aa0-b16d-5c2fdfa59780_689x336.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vbsc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833815b9-43c1-4aa0-b16d-5c2fdfa59780_689x336.png 424w, https://substackcdn.com/image/fetch/$s_!vbsc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833815b9-43c1-4aa0-b16d-5c2fdfa59780_689x336.png 848w, https://substackcdn.com/image/fetch/$s_!vbsc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833815b9-43c1-4aa0-b16d-5c2fdfa59780_689x336.png 1272w, https://substackcdn.com/image/fetch/$s_!vbsc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833815b9-43c1-4aa0-b16d-5c2fdfa59780_689x336.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vbsc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833815b9-43c1-4aa0-b16d-5c2fdfa59780_689x336.png" width="689" height="336" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/833815b9-43c1-4aa0-b16d-5c2fdfa59780_689x336.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:336,&quot;width&quot;:689,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:30230,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833815b9-43c1-4aa0-b16d-5c2fdfa59780_689x336.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vbsc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833815b9-43c1-4aa0-b16d-5c2fdfa59780_689x336.png 424w, https://substackcdn.com/image/fetch/$s_!vbsc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833815b9-43c1-4aa0-b16d-5c2fdfa59780_689x336.png 848w, https://substackcdn.com/image/fetch/$s_!vbsc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833815b9-43c1-4aa0-b16d-5c2fdfa59780_689x336.png 1272w, https://substackcdn.com/image/fetch/$s_!vbsc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F833815b9-43c1-4aa0-b16d-5c2fdfa59780_689x336.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h1>&#128187; Practice Setup (Local, Safe)</h1><pre><code><code>mkdir -p /tmp/linux_course/week16/config_repo
cd /tmp/linux_course/week16/config_repo
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; Initialize a Git Repository</h2><pre><code><code>git init
</code></code></pre><p>&#9989; Output:</p><pre><code><code>Initialized empty Git repository in /tmp/linux_course/week16/config_repo/.git/
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; Configure Git User Identity</h2><pre><code><code>git config --global user.name &#8220;Bavi&#8221;
git config --global user.email &#8220;bavi@example.com&#8221;
</code></code></pre><p>View config:</p><pre><code><code>git config --list
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Create and Commit Files</h2><pre><code><code>echo &#8220;ServerName careerbytecode.local&#8221; &gt; apache.conf
echo &#8220;PermitRootLogin no&#8221; &gt; sshd_config

git add .
git commit -m &#8220;Initial configuration files added&#8221;
</code></code></pre><p>Check history:</p><pre><code><code>git log --oneline
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; Make and Commit Changes</h2><pre><code><code>echo &#8220;Port 2222&#8221; &gt;&gt; sshd_config
git status
git add sshd_config
git commit -m &#8220;Changed SSH port to 2222&#8221;
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; View File Differences</h2><pre><code><code>git diff HEAD~1 sshd_config
</code></code></pre><p>Shows what was added or removed compared to the previous commit.</p><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; Restore Previous Version</h2><pre><code><code>git checkout HEAD~1 sshd_config
cat sshd_config
</code></code></pre><p>&#9989; File reverts to earlier version.</p><p>To undo the restore:</p><pre><code><code>git restore sshd_config
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; Using .gitignore</h2><pre><code><code>echo &#8220;*.log&#8221; &gt; .gitignore
echo &#8220;temp/&#8221; &gt;&gt; .gitignore
mkdir temp
touch debug.log
git status
</code></code></pre><p>Files listed in <code>.gitignore</code> will not appear in &#8220;untracked files.&#8221;</p><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; Create and Switch Branches</h2><pre><code><code>git branch dev
git switch dev
echo &#8220;# Dev changes&#8221; &gt; notes.txt
git add notes.txt
git commit -m &#8220;Added developer notes&#8221;
</code></code></pre><p>Switch back:</p><pre><code><code>git switch main
</code></code></pre><p>Merge changes:</p><pre><code><code>git merge dev
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Create a Remote Repo Simulation (Optional Demo)</h2><p><em>(No internet needed &#8212; local simulation)</em></p><pre><code><code>mkdir -p /tmp/linux_course/week16/remote_repo.git
cd /tmp/linux_course/week16/remote_repo.git
git init --bare
</code></code></pre><p>Now connect local repo:</p><pre><code><code>cd /tmp/linux_course/week16/config_repo
git remote add origin /tmp/linux_course/week16/remote_repo.git
git push origin main
</code></code></pre><p>&#9989; You&#8217;ve simulated a remote Git server locally!</p><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; Git for Backup &amp; Config Sync</h2><p>Automate periodic commits:</p><pre><code><code>cat &gt; git_backup.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
repo=&#8221;/tmp/linux_course/week16/config_repo&#8221;
cd $repo
git add .
git commit -m &#8220;Auto backup at $(date +%F_%T)&#8221;
EOF

chmod +x git_backup.sh
./git_backup.sh
git log --oneline | head -5
</code></code></pre><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><ol><li><p>Initialize a new Git repository in <code>/tmp/linux_course/week16/test_repo</code>.</p></li><li><p>Create a <code>notes.txt</code> and commit it.</p></li><li><p>Modify the file and check <code>git status</code>.</p></li><li><p>Commit your changes with a clear message.</p></li><li><p>View your Git commit history with <code>git log</code>.</p></li><li><p>Create and switch to a branch named <code>testing</code>.</p></li><li><p>Add a <code>.gitignore</code> file that ignores <code>.bak</code> files.</p></li><li><p>Simulate a merge between <code>testing</code> and <code>main</code>.</p></li><li><p>Run the <code>git diff</code> command to view changes.</p></li><li><p>Create a small script that automatically commits changes every hour (with cron).</p></li></ol><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>What is a Git repository?</p></li><li><p>What does the command <code>git init</code> do?</p></li><li><p>How do you view the list of committed changes?</p></li><li><p>What&#8217;s the purpose of <code>.gitignore</code>?</p></li><li><p>How do you restore a previous version of a file?</p></li><li><p>What command creates a new branch?</p></li><li><p>What&#8217;s the difference between <code>git add</code> and <code>git commit</code>?</p></li><li><p>How do you simulate pushing to a remote repository locally?</p></li><li><p>Why is Git useful for system administrators?</p></li><li><p>What does <code>git diff</code> show?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 16 Summary</strong><br>You learned:</p><ul><li><p>How Git tracks configuration changes.</p></li><li><p>How to commit, branch, merge, and rollback safely.</p></li><li><p>How to use <code>.gitignore</code> to exclude temp/log files.</p></li><li><p>How to simulate remote repositories locally.</p></li><li><p>How to automate versioned backups.</p></li></ul><div><hr></div><h1>Chapter 17 &#8211; Advanced Linux Administration</h1><p><strong>Week 17 Objective:</strong><br>Master kernel management, boot configuration (GRUB), resource limits, time synchronization, and system tuning parameters &#8212; safely and practically.</p><div><hr></div><h2>&#129504; 1 &#8211; Layman&#8217;s Explanation &#8212; &#8220;The Brain &amp; Nervous System Analogy&#8221; &#129504;&#9881;&#65039;</h2><p>If Linux were a human body:</p><ul><li><p>The <strong>kernel</strong> is the <strong>brain</strong> &#129504; controlling everything &#8212; CPU, memory, I/O.</p></li><li><p>The <strong>bootloader (GRUB)</strong> is the <strong>alarm clock</strong> that wakes the brain.</p></li><li><p><strong>sysctl</strong> values are the <strong>neural settings</strong> (reflex speeds, thresholds).</p></li><li><p><strong>ulimit</strong> defines <strong>how much work</strong> each organ (process) can handle.</p></li><li><p><strong>chrony</strong> or <strong>NTP</strong> keeps the <strong>body&#8217;s clock in sync</strong> with the world.</p></li></ul><div><hr></div><h2>&#129513; 2 &#8211; Major Concepts</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JlQO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef64c95-310e-405d-bf54-677516cb4c2c_650x267.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JlQO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef64c95-310e-405d-bf54-677516cb4c2c_650x267.png 424w, https://substackcdn.com/image/fetch/$s_!JlQO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef64c95-310e-405d-bf54-677516cb4c2c_650x267.png 848w, https://substackcdn.com/image/fetch/$s_!JlQO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef64c95-310e-405d-bf54-677516cb4c2c_650x267.png 1272w, https://substackcdn.com/image/fetch/$s_!JlQO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef64c95-310e-405d-bf54-677516cb4c2c_650x267.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JlQO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef64c95-310e-405d-bf54-677516cb4c2c_650x267.png" width="650" height="267" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ef64c95-310e-405d-bf54-677516cb4c2c_650x267.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:267,&quot;width&quot;:650,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:23224,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175941295?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef64c95-310e-405d-bf54-677516cb4c2c_650x267.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JlQO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef64c95-310e-405d-bf54-677516cb4c2c_650x267.png 424w, https://substackcdn.com/image/fetch/$s_!JlQO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef64c95-310e-405d-bf54-677516cb4c2c_650x267.png 848w, https://substackcdn.com/image/fetch/$s_!JlQO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef64c95-310e-405d-bf54-677516cb4c2c_650x267.png 1272w, https://substackcdn.com/image/fetch/$s_!JlQO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ef64c95-310e-405d-bf54-677516cb4c2c_650x267.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h1>&#128187; Safe Practice Setup</h1><pre><code><code>mkdir -p /tmp/linux_course/week17
cd /tmp/linux_course/week17
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; View Kernel Version &amp; Info</h2><pre><code><code>uname -a
cat /proc/version
</code></code></pre><p>&#9989; Output:</p><pre><code><code>Linux hostname 6.8.0-37-generic #1 SMP ...
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; List Loaded Kernel Modules</h2><pre><code><code>lsmod | head -10
</code></code></pre><p>Shows kernel modules currently loaded.<br>To describe one:</p><pre><code><code>modinfo ext4 | head -10
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Bootloader (GRUB) Configuration</h2><pre><code><code>cat /etc/default/grub | grep GRUB_
</code></code></pre><p>Typical lines:</p><pre><code><code>GRUB_TIMEOUT=5
GRUB_DEFAULT=0
GRUB_CMDLINE_LINUX=&#8221;quiet splash&#8221;
</code></code></pre><p>&#128161; <strong>Never modify this directly</strong> on a production system &#8212; only in a VM or test.</p><p>To apply changes (DEMO ONLY):</p><pre><code><code># sudo update-grub   &#8592; (commented out for safety)
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; List All sysctl Parameters (Read-only)</h2><pre><code><code>sysctl -a | head -20
</code></code></pre><p>To view a single parameter:</p><pre><code><code>sysctl net.ipv4.ip_forward
</code></code></pre><p>&#9989; Output:</p><pre><code><code>net.ipv4.ip_forward = 0
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; Temporarily Change a Kernel Parameter (Safe)</h2><pre><code><code>sudo sysctl -w net.ipv4.ip_forward=1
sysctl net.ipv4.ip_forward
</code></code></pre><p>&#9888;&#65039; This change resets after reboot.<br>To make it persistent:</p><pre><code><code>echo &#8220;net.ipv4.ip_forward = 1&#8221; | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; Process &amp; Resource Limits (ulimit)</h2><pre><code><code>ulimit -a
</code></code></pre><p>To set a new limit temporarily:</p><pre><code><code>ulimit -n 4096
</code></code></pre><p>Common limits you can control:</p><p>Limit Meaning Example <code>-n</code> Max open files 1024 &#8594; 4096 <code>-u</code> Max processes per user 4096 <code>-t</code> Max CPU time (sec) 600 <code>-v</code> Virtual memory 1 GB</p><p>Persistent limit location:</p><pre><code><code>/etc/security/limits.conf
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; Time Synchronization with chrony</h2><p>Check if chrony is active:</p><pre><code><code>sudo systemctl status chronyd 2&gt;/dev/null || sudo systemctl status chrony
</code></code></pre><p>List time sources:</p><pre><code><code>chronyc sources 2&gt;/dev/null || timedatectl show-timesync
</code></code></pre><p>Manual sync:</p><pre><code><code>sudo chronyc makestep
</code></code></pre><p>If chrony isn&#8217;t installed:</p><pre><code><code>sudo apt install chrony -y 2&gt;/dev/null || sudo yum install chrony -y 2&gt;/dev/null
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; Analyze System Boot Logs</h2><pre><code><code>journalctl -b | grep -E &#8220;boot|kernel&#8221; | head -20
</code></code></pre><p>Check last boot time:</p><pre><code><code>systemd-analyze
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; System Resource Monitoring (Safe Combo Command)</h2><pre><code><code>echo &#8220;=== Resource Overview ===&#8221;
uptime
free -h
df -h
vmstat 2 3
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; Automate Health Check Script</h2><pre><code><code>cat &gt; health_check.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
echo &#8220;=== Advanced System Health Check ===&#8221;
date
echo
echo &#8220;--- Kernel Info ---&#8221;
uname -r
echo &#8220;--- Uptime ---&#8221;
uptime
echo &#8220;--- Memory ---&#8221;
free -h
echo &#8220;--- Disk Usage ---&#8221;
df -h | grep -v tmpfs
echo &#8220;--- Sysctl Key (ip_forward) ---&#8221;
sysctl net.ipv4.ip_forward
echo &#8220;--- Open Files Limit ---&#8221;
ulimit -n
echo &#8220;--- Time Sync Status ---&#8221;
timedatectl | grep &#8220;System clock synchronized&#8221;
EOF
chmod +x health_check.sh
./health_check.sh
</code></code></pre><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><ol><li><p>Run <code>uname -a</code> to view your kernel version.</p></li><li><p>Use <code>lsmod</code> and <code>modinfo</code> to inspect kernel modules.</p></li><li><p>View GRUB settings in <code>/etc/default/grub</code>.</p></li><li><p>Run <code>sysctl -a | grep net.ipv4</code> to list all IPv4 settings.</p></li><li><p>Enable <code>net.ipv4.ip_forward</code> temporarily using <code>sysctl -w</code>.</p></li><li><p>Display all process limits with <code>ulimit -a</code>.</p></li><li><p>Increase the file descriptor limit (<code>ulimit -n 4096</code>) and verify.</p></li><li><p>Check your system time sync with <code>chronyc sources</code>.</p></li><li><p>Run <code>journalctl -b | grep kernel | head -10</code> to see boot messages.</p></li><li><p>Run your <code>health_check.sh</code> script and review output.</p></li></ol><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>What is the role of the Linux kernel?</p></li><li><p>What file controls GRUB boot settings?</p></li><li><p>How can you view current kernel parameters?</p></li><li><p>What does <code>sysctl -w net.ipv4.ip_forward=1</code> do?</p></li><li><p>What is the difference between temporary and persistent sysctl changes?</p></li><li><p>What command shows all user resource limits?</p></li><li><p>Where can you define permanent process limits for a user?</p></li><li><p>What service keeps the Linux clock synchronized?</p></li><li><p>What command shows all loaded kernel modules?</p></li><li><p>Why is it risky to modify GRUB directly on production systems?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 17 Summary</strong><br>You learned:</p><ul><li><p>How to inspect and manage kernel parameters safely.</p></li><li><p>How GRUB controls system boot behavior.</p></li><li><p>How to use sysctl and ulimit for tuning.</p></li><li><p>How to maintain accurate time sync with chrony.</p></li><li><p>How to automate full system health checks.</p></li></ul><div><hr></div><h1>Chapter 18 &#8211; Real-Time Administration Use Cases</h1><div><hr></div><h3>&#127919; Week 18 Objective</h3><p>Practise real-world Linux administration operations such as server patching, log rotation, automated cleanup, user lifecycle management, backup validation, and root-cause analysis &#8212; all through hands-on, non-destructive examples under <code>/tmp/linux_course/week18</code>.</p><div><hr></div><h2>&#129504; 1 &#8211; Layman&#8217;s Explanation &#8212; &#8220;The Maintenance Analogy&#8221;</h2><p>Think of your server as a <strong>factory</strong> &#127981;</p><ul><li><p><strong>Patching</strong> = updating the factory&#8217;s machines.</p></li><li><p><strong>User lifecycle</strong> = managing employee badges.</p></li><li><p><strong>Log cleanup</strong> = removing old security footage.</p></li><li><p><strong>Backups</strong> = daily safety copies of factory plans.</p></li><li><p><strong>Root-cause analysis (RCA)</strong> = investigating why a machine broke down.</p></li></ul><div><hr></div><h2>&#129513; 2 &#8211; Common Real-Time Admin Tasks</h2><p>Category Task Example System Maintenance Patch OS and packages <code>sudo apt update &amp;&amp; sudo apt upgrade -y</code> User Management Create/disable accounts <code>useradd</code>, <code>usermod -L</code> Storage Cleanup Rotate and remove old logs <code>logrotate</code>, <code>find *.log -mtime +30 -delete</code> Backup Validation Verify latest archives <code>tar -tf backup.tar.gz</code> Troubleshooting Analyze downtime and logs <code>journalctl -p err -b</code></p><div><hr></div><h1>&#128187; Safe Practice Setup</h1><pre><code><code>mkdir -p /tmp/linux_course/week18
cd /tmp/linux_course/week18
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 1 &#8211; Server Patching Simulation</h2><pre><code><code>echo &#8220;=== Check for updates ===&#8221;
sudo apt update 2&gt;/dev/null || sudo yum check-update
echo &#8220;=== Apply available updates ===&#8221;
sudo apt upgrade -y 2&gt;/dev/null || sudo yum update -y
</code></code></pre><p>&#128161; Always snapshot VMs or test servers before patching production.</p><div><hr></div><h2>&#9881;&#65039; Example 2 &#8211; User Lifecycle Management</h2><pre><code><code>sudo useradd maria -m -c &#8220;QA Engineer&#8221;
sudo passwd maria
id maria
sudo usermod -L maria # lock user
sudo userdel -r maria # delete user and home folder
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 3 &#8211; Automated Log Cleanup</h2><pre><code><code>mkdir logs
touch logs/app_{1..5}.log
sleep 1
find logs -name &#8220;*.log&#8221; -type f -mtime +30 -delete # (simulate cleanup)
</code></code></pre><p>Schedule with cron to run daily.</p><div><hr></div><h2>&#9881;&#65039; Example 4 &#8211; Log Rotation Verification</h2><pre><code><code>sudo logrotate -d /etc/logrotate.conf | head -10
</code></code></pre><p>&#128161; Use <code>-d</code> for dry-run mode to avoid actual rotation during tests.</p><div><hr></div><h2>&#9881;&#65039; Example 5 &#8211; Backup Validation Script</h2><pre><code><code>cat &gt; validate_backup.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
latest=$(ls -t /tmp/linux_course/week12/backups/*.tar* 2&gt;/dev/null | head -n 1)
if [ -z &#8220;$latest&#8221; ]; then
  echo &#8220;No backups found.&#8221;
  exit 1
fi
echo &#8220;Validating $latest&#8221;
tar -tf &#8220;$latest&#8221; &gt; /dev/null &amp;&amp; echo &#8220;&#9989; Backup valid&#8221; || echo &#8220;&#10060; Corrupt backup&#8221;
EOF
chmod +x validate_backup.sh
./validate_backup.sh
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 6 &#8211; System Health and Service Audit</h2><pre><code><code>systemctl --failed
sudo journalctl -p err -b | tail -10
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 7 &#8211; Resource Cleanup Automation</h2><pre><code><code>cat &gt; cleanup_temp.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
find /tmp -type f -mtime +7 -delete
echo &#8220;Old temporary files cleaned.&#8221;
EOF
chmod +x cleanup_temp.sh
./cleanup_temp.sh
</code></code></pre><p>Schedule weekly via <code>cron</code>.</p><div><hr></div><h2>&#9881;&#65039; Example 8 &#8211; Patching Automation (Example Script)</h2><pre><code><code>cat &gt; auto_patch.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
echo &#8220;=== Automated Patch Started $(date) ===&#8221;
sudo apt update -y 2&gt;/dev/null || sudo yum update -y
sudo apt upgrade -y 2&gt;/dev/null || sudo yum upgrade -y
echo &#8220;=== Patch Completed $(date) ===&#8221;
EOF
chmod +x auto_patch.sh
./auto_patch.sh
</code></code></pre><div><hr></div><h2>&#9881;&#65039; Example 9 &#8211; Simulated Downtime RCA (Log Analysis)</h2><pre><code><code>sudo journalctl -p err --since &#8220;1 hour ago&#8221; | grep -E &#8220;fail|error|critical&#8221; | head -10
</code></code></pre><p>Helps identify root cause of failures (e.g., service crashes, disk errors).</p><div><hr></div><h2>&#9881;&#65039; Example 10 &#8211; Comprehensive System Maintenance Script</h2><pre><code><code>cat &gt; maintenance.sh &lt;&lt;&#8217;EOF&#8217;
#!/bin/bash
echo &#8220;=== System Maintenance Report ===&#8221;
date
echo &#8220;[1] Disk Usage:&#8221;; df -h | grep -v tmpfs
echo &#8220;[2] CPU Load:&#8221;; uptime
echo &#8220;[3] Failed Services:&#8221;; systemctl --failed
echo &#8220;[4] Old Temp Files Cleanup...&#8221;; find /tmp -type f -mtime +7 -delete
echo &#8220;[5] Backup Validation:&#8221;; bash /tmp/linux_course/week18/validate_backup.sh
echo &#8220;=== Maintenance Complete ===&#8221;
EOF
chmod +x maintenance.sh
./maintenance.sh
</code></code></pre><div><hr></div><h1>&#129513; 10 Hands-On Exercises</h1><ol><li><p>Run <code>sudo apt update &amp;&amp; sudo apt upgrade</code> in a test VM.</p></li><li><p>Create two new users and set passwords and sudo access.</p></li><li><p>Lock one account and verify login denied.</p></li><li><p>Create dummy logs and remove older ones using <code>find -delete</code>.</p></li><li><p>List configured logrotate policies under <code>/etc/logrotate.d/</code>.</p></li><li><p>Create and verify a TAR backup using the validation script.</p></li><li><p>Run <code>systemctl --failed</code> and note any non-active units.</p></li><li><p>Schedule <code>cleanup_temp.sh</code> to run daily at 3 AM via <code>cron</code>.</p></li><li><p>Check for error logs in the last hour using <code>journalctl</code>.</p></li><li><p>Execute the full <code>maintenance.sh</code> and analyze its output.</p></li></ol><div><hr></div><h1>&#129504; 10 Assessment Questions</h1><ol><li><p>Why is it important to patch Linux systems regularly?</p></li><li><p>Which commands are used to add, lock, and remove users?</p></li><li><p>How does <code>logrotate</code> help in log management?</p></li><li><p>How do you automate log cleanup using <code>find</code> and <code>cron</code>?</p></li><li><p>What does the backup validation step ensure?</p></li><li><p>Which command shows failed systemd services?</p></li><li><p>What is the purpose of RCA in system administration?</p></li><li><p>What is the difference between manual and automated patching?</p></li><li><p>Why should cleanup scripts be scheduled off-peak hours?</p></li><li><p>How does a comprehensive maintenance script benefit admins?</p></li></ol><div><hr></div><p>&#9989; <strong>End of Chapter 18 Summary</strong><br>You now know how to perform real-world admin duties:</p><ul><li><p>Apply patches and security updates.</p></li><li><p>Manage user lifecycle.</p></li><li><p>Rotate and clean logs automatically.</p></li><li><p>Validate backups and audit system health.</p></li><li><p>Analyze and troubleshoot production issues efficiently.</p></li></ul><div><hr></div><p></p>]]></content:encoded></item><item><title><![CDATA[AI & Analytics with PostgreSQL: Master Feature Engineering and Data Warehousing]]></title><description><![CDATA[&#128161; From Zero to Real-Time Analytics &#8212; Learn SQL the AI Way]]></description><link>https://careerbytecode.substack.com/p/ai-analytics-with-postgresql-master-feature-engineering-and-data-warehousing</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/ai-analytics-with-postgresql-master-feature-engineering-and-data-warehousing</guid><dc:creator><![CDATA[CareerByteCode]]></dc:creator><pubDate>Sun, 05 Oct 2025 20:14:46 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!v4ai!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1574bc8-b9b5-4fc4-8c95-98430ffb4802_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!v4ai!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1574bc8-b9b5-4fc4-8c95-98430ffb4802_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!v4ai!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1574bc8-b9b5-4fc4-8c95-98430ffb4802_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!v4ai!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1574bc8-b9b5-4fc4-8c95-98430ffb4802_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!v4ai!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1574bc8-b9b5-4fc4-8c95-98430ffb4802_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!v4ai!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1574bc8-b9b5-4fc4-8c95-98430ffb4802_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!v4ai!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1574bc8-b9b5-4fc4-8c95-98430ffb4802_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b1574bc8-b9b5-4fc4-8c95-98430ffb4802_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:524759,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1574bc8-b9b5-4fc4-8c95-98430ffb4802_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!v4ai!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1574bc8-b9b5-4fc4-8c95-98430ffb4802_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!v4ai!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1574bc8-b9b5-4fc4-8c95-98430ffb4802_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!v4ai!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1574bc8-b9b5-4fc4-8c95-98430ffb4802_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!v4ai!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb1574bc8-b9b5-4fc4-8c95-98430ffb4802_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p><br></p><h2>&#127919; <strong>Course Description</strong></h2><p>In the world of Artificial Intelligence and Machine Learning, <strong>data is everything</strong> and <strong>PostgreSQL</strong> is one of the most powerful tools to manage, clean, and prepare that data efficiently.</p><p>This course is designed for <strong>Python learners, data enthusiasts, and aspiring AI/ML professionals</strong> who want to build a <em>strong SQL foundation</em> using <strong>PostgreSQL</strong>, the most advanced open-source database in the world.</p><p>We start from absolute scratch understanding databases, tables, and queries  and gradually build up to advanced analytical queries, window functions, feature engineering, and performance tuning.</p><p>Each chapter includes:</p><ul><li><p>&#128187; <strong>Real-world, copy-paste runnable examples</strong></p></li><li><p>&#129504; <strong>Step-by-step explanations in plain English</strong></p></li><li><p>&#128202; <strong>Mini projects linked to AI and data analytics</strong></p></li><li><p>&#129513; <strong>Exercises to build hands-on confidence</strong></p></li></ul><p>By the end, you&#8217;ll not only master SQL for data extraction and transformation  you&#8217;ll learn how to <strong>bridge SQL with Python</strong> for real-time analytics, model-ready datasets, and production-grade pipelines.</p><div><hr></div><h2>&#128640; <strong>Who This Course Is For</strong></h2><p>&#9989; Python learners stepping into AI, Data Science, or ML.<br>&#9989; Developers who want to master SQL from zero using practical examples.<br>&#9989; Data Analysts who want to transition into AI roles.<br>&#9989; AI/ML Engineers who want to design efficient feature engineering pipelines.<br>&#9989; Anyone preparing for <strong>AI/Data interviews</strong> requiring strong SQL query writing.</p><div><hr></div><h2>&#128218; <strong>What You&#8217;ll Learn</strong></h2><p>You&#8217;ll go from:</p><blockquote><p>&#8220;I know a bit of SELECT&#8230;&#8221;<br>to<br>&#8220;I can write complex queries that feed ML models!&#8221;</p></blockquote><p>Here&#8217;s a glimpse of your journey:</p><h3>&#128205; Foundations</h3><ul><li><p>Understanding databases, tables, and data types</p></li><li><p>Writing queries with <code>SELECT</code>, <code>WHERE</code>, and <code>ORDER BY</code></p></li><li><p>Using conditions, filters, and aliases</p></li></ul><h3>&#128205; Intermediate SQL</h3><ul><li><p>Aggregations (<code>COUNT</code>, <code>SUM</code>, <code>AVG</code>) and <code>GROUP BY</code></p></li><li><p>All types of Joins and Subqueries</p></li><li><p>Common Table Expressions (CTEs)</p></li></ul><h3>&#128205; Advanced SQL</h3><ul><li><p>Window Functions for time-series analytics</p></li><li><p>Case statements, ranking, and rolling metrics</p></li><li><p>Data cleaning using string and date functions</p></li><li><p>JSON and semi-structured data handling</p></li></ul><h3>&#128205; Real-World AI Applications</h3><ul><li><p>SQL for feature engineering</p></li><li><p>Handling missing data, anomalies, and outliers</p></li><li><p>SQL + Python integration (Pandas, SQLAlchemy)</p></li><li><p>Building small ETL pipelines with PostgreSQL</p></li></ul><div><hr></div><h2>&#127775; <strong>Key Benefits</strong></h2><h3>1&#65039;&#8419; <strong>Real-World Ready</strong></h3><p>Every topic connects directly to how data scientists and AI engineers use SQL in real jobs &#8212; preparing, cleaning, and transforming data for analysis and model training.</p><h3>2&#65039;&#8419; <strong>Python + SQL Integration</strong></h3><p>You&#8217;ll learn to connect PostgreSQL with Python, pull datasets using <code>pandas</code>, and preprocess them for your AI projects or dashboards.</p><h3>3&#65039;&#8419; <strong>Practice Without Frustration</strong></h3><p>All examples are fully self-contained &#8212; if you copy-paste them, they <em>just work</em>. No missing data, no setup errors.</p><h3>4&#65039;&#8419; <strong>Visual Learning Approach</strong></h3><p>Each concept includes tables, outputs, and real data. You&#8217;ll understand <strong>why</strong> a query works, not just <strong>how</strong>.</p><h3>5&#65039;&#8419; <strong>AI-Focused SQL Mastery</strong></h3><p>This isn&#8217;t generic database training. The entire syllabus is tailored to AI/ML use cases &#8212; feature creation, time series, window analytics, and ETL workflows.</p><h3>6&#65039;&#8419; <strong>Practical Assignments</strong></h3><p>Each chapter ends with 10 hands-on exercises that can be solved directly in PostgreSQL &#8212; designed to reinforce learning.</p><h3>7&#65039;&#8419; <strong>Career-Oriented Learning Path</strong></h3><p>You&#8217;ll build the SQL confidence needed to answer <strong>data engineering, data analyst, and AI interview questions</strong> with clarity.</p><div><hr></div><h2>&#129504; <strong>By the End of This Course, You&#8217;ll Be Able To:</strong></h2><p>&#9989; Design and query complex PostgreSQL databases.<br>&#9989; Clean, join, and transform raw data for AI/ML workflows.<br>&#9989; Write advanced SQL queries with subqueries, CTEs, and window functions.<br>&#9989; Handle JSON, arrays, and time-series data inside PostgreSQL.<br>&#9989; Integrate PostgreSQL queries directly with Python notebooks and pipelines.<br>&#9989; Debug and optimize queries for faster performance.<br>&#9989; Build complete, model-ready datasets from raw data.</p><div><hr></div><h2>&#128338; <strong>Duration</strong></h2><p><strong>6 Weeks (Self-paced, Practice-based)</strong><br>Each week includes:</p><ul><li><p>1 Chapter (detailed theory + 5 runnable examples + 10 exercises)</p></li><li><p>1 Practice project at the end of the module</p></li></ul><div><hr></div><h2>&#129513; <strong>Course Structure</strong></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aMVG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbc08b49-c495-48ee-a762-2d5ac85f7835_744x582.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aMVG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbc08b49-c495-48ee-a762-2d5ac85f7835_744x582.png 424w, https://substackcdn.com/image/fetch/$s_!aMVG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbc08b49-c495-48ee-a762-2d5ac85f7835_744x582.png 848w, https://substackcdn.com/image/fetch/$s_!aMVG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbc08b49-c495-48ee-a762-2d5ac85f7835_744x582.png 1272w, https://substackcdn.com/image/fetch/$s_!aMVG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbc08b49-c495-48ee-a762-2d5ac85f7835_744x582.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aMVG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbc08b49-c495-48ee-a762-2d5ac85f7835_744x582.png" width="744" height="582" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bbc08b49-c495-48ee-a762-2d5ac85f7835_744x582.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:582,&quot;width&quot;:744,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:41793,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbc08b49-c495-48ee-a762-2d5ac85f7835_744x582.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!aMVG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbc08b49-c495-48ee-a762-2d5ac85f7835_744x582.png 424w, https://substackcdn.com/image/fetch/$s_!aMVG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbc08b49-c495-48ee-a762-2d5ac85f7835_744x582.png 848w, https://substackcdn.com/image/fetch/$s_!aMVG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbc08b49-c495-48ee-a762-2d5ac85f7835_744x582.png 1272w, https://substackcdn.com/image/fetch/$s_!aMVG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbc08b49-c495-48ee-a762-2d5ac85f7835_744x582.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#128188; <strong>Career Impact</strong></h2><p>After completing this course, you&#8217;ll confidently say:</p><blockquote><p>&#8220;I can use SQL to build datasets for AI models and analytics &#8212; from raw data to insights.&#8221;</p></blockquote><p>You&#8217;ll be ready for roles like:</p><ul><li><p><strong>Data Analyst (Python + SQL)</strong></p></li><li><p><strong>Data Engineer (PostgreSQL + ETL)</strong></p></li><li><p><strong>ML Engineer (Feature Engineering with SQL)</strong></p></li><li><p><strong>AI Developer (Data Prep &amp; Integration)</strong></p></li></ul><div><hr></div><h2>&#127942; <strong>Certificate of Completion</strong></h2><p>Upon completing all chapters and final project, you&#8217;ll receive a <strong>CareerByteCode Certificate</strong> showcasing your practical PostgreSQL expertise for AI and Data roles.</p><div><hr></div><h2>&#128640; PostgreSQL Roadmap for AI / Data / ML Jobs</h2><div><hr></div><h3>&#128313;Chapter 1. PostgreSQL Basics (Foundations)</h3><p><strong>Goal:</strong> Build a solid foundation in PostgreSQL syntax and structure.</p><ul><li><p>What is PostgreSQL? (Architecture, Role in AI systems)</p></li><li><p>Understanding Databases, Schemas, Tables, Columns, Records</p></li><li><p>Data Types: <code>INTEGER</code>, <code>NUMERIC</code>, <code>TEXT</code>, <code>BOOLEAN</code>, <code>DATE</code>, <code>TIMESTAMP</code></p></li><li><p>DDL, DML, DQL, DCL, TCL overview</p></li><li><p>Creating and managing databases (<code>CREATE DATABASE</code>, <code>DROP DATABASE</code>)</p></li><li><p>Creating tables with constraints (<code>PRIMARY KEY</code>, <code>FOREIGN KEY</code>, <code>UNIQUE</code>, <code>NOT NULL</code>)</p></li><li><p><code>SELECT</code>, <code>FROM</code>, <code>WHERE</code> basics</p></li><li><p>Filtering data (<code>=</code>, <code>&lt;</code>, <code>&gt;</code>, <code>&lt;&gt;</code>, <code>BETWEEN</code>, <code>IN</code>, <code>LIKE</code>, <code>ILIKE</code>)</p></li><li><p>Sorting with <code>ORDER BY</code></p></li><li><p>Limiting with <code>LIMIT</code>, <code>OFFSET</code>, <code>FETCH</code></p></li><li><p>Aliases with <code>AS</code></p></li></ul><p>&#128073; <strong>AI Relevance:</strong> Core foundation for data extraction and manipulation before model training.</p><div><hr></div><h3>&#128313;Chapter  2. Aggregations &amp; Grouping</h3><p><strong>Goal:</strong> Summarize and explore datasets effectively.</p><ul><li><p><code>COUNT()</code>, <code>SUM()</code>, <code>AVG()</code>, <code>MIN()</code>, <code>MAX()</code></p></li><li><p><code>GROUP BY</code> with single/multiple columns</p></li><li><p><code>HAVING</code> vs <code>WHERE</code></p></li><li><p>Removing duplicates with <code>DISTINCT</code></p></li><li><p>Statistical queries for EDA (Exploratory Data Analysis)</p></li></ul><p>&#128073; <strong>AI Relevance:</strong> Computing aggregates for feature engineering and EDA (mean, count, frequency features).</p><div><hr></div><h3>&#128313;Chapter  3. Joins (Essential for Data Engineering &amp; AI)</h3><p><strong>Goal:</strong> Combine multiple datasets efficiently.</p><ul><li><p><code>INNER JOIN</code>, <code>LEFT JOIN</code>, <code>RIGHT JOIN</code>, <code>FULL OUTER JOIN</code></p></li><li><p><code>CROSS JOIN</code> and Cartesian products</p></li><li><p><code>SELF JOIN</code> (hierarchical and recursive relationships)</p></li><li><p>Multi-table joins</p></li><li><p>Natural joins vs explicit joins</p></li></ul><p>&#128073; <strong>AI Relevance:</strong> Combine multiple sources for dataset creation, feature enrichment, or entity linking.</p><div><hr></div><h3>&#128313;Chapter  4. Subqueries &amp; CTEs (Common Table Expressions)</h3><p><strong>Goal:</strong> Create modular, readable, and optimized queries.</p><ul><li><p>Subqueries in <code>SELECT</code>, <code>FROM</code>, and <code>WHERE</code></p></li><li><p>Correlated vs non-correlated subqueries</p></li><li><p><code>EXISTS</code> vs <code>IN</code> performance</p></li><li><p>Using <code>WITH</code> for Common Table Expressions (CTEs)</p></li><li><p>Recursive CTEs for hierarchical data</p></li></ul><p>&#128073; <strong>AI Relevance:</strong> Break down complex queries for ETL pipelines and data preparation workflows.</p><div><hr></div><h3>&#128313;Chapter  5. Advanced Filtering &amp; Window Functions</h3><p><strong>Goal:</strong> Learn analytics-level querying (critical for AI feature creation).</p><ul><li><p>Conditional logic using <code>CASE WHEN</code></p></li><li><p>Handling NULLs: <code>COALESCE</code>, <code>NULLIF</code>, <code>IS NULL</code></p></li><li><p>Ranking functions: <code>ROW_NUMBER()</code>, <code>RANK()</code>, <code>DENSE_RANK()</code></p></li><li><p>Window aggregates: <code>SUM() OVER()</code>, <code>AVG() OVER()</code></p></li><li><p>Frame clauses: <code>ROWS BETWEEN</code>, <code>RANGE BETWEEN</code></p></li><li><p>Lead/Lag functions for time-series (<code>LAG()</code>, <code>LEAD()</code>)</p></li><li><p>Running totals, moving averages, percentiles</p></li></ul><p>&#128073; <strong>AI Relevance:</strong> Perfect for time series modeling, rolling statistics, and trend analysis.</p><div><hr></div><h3>&#128313; Chapter 6. Data Manipulation</h3><p><strong>Goal:</strong> Manage data lifecycle inside PostgreSQL.</p><ul><li><p><code>INSERT</code>, <code>UPDATE</code>, <code>DELETE</code></p></li><li><p><code>RETURNING</code> clause (unique to PostgreSQL)</p></li><li><p>Upsert operations using <code>INSERT ... ON CONFLICT DO UPDATE</code></p></li><li><p>Bulk inserts with <code>COPY</code> command</p></li><li><p>Transactions with <code>BEGIN</code>, <code>COMMIT</code>, <code>ROLLBACK</code></p></li></ul><p>&#128073; <strong>AI Relevance:</strong> Managing data updates efficiently during ETL or experiment iterations.</p><div><hr></div><h3>&#128313; Chapter 7. Set Operations</h3><p><strong>Goal:</strong> Combine or compare datasets for complex workflows.</p><ul><li><p><code>UNION</code>, <code>UNION ALL</code>, <code>INTERSECT</code>, <code>EXCEPT</code></p></li><li><p>Combining datasets for training/validation splits</p></li><li><p>Deduplication with set operations</p></li></ul><p>&#128073; <strong>AI Relevance:</strong> Useful for merging multiple datasets, or comparing model prediction results vs actuals.</p><div><hr></div><h3>&#128313;Chapter  8. Data Cleaning &amp; Transformation (ETL Core)</h3><p><strong>Goal:</strong> Prepare clean, well-structured datasets for ML.</p><ul><li><p>String operations: <code>TRIM</code>, <code>SUBSTRING</code>, <code>CONCAT</code>, <code>UPPER</code>, <code>LOWER</code>, <code>REPLACE</code></p></li><li><p>Date &amp; time functions: <code>AGE</code>, <code>DATE_PART</code>, <code>EXTRACT</code>, <code>TO_CHAR</code>, <code>NOW()</code></p></li><li><p>Type conversion: <code>CAST</code>, <code>::type</code> syntax</p></li><li><p>Pivoting data using <code>crosstab()</code> (from <code>tablefunc</code> extension)</p></li><li><p>Unpivoting / reshaping datasets</p></li><li><p>Conditional transformations using <code>CASE</code></p></li></ul><p>&#128073; <strong>AI Relevance:</strong> Critical preprocessing step before model training &#8212; clean, normalized, formatted data.</p><div><hr></div><h3>&#128313; Chapter 9. JSON &amp; Semi-Structured Data (PostgreSQL Power Feature)</h3><p><strong>Goal:</strong> Handle real-world mixed-format data efficiently.</p><ul><li><p>JSON &amp; JSONB columns</p></li><li><p>Accessing data: <code>-&gt;</code>, <code>-&gt;&gt;</code>, <code>#&gt;</code> operators</p></li><li><p>JSON functions: <code>json_each()</code>, <code>jsonb_array_elements()</code>, <code>jsonb_build_object()</code></p></li><li><p>Querying nested structures</p></li><li><p>Storing AI/ML model metadata or configurations</p></li></ul><p>&#128073; <strong>AI Relevance:</strong> Modern datasets often include API responses or event logs stored as JSON.</p><div><hr></div><h3>&#128313;Chapter 10. Array &amp; Advanced Data Types</h3><p><strong>Goal:</strong> Work with complex and scientific data structures.</p><ul><li><p>Array creation and indexing</p></li><li><p><code>unnest()</code> for array flattening</p></li><li><p>Range types (<code>int4range</code>, <code>numrange</code>, <code>daterange</code>)</p></li><li><p>ENUMs, UUIDs, HSTORE key-value pairs</p></li></ul><p>&#128073; <strong>AI Relevance:</strong> Helpful for storing multiple model parameters or embedding vectors.</p><div><hr></div><h3>&#128313;Chapter  11. Performance &amp; Optimization</h3><p><strong>Goal:</strong> Run large queries efficiently in data pipelines.</p><ul><li><p>Index types: <code>B-tree</code>, <code>Hash</code>, <code>GIN</code>, <code>GiST</code></p></li><li><p>Creating and analyzing indexes</p></li><li><p>Query plans with <code>EXPLAIN</code> and <code>EXPLAIN ANALYZE</code></p></li><li><p>Understanding Sequential vs Index Scan</p></li><li><p>Partitioning large tables</p></li><li><p>Materialized views</p></li><li><p>VACUUM and ANALYZE commands</p></li></ul><p>&#128073; <strong>AI Relevance:</strong> Optimized queries mean faster ETL, real-time dashboards, and efficient training loops.</p><div><hr></div><h3>&#128313;Chapter  12. AI / Data-Specific Use Cases</h3><p><strong>Goal:</strong> Connect SQL knowledge directly to ML &amp; AI workflows.</p><ul><li><p>Feature engineering queries (aggregates, ratios, time-based deltas)</p></li><li><p>Time-series transformations (lags, moving windows)</p></li><li><p>Anomaly detection with SQL-based thresholds</p></li><li><p>Missing value detection (<code>COUNT(NULL)</code>, <code>COALESCE</code>)</p></li><li><p>Deduplication and data consistency checks</p></li><li><p>Statistical summaries with SQL</p></li><li><p>Creating feature stores in PostgreSQL</p></li></ul><div><hr></div><h3>&#128313;Chapter  13. PostgreSQL with Python (Integration)</h3><p><strong>Goal:</strong> Combine PostgreSQL and Python seamlessly for end-to-end data work.</p><ul><li><p>Connecting using <code>psycopg2</code> or <code>SQLAlchemy</code></p></li><li><p>Reading queries into Pandas DataFrames (<code>pd.read_sql()</code>)</p></li><li><p>Writing model outputs back to PostgreSQL</p></li><li><p>Using <code>COPY</code> for fast bulk inserts from Python</p></li><li><p>Building ETL pipelines (Airflow + Postgres + Pandas)</p></li><li><p>Query automation via Jupyter or scripts</p></li></ul><p>&#128073; <strong>AI Relevance:</strong> The bridge between SQL and ML model development.</p><div><hr></div><h3>&#128313;Chapter  14. Data Warehousing &amp; Analytical Extensions</h3><p><strong>Goal:</strong> Handle enterprise-scale analytics.</p><ul><li><p>Understanding extensions like <code>TimescaleDB</code> (for time series)</p></li><li><p><code>CUBE</code>, <code>ROLLUP</code>, and <code>GROUPING SETS</code></p></li><li><p>PostgreSQL partitioning for analytical datasets</p></li><li><p>Integration with BI tools (Power BI, Tableau, Metabase)</p></li><li><p>Using <code>FDW</code> (Foreign Data Wrapper) for external data access</p></li></ul><p>&#128073; <strong>AI Relevance:</strong> Scaling SQL analysis for production AI data pipelines.</p><div><hr></div><h3>&#9989; <strong>Summary: What You Must Master for AI Jobs</strong></h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ynYd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a585b34-9da6-4cc5-9e89-00d4d7f4fc80_723x237.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ynYd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a585b34-9da6-4cc5-9e89-00d4d7f4fc80_723x237.png 424w, https://substackcdn.com/image/fetch/$s_!ynYd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a585b34-9da6-4cc5-9e89-00d4d7f4fc80_723x237.png 848w, https://substackcdn.com/image/fetch/$s_!ynYd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a585b34-9da6-4cc5-9e89-00d4d7f4fc80_723x237.png 1272w, https://substackcdn.com/image/fetch/$s_!ynYd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a585b34-9da6-4cc5-9e89-00d4d7f4fc80_723x237.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ynYd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a585b34-9da6-4cc5-9e89-00d4d7f4fc80_723x237.png" width="723" height="237" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a585b34-9da6-4cc5-9e89-00d4d7f4fc80_723x237.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:237,&quot;width&quot;:723,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:29338,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a585b34-9da6-4cc5-9e89-00d4d7f4fc80_723x237.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ynYd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a585b34-9da6-4cc5-9e89-00d4d7f4fc80_723x237.png 424w, https://substackcdn.com/image/fetch/$s_!ynYd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a585b34-9da6-4cc5-9e89-00d4d7f4fc80_723x237.png 848w, https://substackcdn.com/image/fetch/$s_!ynYd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a585b34-9da6-4cc5-9e89-00d4d7f4fc80_723x237.png 1272w, https://substackcdn.com/image/fetch/$s_!ynYd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a585b34-9da6-4cc5-9e89-00d4d7f4fc80_723x237.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><div><hr></div><h3>&#128279; Recommended Tools for Practice</h3><ul><li><p><strong>PostgreSQL</strong> (install locally or use Docker)</p></li><li><p><strong>pgAdmin / DBeaver</strong> (GUI tools)</p></li><li><p><strong>Jupyter Notebook + SQLAlchemy</strong> (Python integration)</p></li><li><p><strong>Kaggle Datasets + PostgreSQL</strong> (real-world AI practice)</p></li></ul><div><hr></div><p></p><h1>Chapter 1 &#8212; PostgreSQL Basics (Foundations)</h1><p></p><h2>What you&#8217;ll learn in this chapter (in one sentence)</h2><p>You&#8217;ll learn what PostgreSQL is, the basic building blocks of a database (databases &#8594; schemas &#8594; tables &#8594; rows/columns), how to write simple <code>SELECT</code> queries, filter results, sort them, limit rows, and use column aliases &#8212; all explained in plain language.</p><div><hr></div><h2>Layman explanations (super simple)</h2><ul><li><p><strong>What is PostgreSQL?</strong><br>PostgreSQL (Postgres) is a program that stores data for you (like a super-organized filing cabinet). You ask it for data using SQL (a language); it gives the data back.</p></li><li><p><strong>Database vs Schema vs Table vs Row vs Column</strong></p><ul><li><p><strong>Database</strong>: A whole filing cabinet.</p></li><li><p><strong>Schema</strong>: A drawer inside the cabinet (helps organize).</p></li><li><p><strong>Table</strong>: A file folder in the drawer (holds similar records).</p></li><li><p><strong>Row</strong>: One sheet of paper in the folder (a single item/record).</p></li><li><p><strong>Column</strong>: A labeled line on the sheet (a specific attribute, like &#8220;name&#8221; or &#8220;age&#8221;).</p></li></ul></li><li><p><strong>Primary Key</strong><br>A column that uniquely identifies each row &#8212; like a unique ID number on each sheet.</p></li><li><p><strong>Foreign Key</strong><br>A column that points to a primary key in another table &#8212; like a reference to another file.</p></li><li><p><strong>Data types</strong><br>Tells Postgres what kind of info a column holds: <code>INTEGER</code> (numbers), <code>TEXT</code> (words), <code>BOOLEAN</code> (true/false), <code>TIMESTAMP</code> (date &amp; time), etc.</p></li><li><p><strong>DDL / DML / DQL</strong></p><ul><li><p><strong>DDL (Data Definition Language)</strong>: Commands that create or change the structure (e.g., <code>CREATE TABLE</code>).</p></li><li><p><strong>DML (Data Manipulation Language)</strong>: Commands that modify data (e.g., <code>INSERT</code>, <code>UPDATE</code>, <code>DELETE</code>).</p></li><li><p><strong>DQL (Data Query Language)</strong>: Commands that read data (mostly <code>SELECT</code>).</p></li></ul></li><li><p><strong>SELECT, FROM, WHERE</strong></p><ul><li><p><code>SELECT</code> lists which columns you want.</p></li><li><p><code>FROM</code> says which table.</p></li><li><p><code>WHERE</code> filters rows (gives conditions).</p></li></ul></li><li><p><strong>Filtering operators</strong><br>Use <code>=</code> (equal), <code>&lt;</code>, <code>&gt;</code>, <code>&lt;&gt;</code> (not equal), <code>BETWEEN</code>, <code>IN</code> (in a set), <code>LIKE</code> (pattern matching).</p></li><li><p><strong>ORDER BY</strong><br>Sort the results (e.g., newest first or lowest price first).</p></li><li><p><strong>LIMIT / OFFSET</strong><br>Only take the first N rows (LIMIT), or skip some and then take (OFFSET).</p></li><li><p><strong>Aliases (AS)</strong><br>Rename columns or tables within your query to make output cleaner or queries shorter.</p></li></ul><div><hr></div><h2>Practical Examples (each is copy-paste runnable)</h2><blockquote><p><strong>Note:</strong> Each example starts with <code>DROP TABLE IF EXISTS</code> so you can re-run freely.</p></blockquote><div><hr></div><h3>Example 1 &#8212; Basic SELECT and creating a table</h3><p><strong>Scenario</strong>: A tiny people table. Show selected columns.</p><pre><code><code>-- Example 1: basic SELECT
DROP TABLE IF EXISTS ex1_people;

CREATE TABLE ex1_people (
  person_id SERIAL PRIMARY KEY,
  full_name TEXT NOT NULL,
  age INTEGER,
  city TEXT
);

INSERT INTO ex1_people (full_name, age, city) VALUES
(&#8217;Anita Sharma&#8217;, 28, &#8216;Brussels&#8217;),
(&#8217;Mark Johnson&#8217;, 35, &#8216;London&#8217;),
(&#8217;Sana Ali&#8217;, 22, &#8216;Amsterdam&#8217;),
(&#8217;Tom Lee&#8217;, NULL, &#8216;Berlin&#8217;);  -- Tom&#8217;s age unknown

-- 1) select all columns
SELECT * FROM ex1_people;

-- 2) select specific columns
SELECT full_name, city FROM ex1_people;

-- 3) rename a column in output
SELECT full_name AS name, age AS years FROM ex1_people;

</code></code></pre><p><strong>What you learned</strong>: how to create a table, insert rows, and fetch all or specific columns. <code>NULL</code> means unknown.</p><div><hr></div><h3>Example 2 &#8212; Filtering with WHERE and operators</h3><p><strong>Scenario</strong>: Products table &#8212; use <code>=</code>, <code>&lt;</code>, <code>&gt;</code>, <code>&lt;&gt;</code>, <code>BETWEEN</code>, <code>IN</code>, <code>LIKE</code>, <code>ILIKE</code>.</p><pre><code><code>-- Example 2: filtering
DROP TABLE IF EXISTS ex2_products;
CREATE TABLE ex2_products (
  product_id SERIAL PRIMARY KEY,
  name TEXT NOT NULL,
  price NUMERIC(8,2),
  category TEXT
);

INSERT INTO ex2_products (name, price, category) VALUES
(&#8217;Coffee Beans&#8217;, 12.50, &#8216;Beverage&#8217;),
(&#8217;Green Tea&#8217;, 8.00, &#8216;Beverage&#8217;),
(&#8217;Notebook A4&#8217;, 3.25, &#8216;Stationery&#8217;),
(&#8217;Premium Notebook&#8217;, 7.50, &#8216;Stationery&#8217;),
(&#8217;Espresso Machine&#8217;, 120.00, &#8216;Appliance&#8217;);

-- Equal
SELECT * FROM ex2_products WHERE category = &#8216;Beverage&#8217;;

-- Not equal
SELECT * FROM ex2_products WHERE price &lt;&gt; 12.50;

-- Greater than / Less than
SELECT name, price FROM ex2_products WHERE price &gt; 10.00;

-- BETWEEN
SELECT name, price FROM ex2_products WHERE price BETWEEN 5 AND 50;

-- IN (matches any of a list)
SELECT * FROM ex2_products WHERE category IN (&#8217;Beverage&#8217;, &#8216;Appliance&#8217;);

-- LIKE (pattern; % means any chars)
SELECT * FROM ex2_products WHERE name LIKE &#8216;%Notebook%&#8217;;

-- ILIKE (case-insensitive)
SELECT * FROM ex2_products WHERE name LIKE &#8216;coffee%&#8217;;
</code></code></pre><p><strong>What you learned</strong>: common filters and pattern matching (case sensitive <code>LIKE</code>, case-insensitive <code>ILIKE</code>).</p><div><hr></div><h3>Example 3 &#8212; ORDER BY, LIMIT, OFFSET</h3><p><strong>Scenario</strong>: Students leaderboard &#8212; sort by score and paginate.</p><pre><code><code>-- Example 3: order, limit, offset
DROP TABLE IF EXISTS ex3_students;
CREATE TABLE ex3_students (
  student_id SERIAL PRIMARY KEY,
  name TEXT,
  score INTEGER,
  taken_at TIMESTAMP
);

INSERT INTO ex3_students (name, score, taken_at) VALUES
(&#8217;Aisha&#8217;, 92, &#8216;2025-01-05 10:00&#8217;),
(&#8217;Ben&#8217;, 85, &#8216;2025-01-06 11:30&#8217;),
(&#8217;Carla&#8217;, 78, &#8216;2025-01-04 09:20&#8217;),
(&#8217;Derek&#8217;, 92, &#8216;2025-01-07 14:00&#8217;),
(&#8217;Eve&#8217;, 68, &#8216;2025-01-03 08:00&#8217;);

-- Sort by highest score first, newest attempt first
SELECT name, score, taken_at
FROM ex3_students
ORDER BY score DESC, taken_at DESC;

-- Only top 3
SELECT name, score FROM ex3_students ORDER BY score DESC LIMIT 3;

-- Pagination: skip first 2, show next 2
SELECT name, score FROM ex3_students ORDER BY score DESC LIMIT 2 OFFSET 2;
</code></code></pre><p><strong>What you learned</strong>: ordering, limiting results and simple pagination with <code>LIMIT</code> and <code>OFFSET</code>.</p><div><hr></div><h3>Example 4 &#8212; Aliases, expressions, and casting</h3><p><strong>Scenario</strong>: Employee salaries; show monthly pay and format.</p><pre><code><code>-- Example 4: aliases, calculation, type casting
DROP TABLE IF EXISTS ex4_staff;
CREATE TABLE ex4_staff (
  staff_id SERIAL PRIMARY KEY,
  name TEXT,
  annual_salary NUMERIC(12,2),
  join_date DATE
);

INSERT INTO ex4_staff (name, annual_salary, join_date) VALUES
(&#8217;Ramesh&#8217;, 60000.00, &#8216;2020-06-15&#8217;),
(&#8217;Julia&#8217;, 48000.50, &#8216;2021-09-01&#8217;),
(&#8217;Liam&#8217;, 72000.00, &#8216;2019-03-10&#8217;);

-- Calculate monthly salary (simple division), show with alias
SELECT name,
       annual_salary,
       (annual_salary / 12) AS monthly_salary
FROM ex4_staff;

-- Round monthly salary to 2 decimals and show as text label
SELECT name,
       annual_salary,
       ROUND(annual_salary / 12, 2) AS monthly_salary_rounded,
       (ROUND(annual_salary / 12, 2))::TEXT || &#8216; EUR/month&#8217; AS pay_label
FROM ex4_staff;
</code></code></pre><p><strong>What you learned</strong>: you can do math in <code>SELECT</code>, assign a friendly column name with <code>AS</code>, and cast results to text for readable labels.</p><div><hr></div><h3>Example 5 &#8212; DISTINCT and basic uniqueness check</h3><p><strong>Scenario</strong>: Orders with cities &#8212; find unique cities, and count distinct.</p><pre><code><code>-- Example 5: DISTINCT
DROP TABLE IF EXISTS ex5_orders;
CREATE TABLE ex5_orders (
  order_id SERIAL PRIMARY KEY,
  customer TEXT,
  city TEXT,
  amount NUMERIC(8,2)
);

INSERT INTO ex5_orders (customer, city, amount) VALUES
(&#8217;Anna&#8217;, &#8216;Brussels&#8217;, 34.50),
(&#8217;Ben&#8217;, &#8216;Brussels&#8217;, 15.00),
(&#8217;Carmen&#8217;, &#8216;Antwerp&#8217;, 44.00),
(&#8217;David&#8217;, &#8216;Ghent&#8217;, 21.25),
(&#8217;Ella&#8217;, &#8216;Antwerp&#8217;, 99.99);

-- Get unique cities
SELECT DISTINCT city FROM ex5_orders;

-- Count unique cities
SELECT COUNT(DISTINCT city) AS unique_city_count FROM ex5_orders;

-- Distinct combinations (customer+city)
SELECT DISTINCT customer, city FROM ex5_orders;
</code></code></pre><p><strong>What you learned</strong>: <code>DISTINCT</code> removes duplicates from the result set.</p><div><hr></div><h3>Example 6 &#8212; Basic table constraints (NOT NULL, UNIQUE, PRIMARY KEY)</h3><p><strong>Scenario</strong>: Simple contacts table demonstrating constraints and safe inserts.</p><pre><code><code>-- Example 6: constraints
DROP TABLE IF EXISTS ex6_contacts;
CREATE TABLE ex6_contacts (
  contact_id SERIAL PRIMARY KEY,
  email TEXT UNIQUE NOT NULL,
  name TEXT NOT NULL,
  phone TEXT
);

-- valid insert
INSERT INTO ex6_contacts (email, name, phone) VALUES
(&#8217;alice@example.com&#8217;,&#8217;Alice&#8217;,&#8217;+32-2-555-0100&#8217;),
(&#8217;bob@example.com&#8217;,&#8217;Bob&#8217;,NULL);

-- Trying to insert NULL into email or duplicate email would fail:
-- (these lines are commented out so script runs; try them manually)
-- INSERT INTO ex6_contacts (email, name) VALUES (NULL, &#8216;Bad&#8217;); -- error due to NOT NULL
-- INSERT INTO ex6_contacts (email, name) VALUES (&#8217;alice@example.com&#8217;,&#8217;Duplicate&#8217;); -- UNIQUE violation

SELECT * FROM ex6_contacts;
</code></code></pre><p><strong>What you learned</strong>: constraints enforce rules &#8212; <code>NOT NULL</code>, <code>UNIQUE</code>, <code>PRIMARY KEY</code> keep data valid. I commented the failing inserts so the script runs cleanly; try them yourself to see the errors.</p><div><hr></div><h2>Quick troubleshooting tips</h2><ul><li><p>If you see <code>relation &#8220;ex1_people&#8221; does not exist</code>, make sure you executed the <code>CREATE TABLE</code> block first.</p></li><li><p>If an <code>INSERT</code> fails with <code>duplicate key value violates unique constraint</code>, it means you tried to insert a value that must be unique (like an email or primary key).</p></li><li><p>Use <code>\d tablename</code> in <code>psql</code> to inspect table structure.</p></li></ul><div><hr></div><h2>10 Exercises (practice tasks for Chapter 1)</h2><p>Try these on your own. For each exercise write SQL to solve it.</p><ol><li><p><strong>Make a </strong><code>books</code><strong> table</strong> with columns <code>book_id</code> (PK), <code>title</code>, <code>author</code>, <code>price</code>. Insert 6 books, then select all books cheaper than 20.</p></li><li><p><strong>Create a </strong><code>visitors</code><strong> table</strong> with <code>visitor_id</code>, <code>name</code>, <code>visit_date</code>. Insert 5 rows. Select rows where <code>visit_date</code> is after <code>&#8216;2025-01-01&#8217;</code>.</p></li><li><p><strong>Filter by multiple conditions</strong>: Using a table <code>ex2_products</code>-style, select products where <code>category = &#8216;Stationery&#8217;</code> <strong>and</strong> <code>price &lt; 5</code>.</p></li><li><p><strong>Case-insensitive search</strong>: Create a <code>users</code> table with usernames in mixed case. Use a query to find username starting with <code>&#8216;jo&#8217;</code> regardless of case.</p></li><li><p><strong>Top-N</strong>: Create a <code>scores</code> table, insert 8 rows and return top 3 scorers.</p></li><li><p><strong>Aliases and calculations</strong>: Make a <code>sales</code> table with <code>unit_price</code> and <code>quantity</code>. Show <code>total = unit_price * quantity</code> with alias <code>order_total</code>.</p></li><li><p><strong>Distinct usage</strong>: Create an <code>events</code> table with event names and cities. List all distinct cities.</p></li><li><p><strong>Constraint test</strong>: Create a <code>members</code> table where <code>email</code> must be unique and <code>name</code> not null. Try inserting duplicates to see the error. (Explain what happened.)</p></li><li><p><strong>Limit + Offset</strong>: Create a <code>messages</code> table and return rows 6&#8211;10 ordered by timestamp (simulate pagination).</p></li><li><p><strong>Explain why NULL matters</strong>: Create a table with a column allowed to be NULL. Insert a row with NULL and another without. Show how <code>WHERE column = &#8216;something&#8217;</code> ignores the NULL row, but <code>WHERE column IS NULL</code> picks it up.</p></li></ol><div><hr></div><h1>Chapter 2 &#8212; <strong>Aggregations &amp; Grouping</strong></h1><p><em>(Plain-English explanations + very detailed examples you can copy-paste + 10 hands-on exercises)</em></p><p>Bavi &#8212; this chapter teaches how to <strong>summarize</strong> and <strong>roll up</strong> data: counts, sums, averages, min/max, and how to group rows into buckets (by product, by day, by city) so you can get the high-level numbers data scientists need for EDA and feature engineering.</p><div><hr></div><h2>What you&#8217;ll learn in plain English</h2><ul><li><p><strong>Aggregate functions</strong> are small math tools Postgres gives you: <code>COUNT</code>, <code>SUM</code>, <code>AVG</code>, <code>MIN</code>, <code>MAX</code>. They take many rows and return one number (e.g., total sales).</p></li><li><p><strong>GROUP BY</strong> collects rows into buckets (e.g., one bucket per product) so you can run aggregates per bucket.</p></li><li><p><strong>HAVING</strong> filters buckets after aggregation (e.g., show only products whose total sales exceed &#8364;500).</p></li><li><p><strong>COUNT(*) vs COUNT(column)</strong> &#8212; <code>COUNT(*)</code> counts rows; <code>COUNT(column)</code> only counts non-NULL values.</p></li><li><p><strong>COUNT(DISTINCT ...)</strong> counts unique values inside each group.</p></li><li><p><strong>FILTER</strong> (Postgres feature) lets you run conditional aggregates in the same query (e.g., count purchases vs refunds).</p></li><li><p><strong>DATE_TRUNC</strong> is handy to group timestamps by month/week/day. Very useful for time-series features.</p></li></ul><p>All examples below are <strong>fully self-contained</strong> (they <code>DROP</code> then <code>CREATE</code> tables and <code>INSERT</code> data). Copy-paste any single example into your <code>psql</code>, pgAdmin, DBeaver, or other Postgres client and it will run.</p><div><hr></div><h2>Example 1 &#8212; Simple aggregates: COUNT, SUM, AVG, MIN, MAX</h2><p><strong>Goal:</strong> See the basic aggregate functions in action on a small <code>transactions</code> table.</p><pre><code><code>-- EX1: Basic aggregates
DROP TABLE IF EXISTS ex1_transactions;
CREATE TABLE ex1_transactions (
  txn_id   SERIAL PRIMARY KEY,
  user_id  INTEGER,
  amount   NUMERIC(10,2),
  txn_time TIMESTAMP
);

INSERT INTO ex1_transactions (user_id, amount, txn_time) VALUES
(1, 12.50, &#8216;2025-01-01 09:10&#8217;),
(2, 7.00,  &#8216;2025-01-01 10:00&#8217;),
(1, 5.25,  &#8216;2025-01-02 11:15&#8217;),
(3, NULL,  &#8216;2025-01-03 12:00&#8217;), -- failed / missing amount
(2, 20.00, &#8216;2025-01-04 13:00&#8217;),
(4, 100.00,&#8217;2025-01-05 14:30&#8217;);

-- a) total number of transactions (rows)
SELECT COUNT(*) AS total_transactions FROM ex1_transactions;

-- b) total amount of all transactions (NULL values ignored by SUM)
SELECT SUM(amount) AS total_amount FROM ex1_transactions;

-- c) average amount per transaction (NULLs ignored)
SELECT AVG(amount) AS avg_amount FROM ex1_transactions;

-- d) smallest and largest transaction amounts
SELECT MIN(amount) AS smallest, MAX(amount) AS largest FROM ex1_transactions;

-- e) combine them in one row for an overview
SELECT
  COUNT(*) AS total_rows,
  COUNT(amount) AS rows_with_amount,
  SUM(amount) AS sum_amount,
  AVG(amount) AS avg_amount,
  MIN(amount) AS min_amount,
  MAX(amount) AS max_amount
FROM ex1_transactions;
</code></code></pre><p><strong>Why this matters (layman):</strong> <code>COUNT</code> tells you how many rows; <code>SUM</code> adds numbers; <code>AVG</code> finds the mean; <code>MIN</code> and <code>MAX</code> show extremes. Notice <code>SUM</code> and <code>AVG</code> ignore <code>NULL</code> amounts &#8212; that prevents broken math when some rows are missing data.</p><div><hr></div><h2>Example 2 &#8212; GROUP BY a single column: totals per category</h2><p><strong>Goal:</strong> Group sales by <code>category</code> to see which categories sell the most.</p><pre><code><code>-- EX2: Group by category (sales totals and counts)
DROP TABLE IF EXISTS ex2_category_sales;
CREATE TABLE ex2_category_sales (
  sale_id  SERIAL PRIMARY KEY,
  product  TEXT,
  category TEXT,
  qty      INTEGER,
  unit_price NUMERIC(8,2)
);

INSERT INTO ex2_category_sales (product, category, qty, unit_price) VALUES
(&#8217;Espresso Beans&#8217;,&#8217;Beverage&#8217;, 10, 12.50),
(&#8217;Green Tea&#8217;,&#8217;Beverage&#8217;, 5, 8.00),
(&#8217;Notebook A4&#8217;,&#8217;Stationery&#8217;, 50, 3.25),
(&#8217;Premium Notebook&#8217;,&#8217;Stationery&#8217;, 20, 7.50),
(&#8217;Espresso Machine&#8217;,&#8217;Appliance&#8217;, 2, 120.00),
(&#8217;Mug&#8217;,&#8217;Merch&#8217;, 100, 4.00),
(&#8217;Sticker Pack&#8217;,&#8217;Merch&#8217;, 200, 1.50);

-- Calculate total sales per category and number of items sold
SELECT
  category,
  SUM(qty * unit_price) AS total_revenue,
  SUM(qty) AS total_units_sold,
  COUNT(*) AS number_of_line_items
FROM ex2_category_sales
GROUP BY category
ORDER BY total_revenue DESC;
</code></code></pre><p><strong>What you see:</strong> Each <code>category</code> becomes one row; inside that row we compute <code>SUM(qty * unit_price)</code> to get revenue for that category. <code>GROUP BY</code> is how we &#8220;fold&#8221; rows into buckets.</p><div><hr></div><h2>Example 3 &#8212; GROUP BY multiple columns and time bucketing (DATE_TRUNC)</h2><p><strong>Goal:</strong> For each city and each month, compute total revenue &#8212; extremely useful for time-series features.</p><pre><code><code>-- EX3: Group by city and month (time bucketing)
DROP TABLE IF EXISTS ex3_orders;
CREATE TABLE ex3_orders (
  order_id   SERIAL PRIMARY KEY,
  customer   TEXT,
  city       TEXT,
  amount     NUMERIC(10,2),
  order_ts   TIMESTAMP
);

INSERT INTO ex3_orders (customer, city, amount, order_ts) VALUES
(&#8217;Anna&#8217;,&#8217;Brussels&#8217;, 34.50, &#8216;2025-01-05 10:00&#8217;),
(&#8217;Ben&#8217;,&#8217;Brussels&#8217;, 15.00, &#8216;2025-01-06 12:00&#8217;),
(&#8217;Carmen&#8217;,&#8217;Antwerp&#8217;, 44.00, &#8216;2025-01-20 09:00&#8217;),
(&#8217;David&#8217;,&#8217;Ghent&#8217;, 21.25, &#8216;2025-02-02 11:00&#8217;),
(&#8217;Ella&#8217;,&#8217;Antwerp&#8217;, 99.99, &#8216;2025-02-10 14:00&#8217;),
(&#8217;Fahad&#8217;,&#8217;Brussels&#8217;, 12.00, &#8216;2025-02-12 16:00&#8217;),
(&#8217;Gina&#8217;,&#8217;Brussels&#8217;, 60.00, &#8216;2025-03-01 10:30&#8217;);

-- Group by city and month
SELECT
  city,
  DATE_TRUNC(&#8217;month&#8217;, order_ts) AS month,
  COUNT(*) AS orders_count,
  SUM(amount) AS month_revenue,
  AVG(amount) AS avg_order_value
FROM ex3_orders
GROUP BY city, DATE_TRUNC(&#8217;month&#8217;, order_ts)
ORDER BY month, city;
</code></code></pre><p><strong>Why this is handy:</strong> <code>DATE_TRUNC(&#8217;month&#8217;, order_ts)</code> converts a timestamp to the month (e.g., &#8216;2025-02-01 00:00:00&#8217;) so months become grouping keys. Grouping by more than one column (city + month) gives a grid of metrics you can turn into time-series features for ML.</p><div><hr></div><h2>Example 4 &#8212; HAVING vs WHERE: filter groups (correct way)</h2><p><strong>Goal:</strong> Show how to keep only buckets that meet a condition (like categories with total revenue &gt; 100).</p><pre><code><code>-- EX4: HAVING to filter groups
DROP TABLE IF EXISTS ex4_sales;
CREATE TABLE ex4_sales (
  id SERIAL PRIMARY KEY,
  category TEXT,
  amount   NUMERIC(8,2)
);

INSERT INTO ex4_sales (category, amount) VALUES
(&#8217;Beverage&#8217;, 12.50),
(&#8217;Beverage&#8217;, 8.00),
(&#8217;Stationery&#8217;, 3.25),
(&#8217;Stationery&#8217;, 7.50),
(&#8217;Appliance&#8217;, 120.00),
(&#8217;Merch&#8217;, 4.00),
(&#8217;Merch&#8217;, 1.50),
(&#8217;Merch&#8217;, 150.00);

-- WRONG: this would fail because WHERE cannot use aggregates (commented)
-- SELECT category, SUM(amount) FROM ex4_sales WHERE SUM(amount) &gt; 100 GROUP BY category;

-- RIGHT: use HAVING to filter groups after aggregation
SELECT
  category,
  SUM(amount) AS total_revenue
FROM ex4_sales
GROUP BY category
HAVING SUM(amount) &gt; 100
ORDER BY total_revenue DESC;

-- Alternative: using a subquery with WHERE (also valid)
SELECT category, total_revenue FROM (
  SELECT category, SUM(amount) AS total_revenue
  FROM ex4_sales
  GROUP BY category
) t
WHERE total_revenue &gt; 100;
</code></code></pre><p><strong>Layman explanation:</strong> <code>WHERE</code> filters individual rows <em>before</em> grouping. <code>HAVING</code> filters the grouped results <em>after</em> you compute SUM/AVG/etc. Use <code>HAVING</code> when your condition uses aggregated numbers.</p><div><hr></div><h2>Example 5 &#8212; COUNT(DISTINCT), FILTER clause, and conditional aggregates</h2><p><strong>Goal:</strong> Count unique users and compute purchase-only sums in the same grouped query.</p><pre><code><code>-- EX5: DISTINCT counts and FILTER (Postgres)
DROP TABLE IF EXISTS ex5_user_events;
CREATE TABLE ex5_user_events (
  event_id   SERIAL PRIMARY KEY,
  user_id    INTEGER,
  event_type TEXT,     -- &#8216;view&#8217;, &#8216;add_to_cart&#8217;, &#8216;purchase&#8217;, &#8216;refund&#8217;
  amount     NUMERIC(10,2),
  event_ts   TIMESTAMP
);

INSERT INTO ex5_user_events (user_id, event_type, amount, event_ts) VALUES
(1, &#8216;view&#8217;, NULL,  &#8216;2025-03-01 09:00&#8217;),
(1, &#8216;add_to_cart&#8217;, NULL, &#8216;2025-03-01 09:05&#8217;),
(1, &#8216;purchase&#8217;, 20.00, &#8216;2025-03-01 09:06&#8217;),
(2, &#8216;view&#8217;, NULL, &#8216;2025-03-01 10:00&#8217;),
(2, &#8216;purchase&#8217;, 15.00, &#8216;2025-03-02 11:00&#8217;),
(3, &#8216;view&#8217;, NULL, &#8216;2025-03-02 12:00&#8217;),
(3, &#8216;purchase&#8217;, 7.50, &#8216;2025-03-02 12:05&#8217;),
(3, &#8216;refund&#8217;, -7.50, &#8216;2025-03-03 13:00&#8217;),
(4, &#8216;purchase&#8217;, 100.00, &#8216;2025-03-04 14:00&#8217;),
(4, &#8216;purchase&#8217;, 50.00, &#8216;2025-03-05 15:00&#8217;);

-- Aggregate example: per-day summary
SELECT
  DATE(event_ts) AS day,
  COUNT(*) AS total_events,
  COUNT(DISTINCT user_id) AS unique_users,
  COUNT(*) FILTER (WHERE event_type = &#8216;purchase&#8217;) AS purchase_events,
  SUM(amount) FILTER (WHERE event_type = &#8216;purchase&#8217;) AS purchase_amount,
  SUM(amount) FILTER (WHERE event_type = &#8216;refund&#8217;) AS refund_amount
FROM ex5_user_events
GROUP BY DATE(event_ts)
ORDER BY day;
</code></code></pre><p><strong>Plain take-away:</strong> <code>COUNT(DISTINCT user_id)</code> gives number of unique users. <code>FILTER (WHERE ...)</code> is a clean Postgres way to say &#8220;run this aggregate but only for rows that match this condition&#8221; &#8212; very useful to compute multiple conditional counts/sums in a single query.</p><div><hr></div><h2>Example 6 &#8212; NULLs, COUNT(*) vs COUNT(col), and grouping NULLs with COALESCE</h2><p><strong>Goal:</strong> Understand how NULL affects aggregates and how to group NULL values cleanly.</p><pre><code><code>-- EX6: NULL handling in aggregates
DROP TABLE IF EXISTS ex6_feedback;
CREATE TABLE ex6_feedback (
  fb_id    SERIAL PRIMARY KEY,
  product_id INTEGER,  -- can be NULL (feedback not tied to product)
  rating   INTEGER,    -- 1..5 or NULL if not rated
  comments TEXT
);

INSERT INTO ex6_feedback (product_id, rating, comments) VALUES
(1, 5, &#8216;Great&#8217;),
(1, 4, &#8216;Good&#8217;),
(NULL, 3, &#8216;General feedback&#8217;),
(2, NULL, &#8216;No rating&#8217;),
(2, 2, &#8216;Poor&#8217;),
(NULL, NULL, &#8216;Anonymous note&#8217;);

-- Counts:
SELECT
  COUNT(*) AS total_rows,
  COUNT(product_id) AS rows_with_product_id,
  COUNT(rating) AS rows_with_rating,
  COUNT(DISTINCT product_id) AS distinct_products_referenced
FROM ex6_feedback;

-- Group by product_id will put NULLs in a distinct bucket.
-- Use COALESCE to label NULL product_id as &#8216;unknown&#8217; when grouping.
SELECT
  COALESCE(product_id::TEXT, &#8216;unknown&#8217;) AS product_label,
  COUNT(*) AS feedback_count,
  AVG(rating) AS avg_rating
FROM ex6_feedback
GROUP BY COALESCE(product_id::TEXT, &#8216;unknown&#8217;);
</code></code></pre><p><strong>Key point for beginners:</strong> <code>COUNT(*)</code> counts every row. <code>COUNT(product_id)</code> ignores rows where <code>product_id</code> is <code>NULL</code>. When grouping, <code>NULL</code> is a real bucket &#8212; use <code>COALESCE</code> to make it human-friendly (e.g., <code>&#8216;unknown&#8217;</code>).</p><div><hr></div><h2>Quick practical tips (layman)</h2><ul><li><p>If you want totals per day/week/month: use <code>DATE_TRUNC(&#8217;day&#8217;|&#8217;week&#8217;|&#8217;month&#8217;, timestamp_col)</code> in <code>GROUP BY</code>.</p></li><li><p>Use <code>ORDER BY</code> on aggregated columns (e.g., <code>ORDER BY SUM(amount) DESC</code>) to find top buckets.</p></li><li><p>To filter groups by their aggregate value use <code>HAVING</code>.</p></li><li><p>Use <code>COUNT(DISTINCT ...)</code> to know how many unique users, products, etc.</p></li><li><p>If you need multiple conditional aggregates (e.g., purchases vs refunds), use <code>FILTER</code> &#8212; it&#8217;s clearer than <code>SUM(CASE WHEN ...)</code>. (Both work.)</p></li></ul><div><hr></div><h2>10 Exercises &#8212; practice (all should be solved in PostgreSQL)</h2><p>Try to write the SQL for each. If you want, I&#8217;ll provide the full runnable solution scripts afterwards.</p><ol><li><p><strong>Total revenue &amp; average order value:</strong> Create an <code>orders</code> table (order_id, customer_id, amount, order_ts). Insert 12 rows across two months. Write a query that returns the total revenue and AVG order amount for the entire dataset.</p></li><li><p><strong>Revenue per product:</strong> Create <code>product_sales(product, category, qty, unit_price)</code> (insert 20 rows across 4 categories). Return total revenue and units sold <strong>per category</strong>, sorted by revenue descending.</p></li><li><p><strong>Monthly active users:</strong> Create <code>events(user_id, event_type, event_ts)</code> where event_type can be <code>&#8216;view&#8217;</code> or <code>&#8216;purchase&#8217;</code>. Write a query that shows month (YYYY-MM) and number of unique users who made a purchase in that month.</p></li><li><p><strong>Top 3 customers:</strong> Using an <code>orders</code> table (customer_id, amount), return the top 3 customers by total spending (customer_id and total_spent).</p></li><li><p><strong>Filter groups with HAVING:</strong> Create a <code>sales</code> table and find categories whose total sales amount is at least 500. Use <code>HAVING</code>.</p></li><li><p><strong>Conditional aggregates:</strong> Create <code>events</code> with types <code>&#8216;purchase&#8217;</code> and <code>&#8216;refund&#8217;</code>. For each day, compute: <code>total_events</code>, <code>purchase_count</code>, <code>refund_count</code>, <code>purchase_amount</code>, <code>refund_amount</code>. Use <code>FILTER</code> or <code>SUM(CASE WHEN ...)</code>.</p></li><li><p><strong>Count vs Count(column):</strong> Build a <code>responses</code> table with a nullable <code>rating</code> and show <code>COUNT(*)</code> vs <code>COUNT(rating)</code> and explain the difference in one sentence (as a SQL comment).</p></li><li><p><strong>Group by multiple columns:</strong> Using an <code>orders</code> table with <code>city</code> and <code>order_ts</code>, compute <code>city, month, orders_count, total_amount</code> grouped by <code>city</code> and month for the last 90 days.</p></li><li><p><strong>Top-N per group (advanced):</strong> For <code>sales(employee_id, region, sale_amount)</code>, find the highest sale per region (region + employee_id + sale_amount). <em>(Hint: use </em><code>ROW_NUMBER()</code><em> over partition &#8212; this crosses into window functions but is very useful. If you prefer not to use window functions yet, use a subquery per region.)</em></p></li><li><p><strong>Distinct counts in groups:</strong> Create a <code>visits(user_id, page, visit_ts)</code> table. For each page, compute how many unique users visited it and the total visits. Sort pages by unique users descending.</p></li></ol><div><hr></div><h1>Chapter 3 &#8212; Joins (Very plain-English + runnable examples + 10 exercises)</h1><p>Alright Bavi &#8212; here&#8217;s <strong>Chapter 3: Joins</strong>. I&#8217;ll explain every concept like you&#8217;re reading a friendly cheat-sheet, then provide <strong>at least 5 fully runnable examples</strong> (each example drops/creates its own tables and inserts data so you can copy/paste and run). Every example is followed by a short plain-language explanation. At the end are <strong>10 exercises</strong> to practice.</p><div><hr></div><h2>What is a JOIN? (super simple)</h2><p>A <strong>join</strong> lets you combine rows from two (or more) tables into a single row in the result &#8212; based on some matching rule.<br>Think of two lists: one is <strong>people</strong>, another is <strong>their phones</strong>. A join answers questions like &#8220;show me each person and their phone&#8221; or &#8220;show all people even if they don&#8217;t have a phone&#8221;.</p><p>Key idea: a join picks rows from Table A and rows from Table B and sticks them together when a matching condition is true (usually when an id in A equals an id in B).</p><div><hr></div><h2>Types of joins &#8212; in one line each</h2><ul><li><p><strong>INNER JOIN</strong>: Only rows that have matches in both tables. (Think: intersection.)</p></li><li><p><strong>LEFT (LEFT OUTER) JOIN</strong>: All rows from the left table; matching rows from right when available; otherwise NULLs for right columns. (Think: everything on the left, bring matching right info.)</p></li><li><p><strong>RIGHT (RIGHT OUTER) JOIN</strong>: All rows from the right table; matching left when available. (Less used but symmetric to LEFT.)</p></li><li><p><strong>FULL OUTER JOIN</strong>: All rows from both tables; where no match exists, fill with NULLs. (Union of left and right with matching combined.)</p></li><li><p><strong>CROSS JOIN</strong>: Cartesian product &#8212; every row from A paired with every row from B (be careful: can explode).</p></li><li><p><strong>SELF JOIN</strong>: A table joined to itself (useful for hierarchies).</p></li><li><p><strong>Multi-table joins</strong>: Chain joins across several tables to build richer rows.</p></li></ul><div><hr></div><h2>Syntax basics</h2><ul><li><p><code>SELECT ... FROM A INNER JOIN B ON A.key = B.key;</code></p></li><li><p><code>LEFT JOIN</code> and <code>RIGHT JOIN</code> work the same but preserve rows from one side.</p></li><li><p>You can use <code>USING(col)</code> when both tables have the same column name for the join key &#8212; this avoids repeating <code>ON A.col = B.col</code>.</p></li></ul><div><hr></div><h2>Example 1 &#8212; INNER JOIN (basic)</h2><pre><code><code>-- EX1: INNER JOIN basic
DROP TABLE IF EXISTS ex1_customers;
DROP TABLE IF EXISTS ex1_orders;

CREATE TABLE ex1_customers (
  customer_id SERIAL PRIMARY KEY,
  name TEXT,
  city TEXT
);

CREATE TABLE ex1_orders (
  order_id SERIAL PRIMARY KEY,
  customer_id INTEGER REFERENCES ex1_customers(customer_id),
  amount NUMERIC(8,2),
  order_ts TIMESTAMP
);

INSERT INTO ex1_customers (name, city) VALUES
(&#8217;Anita&#8217;, &#8216;Brussels&#8217;),
(&#8217;Ben&#8217;, &#8216;London&#8217;),
(&#8217;Carmen&#8217;, &#8216;Antwerp&#8217;);

INSERT INTO ex1_orders (customer_id, amount, order_ts) VALUES
(1, 34.50, &#8216;2025-01-05 10:00&#8217;),
(1, 15.00, &#8216;2025-01-06 12:00&#8217;),
(3, 44.00, &#8216;2025-01-20 09:00&#8217;);

-- Inner join: only customers who have orders
SELECT c.customer_id, c.name, o.order_id, o.amount, o.order_ts
FROM ex1_customers c
INNER JOIN ex1_orders o
  ON c.customer_id = o.customer_id
ORDER BY c.customer_id, o.order_id;
</code></code></pre><p><strong>Plain take-away:</strong> Inner join shows only customers that have orders. Anita and Carmen appear because they have orders; Ben does not because he has none.</p><div><hr></div><h2>Example 2 &#8212; LEFT JOIN (include unmatched left rows)</h2><pre><code><code>-- EX2: LEFT JOIN shows all customers, even if no orders
DROP TABLE IF EXISTS ex2_customers;
DROP TABLE IF EXISTS ex2_orders;

CREATE TABLE ex2_customers (
  customer_id SERIAL PRIMARY KEY,
  name TEXT
);

CREATE TABLE ex2_orders (
  order_id SERIAL PRIMARY KEY,
  customer_id INTEGER,
  amount NUMERIC(8,2)
);

INSERT INTO ex2_customers (name) VALUES
(&#8217;Ali&#8217;),
(&#8217;Beth&#8217;),
(&#8217;Cheng&#8217;);

INSERT INTO ex2_orders (customer_id, amount) VALUES
(1, 10.00),
(1, 5.00),
(3, 100.00);

-- Left join: all customers; orders when available
SELECT c.customer_id, c.name, o.order_id, o.amount
FROM ex2_customers c
LEFT JOIN ex2_orders o
  ON c.customer_id = o.customer_id
ORDER BY c.customer_id;
</code></code></pre><p><strong>Plain take-away:</strong> Beth (customer_id 2) will appear with NULLs for order fields &#8212; left join preserves all left-table rows even if no match on the right.</p><div><hr></div><h2>Example 3 &#8212; RIGHT JOIN and FULL OUTER JOIN</h2><pre><code><code>-- EX3: RIGHT JOIN and FULL OUTER JOIN
DROP TABLE IF EXISTS ex3_employees;
DROP TABLE IF EXISTS ex3_departments;

CREATE TABLE ex3_employees (
  emp_id SERIAL PRIMARY KEY,
  name TEXT,
  dept_id INTEGER
);

CREATE TABLE ex3_departments (
  dept_id SERIAL PRIMARY KEY,
  dept_name TEXT
);

INSERT INTO ex3_employees (name, dept_id) VALUES
(&#8217;Ravi&#8217;, 1),
(&#8217;Mia&#8217;, 2),
(&#8217;Noah&#8217;, NULL);  -- Noah not assigned

INSERT INTO ex3_departments (dept_name) VALUES
(&#8217;Engineering&#8217;),
(&#8217;HR&#8217;),
(&#8217;Legal&#8217;);  -- Legal has no employees yet

-- Right join: all departments, employees info when present
SELECT e.emp_id, e.name, d.dept_id, d.dept_name
FROM ex3_employees e
RIGHT JOIN ex3_departments d
  ON e.dept_id = d.dept_id
ORDER BY d.dept_id;

-- Full outer join: everything from both sides
SELECT e.emp_id, e.name, d.dept_id, d.dept_name
FROM ex3_employees e
FULL OUTER JOIN ex3_departments d
  ON e.dept_id = d.dept_id
ORDER BY COALESCE(d.dept_id, 999), e.emp_id;
</code></code></pre><p><strong>Plain take-away:</strong></p><ul><li><p><code>RIGHT JOIN</code> keeps all departments; Engineering and HR will show matching employees and Legal will show NULL employee columns.</p></li><li><p><code>FULL OUTER JOIN</code> shows Noah (employee with no dept) and Legal (dept with no employees) in the same result.</p></li></ul><div><hr></div><h2>Example 4 &#8212; CROSS JOIN (cartesian product)</h2><pre><code><code>-- EX4: CROSS JOIN can blow up rows, use with care
DROP TABLE IF EXISTS ex4_colors;
DROP TABLE IF EXISTS ex4_sizes;

CREATE TABLE ex4_colors (color TEXT);
CREATE TABLE ex4_sizes (size TEXT);

INSERT INTO ex4_colors VALUES (&#8217;Red&#8217;), (&#8217;Blue&#8217;);
INSERT INTO ex4_sizes VALUES (&#8217;S&#8217;), (&#8217;M&#8217;), (&#8217;L&#8217;);

-- Cross join: every color combined with every size (2 * 3 = 6 rows)
SELECT color, size FROM ex4_colors CROSS JOIN ex4_sizes ORDER BY color, size;
</code></code></pre><p><strong>Plain take-away:</strong> CROSS JOIN pairs every row from first table with every row from second. Useful for generating combinations, but be careful with big tables.</p><div><hr></div><h2>Example 5 &#8212; SELF JOIN (table joined to itself)</h2><pre><code><code>-- EX5: SELF JOIN for manager-employee relationships
DROP TABLE IF EXISTS ex5_people;

CREATE TABLE ex5_people (
  person_id SERIAL PRIMARY KEY,
  name TEXT,
  manager_id INTEGER  -- points to person_id
);

INSERT INTO ex5_people (name, manager_id) VALUES
(&#8217;CEO&#8217;, NULL),
(&#8217;Alice&#8217;, 1),
(&#8217;Bob&#8217;, 1),
(&#8217;Charlie&#8217;, 2),
(&#8217;Diana&#8217;, 2);

-- Self join: show employee + their manager name
SELECT e.person_id AS emp_id, e.name AS employee,
       m.person_id AS mgr_id, m.name AS manager
FROM ex5_people e
LEFT JOIN ex5_people m
  ON e.manager_id = m.person_id
ORDER BY e.person_id;
</code></code></pre><p><strong>Plain take-away:</strong> Self join treats the table as two roles (employee and manager) so we can display relationships stored as IDs in the same table.</p><div><hr></div><h2>Example 6 &#8212; Multi-table joins (chain joins) + USING</h2><pre><code><code>-- EX6: Multi-table join (orders -&gt; customers -&gt; shipments)
DROP TABLE IF EXISTS ex6_customers;
DROP TABLE IF EXISTS ex6_orders;
DROP TABLE IF EXISTS ex6_shipments;

CREATE TABLE ex6_customers (
  customer_id SERIAL PRIMARY KEY,
  name TEXT
);

CREATE TABLE ex6_orders (
  order_id SERIAL PRIMARY KEY,
  customer_id INTEGER REFERENCES ex6_customers(customer_id),
  amount NUMERIC(8,2)
);

CREATE TABLE ex6_shipments (
  shipment_id SERIAL PRIMARY KEY,
  order_id INTEGER REFERENCES ex6_orders(order_id),
  shipped_at TIMESTAMP
);

INSERT INTO ex6_customers (name) VALUES (&#8217;Sam&#8217;), (&#8217;Tina&#8217;);
INSERT INTO ex6_orders (customer_id, amount) VALUES (1, 10),(1,20),(2,50);
INSERT INTO ex6_shipments (order_id, shipped_at) VALUES (1, &#8216;2025-01-02&#8217;), (3, &#8216;2025-01-05&#8217;);

-- Chain join: bring customer, order, and shipment info together
SELECT c.customer_id, c.name, o.order_id, o.amount, s.shipment_id, s.shipped_at
FROM ex6_customers c
JOIN ex6_orders o USING (customer_id)      -- shorthand when same column name
LEFT JOIN ex6_shipments s ON o.order_id = s.order_id
ORDER BY c.customer_id, o.order_id;
</code></code></pre><p><strong>Plain take-away:</strong> You can chain joins to assemble richer records. <code>USING(column)</code> saves typing when both tables have the same join column name &#8212; the output will show that column only once.</p><div><hr></div><h2>Example 7 &#8212; JOIN with aggregate (which side to aggregate?)</h2><pre><code><code>-- EX7: Join and aggregate &#8212; total orders per customer
DROP TABLE IF EXISTS ex7_customers;
DROP TABLE IF EXISTS ex7_orders;

CREATE TABLE ex7_customers (
  customer_id SERIAL PRIMARY KEY,
  name TEXT
);

CREATE TABLE ex7_orders (
  order_id SERIAL PRIMARY KEY,
  customer_id INTEGER,
  amount NUMERIC(8,2)
);

INSERT INTO ex7_customers (name) VALUES (&#8217;Umar&#8217;), (&#8217;Vera&#8217;), (&#8217;Wes&#8217;);
INSERT INTO ex7_orders (customer_id, amount) VALUES (1,10),(1,20),(2,5);

-- Option A: aggregate then join (good when you want customers with totals)
SELECT c.customer_id, c.name, COALESCE(t.total_spent, 0) AS total_spent
FROM ex7_customers c
LEFT JOIN (
  SELECT customer_id, SUM(amount) AS total_spent
  FROM ex7_orders
  GROUP BY customer_id
) t ON c.customer_id = t.customer_id
ORDER BY c.customer_id;

-- Option B: join then group (works too)
SELECT c.customer_id, c.name, SUM(o.amount) AS total_spent
FROM ex7_customers c
LEFT JOIN ex7_orders o ON c.customer_id = o.customer_id
GROUP BY c.customer_id, c.name
ORDER BY c.customer_id;
</code></code></pre><p><strong>Plain take-away:</strong> You can aggregate before or after joining. Aggregating first reduces row volume (useful for big data). Both produce same results here; choose what reads better and performs well.</p><div><hr></div><h2>Example 8 &#8212; JOIN pitfalls: duplicate join columns and ambiguous column names</h2><pre><code><code>-- EX8: ambiguous column names - aliasing required
DROP TABLE IF EXISTS ex8_a;
DROP TABLE IF EXISTS ex8_b;

CREATE TABLE ex8_a (id SERIAL PRIMARY KEY, name TEXT);
CREATE TABLE ex8_b (id SERIAL PRIMARY KEY, a_id INTEGER, value TEXT);

INSERT INTO ex8_a (name) VALUES (&#8217;X&#8217;), (&#8217;Y&#8217;);
INSERT INTO ex8_b (a_id, value) VALUES (1,&#8217;v1&#8217;), (1,&#8217;v2&#8217;), (2,&#8217;v3&#8217;);

-- If both tables have a column named &#8216;id&#8217; and you select id alone, SQL errors or is ambiguous.
-- Always qualify or alias columns when names repeat.
SELECT a.id AS a_id, a.name, b.id AS b_id, b.value
FROM ex8_a a
JOIN ex8_b b ON a.id = b.a_id;
</code></code></pre><p><strong>Plain take-away:</strong> When columns share the same name in joined tables, always prefix with table alias (e.g., <code>a.id</code>) or rename in the SELECT list to avoid confusion.</p><div><hr></div><h2>10 Exercises &#8212; Joins (try them out)</h2><p>For each exercise, create tables and insert sample rows (5&#8211;12 rows usually) then write the query.</p><ol><li><p><strong>Inner join practice:</strong> Create <code>students(student_id, name)</code> and <code>marks(student_id, subject, marks)</code>. Show student name + their math mark only (assume subject=&#8217;math&#8217;).</p></li><li><p><strong>Left join rows with no match:</strong> <code>employees(emp_id, name)</code> and <code>asset_assignments(emp_id, asset)</code>. Show all employees and their assets; employees without assets should show NULL.</p></li><li><p><strong>Full outer join scenario:</strong> <code>local_inventory(item_id, qty)</code> and <code>warehouse_inventory(item_id, qty)</code>. Show combined view with <code>COALESCE</code> to show item_id and both quantities; include items only in one location.</p></li><li><p><strong>Self join &#8212; reporting chain:</strong> Create <code>team(member_id, name, reports_to)</code> and show each person with their manager name. Also show people who have no manager.</p></li><li><p><strong>Multi-table join:</strong> <code>users</code>, <code>orders</code>, <code>payments</code> &#8212; show user name, order id, payment status. Include orders even if payment not recorded.</p></li><li><p><strong>Top N per group without window functions (subquery approach):</strong> For <code>sales(region, rep, amount)</code>, find the highest single sale per region. (Hint: group by region, get max(amount), join back.)</p></li><li><p><strong>Using USING shortcut:</strong> Create two tables sharing <code>product_id</code>. Demonstrate join with <code>USING(product_id)</code> and show the joined columns (note how product_id appears once).</p></li><li><p><strong>Cross join use-case:</strong> <code>colors</code> and <code>sizes</code> &#8212; generate SKU combinations with a synthetic SKU code (<code>color || &#8216;-&#8217; || size</code>). Show how many rows you created.</p></li><li><p><strong>Ambiguous names:</strong> Create two tables both with column <code>id</code>. Write a join and show how you alias both <code>id</code>s in the output to avoid ambiguity.</p></li><li><p><strong>Join + filter order:</strong> Create <code>courses(course_id, name)</code>, <code>enrollments(student_id, course_id, enrolled_at)</code>, and <code>students(student_id, name)</code>. Show names of students who enrolled in &#8216;Data Science 101&#8217; after &#8216;2025-01-01&#8217;. Use proper joins and WHERE on the joined data.</p></li></ol><div><hr></div><h1>Chapter 4 &#8212; Subqueries &amp; CTEs (Common Table Expressions)</h1><p><em>(Step-by-step explanations + runnable examples + 10 exercises)</em></p><p>Hey Bavi &#8212; welcome to Chapter 4 &#127919;.<br>This is where we start writing <strong>multi-level SQL queries</strong> &#8212; a foundation for building <strong>AI-ready data transformations</strong> and <strong>feature pipelines</strong>.<br>We&#8217;ll learn to use <strong>subqueries</strong> (queries inside queries) and <strong>CTEs (</strong><code>WITH</code><strong> clause)</strong> to make your SQL cleaner, modular, and easier to debug.</p><div><hr></div><h2>&#129504; What You&#8217;ll Learn</h2><p>By the end of this chapter, you&#8217;ll be able to:</p><ul><li><p>Understand what <strong>subqueries</strong> are and how they work.</p></li><li><p>Use <strong>subqueries</strong> in <code>SELECT</code>, <code>FROM</code>, and <code>WHERE</code> clauses.</p></li><li><p>Use <strong>correlated subqueries</strong> (where the inner query depends on the outer one).</p></li><li><p>Understand <code>EXISTS</code> vs <code>IN</code>.</p></li><li><p>Build clean, reusable queries with <strong>Common Table Expressions (CTEs)</strong> using <code>WITH</code>.</p></li><li><p>Chain multiple CTEs to build complex transformations step-by-step.</p></li></ul><p>All examples below are <strong>copy-paste runnable</strong> &#8212; each creates its own data, so nothing conflicts.</p><div><hr></div><h2>&#129513; 1. What Is a Subquery? (Plain-English Explanation)</h2><p>Think of a <strong>subquery</strong> as a <strong>small query inside another query</strong> &#8212; like doing one calculation first, then using its result in a bigger calculation.</p><p>It&#8217;s like:</p><blockquote><p>&#8220;First, find the average salary. Then, find all employees earning more than that.&#8221;</p></blockquote><p>Subqueries help <strong>break complex problems</strong> into smaller steps.</p><div><hr></div><h2>&#129513; 2. Subquery in <code>WHERE</code> (Find rows based on results of another query)</h2><pre><code><code>-- EX1: Subquery in WHERE
DROP TABLE IF EXISTS ex1_employees;
CREATE TABLE ex1_employees (
  emp_id SERIAL PRIMARY KEY,
  name TEXT,
  salary NUMERIC(10,2),
  department TEXT
);

INSERT INTO ex1_employees (name, salary, department) VALUES
(&#8217;Alice&#8217;, 60000, &#8216;HR&#8217;),
(&#8217;Bob&#8217;, 45000, &#8216;HR&#8217;),
(&#8217;Charlie&#8217;, 70000, &#8216;Engineering&#8217;),
(&#8217;David&#8217;, 80000, &#8216;Engineering&#8217;),
(&#8217;Ella&#8217;, 50000, &#8216;Marketing&#8217;);

-- Find employees who earn more than the average salary
SELECT name, salary
FROM ex1_employees
WHERE salary &gt; (
  SELECT AVG(salary) FROM ex1_employees
);
</code></code></pre><p><strong>Plain Explanation:</strong><br>The inner query (<code>SELECT AVG(salary) ...</code>) calculates one number (the average salary).<br>The outer query then picks rows where <code>salary &gt;</code> that number.</p><div><hr></div><h2>&#129513; 3. Subquery in <code>FROM</code> (Treat a subquery as a temporary table)</h2><pre><code><code>-- EX2: Subquery in FROM
DROP TABLE IF EXISTS ex2_sales;
CREATE TABLE ex2_sales (
  sale_id SERIAL PRIMARY KEY,
  category TEXT,
  amount NUMERIC(8,2)
);

INSERT INTO ex2_sales (category, amount) VALUES
(&#8217;Stationery&#8217;, 120.00),
(&#8217;Stationery&#8217;, 80.00),
(&#8217;Beverage&#8217;, 200.00),
(&#8217;Beverage&#8217;, 300.00),
(&#8217;Appliance&#8217;, 600.00);

-- Step 1: create a subquery to get total per category
-- Step 2: wrap it in another query to calculate percentage share
SELECT
  category,
  total,
  ROUND(100.0 * total / (SELECT SUM(total) FROM (
    SELECT category, SUM(amount) AS total
    FROM ex2_sales
    GROUP BY category
  ) t), 2) AS percent_share
FROM (
  SELECT category, SUM(amount) AS total
  FROM ex2_sales
  GROUP BY category
) t
ORDER BY percent_share DESC;
</code></code></pre><p><strong>Layman&#8217;s Explanation:</strong><br>We first group sales by category inside the inner query.<br>Then, the outer query uses that as a virtual table (<code>t</code>) to calculate each category&#8217;s percentage contribution.<br>This &#8220;query-inside-FROM&#8221; pattern is common for analytics reports.</p><div><hr></div><h2>&#129513; 4. Subquery in <code>SELECT</code> (Compute an extra column)</h2><pre><code><code>-- EX3: Subquery in SELECT
DROP TABLE IF EXISTS ex3_orders;
CREATE TABLE ex3_orders (
  order_id SERIAL PRIMARY KEY,
  customer_id INTEGER,
  amount NUMERIC(8,2)
);

DROP TABLE IF EXISTS ex3_customers;
CREATE TABLE ex3_customers (
  customer_id SERIAL PRIMARY KEY,
  name TEXT
);

INSERT INTO ex3_customers (name) VALUES
(&#8217;Anita&#8217;), (&#8217;Ben&#8217;), (&#8217;Carmen&#8217;);

INSERT INTO ex3_orders (customer_id, amount) VALUES
(1, 50.00), (1, 30.00), (2, 100.00);

-- Add a column: total spent by that customer
SELECT
  c.customer_id,
  c.name,
  (SELECT SUM(amount) FROM ex3_orders o WHERE o.customer_id = c.customer_id) AS total_spent
FROM ex3_customers c;
</code></code></pre><p><strong>Explanation:</strong><br>For each customer, we run a mini-query (subquery) that sums their orders.<br>It&#8217;s like a lookup performed row by row.</p><div><hr></div><h2>&#129513; 5. Correlated Subquery (depends on outer query)</h2><pre><code><code>-- EX4: Correlated subquery example
DROP TABLE IF EXISTS ex4_products;
CREATE TABLE ex4_products (
  product_id SERIAL PRIMARY KEY,
  name TEXT,
  category TEXT,
  price NUMERIC(8,2)
);

INSERT INTO ex4_products (name, category, price) VALUES
(&#8217;Espresso&#8217;, &#8216;Beverage&#8217;, 5.00),
(&#8217;Latte&#8217;, &#8216;Beverage&#8217;, 7.50),
(&#8217;Green Tea&#8217;, &#8216;Beverage&#8217;, 4.00),
(&#8217;Notebook&#8217;, &#8216;Stationery&#8217;, 3.00),
(&#8217;Pen&#8217;, &#8216;Stationery&#8217;, 2.00),
(&#8217;Marker&#8217;, &#8216;Stationery&#8217;, 4.50);

-- Find products that cost more than the average in their category
SELECT name, category, price
FROM ex4_products p1
WHERE price &gt; (
  SELECT AVG(price)
  FROM ex4_products p2
  WHERE p2.category = p1.category
);
</code></code></pre><p><strong>Plain Explanation:</strong><br>The inner query (<code>p2</code>) runs <strong>once for each row</strong> in the outer query (<code>p1</code>).<br>It compares the product&#8217;s price with the <strong>average price of products in the same category</strong>.</p><p>This is the essence of a <strong>correlated subquery</strong> &#8212; the inner query <em>depends</em> on the outer query.</p><div><hr></div><h2>&#129513; 6. <code>EXISTS</code> vs <code>IN</code></h2><pre><code><code>-- EX5: EXISTS vs IN
DROP TABLE IF EXISTS ex5_users;
DROP TABLE IF EXISTS ex5_orders;

CREATE TABLE ex5_users (
  user_id SERIAL PRIMARY KEY,
  name TEXT
);

CREATE TABLE ex5_orders (
  order_id SERIAL PRIMARY KEY,
  user_id INTEGER,
  total NUMERIC(8,2)
);

INSERT INTO ex5_users (name) VALUES (&#8217;Aisha&#8217;), (&#8217;Ben&#8217;), (&#8217;Celine&#8217;), (&#8217;Dinesh&#8217;);
INSERT INTO ex5_orders (user_id, total) VALUES (1,50),(1,25),(3,100);

-- Using IN
SELECT name
FROM ex5_users
WHERE user_id IN (SELECT user_id FROM ex5_orders);

-- Using EXISTS
SELECT u.name
FROM ex5_users u
WHERE EXISTS (
  SELECT 1 FROM ex5_orders o WHERE o.user_id = u.user_id
);
</code></code></pre><p><strong>Layman&#8217;s Explanation:</strong><br>Both <code>IN</code> and <code>EXISTS</code> check for presence of related rows.</p><ul><li><p><code>IN</code> compares a value against a list (from the inner query).</p></li><li><p><code>EXISTS</code> checks &#8220;does at least one row exist?&#8221; &#8212; faster when matching large datasets.</p></li></ul><div><hr></div><h2>&#129513; 7. Common Table Expressions (CTEs) &#8212; <code>WITH</code> clause</h2><p>CTEs are like <strong>temporary tables</strong> you define at the top of a query.<br>They make your SQL easier to read and debug.</p><p>Think of it as &#8220;naming a subquery&#8221; before using it.</p><pre><code><code>-- EX6: Using CTE to simplify query
DROP TABLE IF EXISTS ex6_sales;
CREATE TABLE ex6_sales (
  id SERIAL PRIMARY KEY,
  category TEXT,
  amount NUMERIC(8,2)
);

INSERT INTO ex6_sales (category, amount) VALUES
(&#8217;Beverage&#8217;, 100),
(&#8217;Beverage&#8217;, 50),
(&#8217;Stationery&#8217;, 200),
(&#8217;Stationery&#8217;, 100),
(&#8217;Appliance&#8217;, 400);

-- Step 1: total per category
-- Step 2: calculate share using CTE
WITH category_totals AS (
  SELECT category, SUM(amount) AS total
  FROM ex6_sales
  GROUP BY category
),
grand_total AS (
  SELECT SUM(total) AS total_sum FROM category_totals
)
SELECT
  c.category,
  c.total,
  ROUND(100.0 * c.total / g.total_sum, 2) AS percent_share
FROM category_totals c, grand_total g
ORDER BY percent_share DESC;
</code></code></pre><p><strong>Explanation:</strong><br>We broke the problem into 2 logical pieces:</p><ol><li><p><code>category_totals</code> &#8594; group totals</p></li><li><p><code>grand_total</code> &#8594; total of all<br>Then we joined them to compute % share.</p></li></ol><div><hr></div><h2>&#129513; 8. Multiple CTEs chained together (step-by-step data pipeline)</h2><pre><code><code>-- EX7: Multi-step CTEs
DROP TABLE IF EXISTS ex7_logs;
CREATE TABLE ex7_logs (
  user_id INTEGER,
  event TEXT,
  amount NUMERIC(8,2),
  event_ts TIMESTAMP
);

INSERT INTO ex7_logs (user_id, event, amount, event_ts) VALUES
(1,&#8217;view&#8217;,NULL,&#8217;2025-01-01&#8217;),
(1,&#8217;purchase&#8217;,20,&#8217;2025-01-02&#8217;),
(2,&#8217;purchase&#8217;,50,&#8217;2025-01-03&#8217;),
(2,&#8217;refund&#8217;,-50,&#8217;2025-01-04&#8217;),
(3,&#8217;view&#8217;,NULL,&#8217;2025-01-05&#8217;),
(3,&#8217;purchase&#8217;,10,&#8217;2025-01-06&#8217;);

WITH purchases AS (
  SELECT user_id, SUM(amount) AS total_spent
  FROM ex7_logs
  WHERE event = &#8216;purchase&#8217;
  GROUP BY user_id
),
refunds AS (
  SELECT user_id, ABS(SUM(amount)) AS total_refunds
  FROM ex7_logs
  WHERE event = &#8216;refund&#8217;
  GROUP BY user_id
),
combined AS (
  SELECT p.user_id, p.total_spent, COALESCE(r.total_refunds,0) AS total_refunds
  FROM purchases p
  LEFT JOIN refunds r USING(user_id)
)
SELECT *,
       (total_spent - total_refunds) AS net_spent
FROM combined
ORDER BY user_id;
</code></code></pre><p><strong>Plain Explanation:</strong><br>This builds a mini data pipeline:</p><ol><li><p><code>purchases</code> step collects all purchase totals.</p></li><li><p><code>refunds</code> step collects all refunds.</p></li><li><p><code>combined</code> step merges them and computes the final metric.</p></li></ol><p>This style is widely used in <strong>AI feature engineering pipelines</strong>.</p><div><hr></div><h2>&#129513; 9. Recursive CTE (optional advanced)</h2><pre><code><code>-- EX8: Recursive CTE for hierarchy
DROP TABLE IF EXISTS ex8_org;
CREATE TABLE ex8_org (
  emp_id SERIAL PRIMARY KEY,
  name TEXT,
  manager_id INTEGER
);

INSERT INTO ex8_org (name, manager_id) VALUES
(&#8217;CEO&#8217;, NULL),
(&#8217;Alice&#8217;, 1),
(&#8217;Bob&#8217;, 1),
(&#8217;Charlie&#8217;, 2),
(&#8217;Diana&#8217;, 2);

-- Recursive CTE to show org hierarchy
WITH RECURSIVE org_cte AS (
  SELECT emp_id, name, manager_id, 1 AS level
  FROM ex8_org
  WHERE manager_id IS NULL
  UNION ALL
  SELECT e.emp_id, e.name, e.manager_id, c.level + 1
  FROM ex8_org e
  JOIN org_cte c ON e.manager_id = c.emp_id
)
SELECT * FROM org_cte ORDER BY level, emp_id;
</code></code></pre><p><strong>Explanation:</strong><br>Recursive CTEs call themselves to walk through hierarchies (e.g., manager &#8594; subordinate &#8594; next level).<br>They&#8217;re like a SQL version of recursion in Python.</p><div><hr></div><h2>&#129513; 10. When to Use What</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!q1np!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd102910d-81bb-413b-baa9-e80e82d72856_568x317.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!q1np!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd102910d-81bb-413b-baa9-e80e82d72856_568x317.png 424w, https://substackcdn.com/image/fetch/$s_!q1np!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd102910d-81bb-413b-baa9-e80e82d72856_568x317.png 848w, https://substackcdn.com/image/fetch/$s_!q1np!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd102910d-81bb-413b-baa9-e80e82d72856_568x317.png 1272w, https://substackcdn.com/image/fetch/$s_!q1np!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd102910d-81bb-413b-baa9-e80e82d72856_568x317.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!q1np!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd102910d-81bb-413b-baa9-e80e82d72856_568x317.png" width="568" height="317" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d102910d-81bb-413b-baa9-e80e82d72856_568x317.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:317,&quot;width&quot;:568,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:23710,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd102910d-81bb-413b-baa9-e80e82d72856_568x317.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!q1np!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd102910d-81bb-413b-baa9-e80e82d72856_568x317.png 424w, https://substackcdn.com/image/fetch/$s_!q1np!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd102910d-81bb-413b-baa9-e80e82d72856_568x317.png 848w, https://substackcdn.com/image/fetch/$s_!q1np!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd102910d-81bb-413b-baa9-e80e82d72856_568x317.png 1272w, https://substackcdn.com/image/fetch/$s_!q1np!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd102910d-81bb-413b-baa9-e80e82d72856_568x317.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129513; 10 Practice Exercises</h2><p>Try these on your own (I can give full runnable answers if you want next):</p><ol><li><p>Create an <code>employees</code> table (name, dept, salary). Find employees earning above the average salary using a subquery.</p></li><li><p>Create a <code>sales</code> table. Show each category and its % of total revenue using a subquery in <code>FROM</code>.</p></li><li><p>Using a <code>students</code> and <code>marks</code> table, find students who scored above the class average.</p></li><li><p>Build a <code>products</code> table and use a correlated subquery to find products priced above their category&#8217;s average.</p></li><li><p>Create <code>customers</code> and <code>orders</code> tables. Use <code>IN</code> and <code>EXISTS</code> to find customers who placed orders.</p></li><li><p>Use a CTE to first compute total sales per region, then compute each region&#8217;s share of total sales.</p></li><li><p>Chain multiple CTEs: step 1 = purchases, step 2 = refunds, step 3 = net revenue.</p></li><li><p>Use a CTE to find top 3 customers by total spend.</p></li><li><p>Create a small organization table and write a <strong>recursive CTE</strong> to display the reporting hierarchy.</p></li><li><p>Create a CTE that filters out customers with zero orders, then use that result to find average spending among active customers.</p></li></ol><div><hr></div><h1>Chapter 5 &#8212; Window Functions</h1><p><em>(Plain-English guide + detailed examples with data + 10 exercises)</em></p><p>Welcome back, Bavi &#128079; &#8212; this is one of the <strong>most powerful and useful SQL chapters</strong>, especially for <strong>AI, analytics, and time-series work</strong>.</p><p>Window functions let you perform <strong>calculations across rows &#8212; without grouping them together</strong>.<br>They are the secret behind <strong>rankings, running totals, moving averages, time-based comparisons</strong>, and <strong>feature engineering</strong> for machine learning models.</p><div><hr></div><h2>&#129504; What You&#8217;ll Learn in This Chapter</h2><p>By the end of this chapter, you&#8217;ll be able to:</p><ul><li><p>Understand what <strong>window functions</strong> are and how they differ from normal aggregates.</p></li><li><p>Use <code>OVER()</code> and <code>PARTITION BY</code>.</p></li><li><p>Rank rows using <code>ROW_NUMBER()</code>, <code>RANK()</code>, and <code>DENSE_RANK()</code>.</p></li><li><p>Compare current vs previous row using <code>LAG()</code> and <code>LEAD()</code>.</p></li><li><p>Compute running totals and moving averages.</p></li><li><p>Use frame clauses like <code>ROWS BETWEEN &#8230;</code> for rolling calculations.</p></li></ul><p>Every example below is <strong>fully runnable</strong> (it drops and creates its own tables).<br>You can copy each one directly into pgAdmin or DBeaver and it&#8217;ll just work &#9989;</p><div><hr></div><h2>&#128161; 1. What Are Window Functions (In Simple Terms)</h2><p>A <strong>window function</strong> looks at a &#8220;window&#8221; of rows &#8212; which can be:</p><ul><li><p>all rows,</p></li><li><p>rows in the same group (partition),</p></li><li><p>or a subset around the current row (like &#8220;previous 2 and next 2&#8221;).</p></li></ul><p>It <strong>does not collapse rows like GROUP BY does</strong>.<br>You still see every row, but you can add running totals, ranks, or differences as extra columns.</p><div><hr></div><h2>&#128313; 2. Basic Window Function Syntax</h2><pre><code><code>function_name(expression) OVER (
    PARTITION BY column
    ORDER BY column
    ROWS BETWEEN ... AND ...
)
</code></code></pre><p>Parts:</p><ul><li><p><code>PARTITION BY</code>: divide rows into groups (like GROUP BY but rows remain visible)</p></li><li><p><code>ORDER BY</code>: defines order inside each group</p></li><li><p><code>ROWS BETWEEN</code>: defines the window range</p></li></ul><div><hr></div><h2>&#129513; Example 1 &#8212; Compare Window vs Aggregate</h2><pre><code><code>-- EX1: Window vs Group Aggregate
DROP TABLE IF EXISTS ex1_sales;
CREATE TABLE ex1_sales (
  region TEXT,
  rep TEXT,
  sales NUMERIC(8,2)
);

INSERT INTO ex1_sales (region, rep, sales) VALUES
(&#8217;East&#8217;,&#8217;Alice&#8217;,100),
(&#8217;East&#8217;,&#8217;Bob&#8217;,150),
(&#8217;West&#8217;,&#8217;Cathy&#8217;,200),
(&#8217;West&#8217;,&#8217;Dan&#8217;,300),
(&#8217;West&#8217;,&#8217;Ella&#8217;,100);

-- Normal aggregate (collapses rows)
SELECT region, SUM(sales) AS total_sales
FROM ex1_sales
GROUP BY region;

-- Window aggregate (keeps all rows)
SELECT
  region,
  rep,
  sales,
  SUM(sales) OVER (PARTITION BY region) AS region_total
FROM ex1_sales
ORDER BY region, rep;
</code></code></pre><p><strong>Plain Explanation:</strong></p><ul><li><p>The <code>GROUP BY</code> query <em>loses individual reps</em> &#8212; it only shows totals.</p></li><li><p>The <code>OVER(PARTITION BY region)</code> query <em>keeps each rep</em> and adds the total for their region beside them.</p></li></ul><div><hr></div><h2>&#129513; Example 2 &#8212; ROW_NUMBER(), RANK(), DENSE_RANK()</h2><pre><code><code>-- EX2: Ranking examples
DROP TABLE IF EXISTS ex2_scores;
CREATE TABLE ex2_scores (
  student TEXT,
  subject TEXT,
  marks INTEGER
);

INSERT INTO ex2_scores (student, subject, marks) VALUES
(&#8217;Anita&#8217;,&#8217;Math&#8217;,90),
(&#8217;Ben&#8217;,&#8217;Math&#8217;,85),
(&#8217;Carmen&#8217;,&#8217;Math&#8217;,85),
(&#8217;David&#8217;,&#8217;Math&#8217;,70),
(&#8217;Ella&#8217;,&#8217;Math&#8217;,95);

-- Ranking functions
SELECT
  student,
  subject,
  marks,
  ROW_NUMBER() OVER (PARTITION BY subject ORDER BY marks DESC) AS row_num,
  RANK() OVER (PARTITION BY subject ORDER BY marks DESC) AS rank_value,
  DENSE_RANK() OVER (PARTITION BY subject ORDER BY marks DESC) AS dense_rank_value
FROM ex2_scores
ORDER BY marks DESC;
</code></code></pre><p><strong>Layman&#8217;s Explanation:</strong></p><ul><li><p><code>ROW_NUMBER()</code> gives unique increasing numbers even for ties.</p></li><li><p><code>RANK()</code> leaves gaps after ties (1, 2, 2, 4).</p></li><li><p><code>DENSE_RANK()</code> doesn&#8217;t leave gaps (1, 2, 2, 3).<br>These are essential for <strong>leaderboards, ranking models, or finding top-N per category.</strong></p></li></ul><div><hr></div><h2>&#129513; Example 3 &#8212; LAG() and LEAD() for Time-Series Comparison</h2><pre><code><code>-- EX3: LAG and LEAD
DROP TABLE IF EXISTS ex3_stock;
CREATE TABLE ex3_stock (
  stock_date DATE,
  symbol TEXT,
  price NUMERIC(8,2)
);

INSERT INTO ex3_stock (stock_date, symbol, price) VALUES
(&#8217;2025-01-01&#8217;,&#8217;AAPL&#8217;,100),
(&#8217;2025-01-02&#8217;,&#8217;AAPL&#8217;,105),
(&#8217;2025-01-03&#8217;,&#8217;AAPL&#8217;,102),
(&#8217;2025-01-04&#8217;,&#8217;AAPL&#8217;,110),
(&#8217;2025-01-05&#8217;,&#8217;AAPL&#8217;,108);

SELECT
  stock_date,
  symbol,
  price,
  LAG(price) OVER (PARTITION BY symbol ORDER BY stock_date) AS prev_price,
  LEAD(price) OVER (PARTITION BY symbol ORDER BY stock_date) AS next_price,
  price - LAG(price) OVER (PARTITION BY symbol ORDER BY stock_date) AS daily_change
FROM ex3_stock
ORDER BY stock_date;
</code></code></pre><p><strong>Plain Explanation:</strong></p><ul><li><p><code>LAG()</code> gives you the previous row&#8217;s value.</p></li><li><p><code>LEAD()</code> gives the next row&#8217;s value.</p></li><li><p>You can calculate <code>price - LAG(price)</code> to find daily changes.<br>This is perfect for <strong>AI time-series features</strong> like &#8220;change from previous day&#8221;.</p></li></ul><div><hr></div><h2>&#129513; Example 4 &#8212; Running Total &amp; Cumulative Sum</h2><pre><code><code>-- EX4: Running total per customer
DROP TABLE IF EXISTS ex4_orders;
CREATE TABLE ex4_orders (
  order_id SERIAL PRIMARY KEY,
  customer TEXT,
  order_date DATE,
  amount NUMERIC(8,2)
);

INSERT INTO ex4_orders (customer, order_date, amount) VALUES
(&#8217;Asha&#8217;,&#8217;2025-01-01&#8217;,100),
(&#8217;Asha&#8217;,&#8217;2025-01-03&#8217;,50),
(&#8217;Asha&#8217;,&#8217;2025-01-05&#8217;,150),
(&#8217;Ben&#8217;,&#8217;2025-01-02&#8217;,200),
(&#8217;Ben&#8217;,&#8217;2025-01-04&#8217;,100);

SELECT
  customer,
  order_date,
  amount,
  SUM(amount) OVER (PARTITION BY customer ORDER BY order_date) AS running_total
FROM ex4_orders
ORDER BY customer, order_date;
</code></code></pre><p><strong>Explanation:</strong><br><code>SUM(...) OVER (PARTITION BY customer ORDER BY order_date)</code> keeps a <strong>running total</strong> as you move through time.<br>It doesn&#8217;t reset the rows &#8212; just adds a new column.</p><div><hr></div><h2>&#129513; Example 5 &#8212; Moving Average (Rolling Window)</h2><pre><code><code>-- EX5: Moving average (3-day window)
DROP TABLE IF EXISTS ex5_temps;
CREATE TABLE ex5_temps (
  reading_date DATE,
  city TEXT,
  temp_c NUMERIC(5,2)
);

INSERT INTO ex5_temps (reading_date, city, temp_c) VALUES
(&#8217;2025-01-01&#8217;,&#8217;Paris&#8217;,10),
(&#8217;2025-01-02&#8217;,&#8217;Paris&#8217;,12),
(&#8217;2025-01-03&#8217;,&#8217;Paris&#8217;,14),
(&#8217;2025-01-04&#8217;,&#8217;Paris&#8217;,16),
(&#8217;2025-01-05&#8217;,&#8217;Paris&#8217;,18),
(&#8217;2025-01-06&#8217;,&#8217;Paris&#8217;,20);

SELECT
  reading_date,
  city,
  temp_c,
  ROUND(AVG(temp_c) OVER (
    PARTITION BY city
    ORDER BY reading_date
    ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
  ),2) AS moving_avg_3days
FROM ex5_temps
ORDER BY reading_date;
</code></code></pre><p><strong>Layman&#8217;s Explanation:</strong><br>This keeps a moving average of the last 3 days (<code>2 PRECEDING + current</code>).<br>It&#8217;s essential for <strong>trend detection and smoothing</strong> in time-series analysis.</p><div><hr></div><h2>&#129513; Example 6 &#8212; Percent Rank and Cumulative Distribution</h2><pre><code><code>-- EX6: Percent rank and cumulative distribution
DROP TABLE IF EXISTS ex6_scores;
CREATE TABLE ex6_scores (
  student TEXT,
  marks INTEGER
);

INSERT INTO ex6_scores (student, marks) VALUES
(&#8217;A&#8217;,90),(&#8217;B&#8217;,80),(&#8217;C&#8217;,70),(&#8217;D&#8217;,60),(&#8217;E&#8217;,50);

SELECT
  student,
  marks,
  PERCENT_RANK() OVER (ORDER BY marks) AS percent_rank,
  CUME_DIST() OVER (ORDER BY marks) AS cumulative_distribution
FROM ex6_scores
ORDER BY marks;
</code></code></pre><p><strong>Plain Explanation:</strong></p><ul><li><p><code>PERCENT_RANK()</code> gives rank as a <strong>percentage</strong> of total rows.</p></li><li><p><code>CUME_DIST()</code> shows the proportion of rows <strong>less than or equal to</strong> current row.<br>These are great for <strong>normalizing scores</strong> or creating percentile-based features in ML.</p></li></ul><div><hr></div><h2>&#129513; Example 7 &#8212; Combine LAG + Window for Change Detection</h2><pre><code><code>-- EX7: Detect change events
DROP TABLE IF EXISTS ex7_device;
CREATE TABLE ex7_device (
  device_id TEXT,
  reading_ts TIMESTAMP,
  status TEXT
);

INSERT INTO ex7_device (device_id, reading_ts, status) VALUES
(&#8217;D1&#8217;,&#8217;2025-01-01 10:00&#8217;,&#8217;ON&#8217;),
(&#8217;D1&#8217;,&#8217;2025-01-01 11:00&#8217;,&#8217;ON&#8217;),
(&#8217;D1&#8217;,&#8217;2025-01-01 12:00&#8217;,&#8217;OFF&#8217;),
(&#8217;D1&#8217;,&#8217;2025-01-01 13:00&#8217;,&#8217;OFF&#8217;),
(&#8217;D1&#8217;,&#8217;2025-01-01 14:00&#8217;,&#8217;ON&#8217;);

SELECT
  device_id,
  reading_ts,
  status,
  LAG(status) OVER (PARTITION BY device_id ORDER BY reading_ts) AS prev_status,
  CASE WHEN status &lt;&gt; LAG(status) OVER (PARTITION BY device_id ORDER BY reading_ts)
       THEN &#8216;CHANGED&#8217;
       ELSE &#8216;SAME&#8217;
  END AS change_flag
FROM ex7_device
ORDER BY reading_ts;
</code></code></pre><p><strong>Layman&#8217;s Explanation:</strong><br>We compare the current status with the previous one using <code>LAG()</code>.<br>This helps detect <strong>status changes</strong>, <strong>anomalies</strong>, or <strong>events</strong> &#8212; very common in IoT, logs, and monitoring datasets.</p><div><hr></div><h2>&#129513; When to Use Window Functions in AI/ML</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Bxai!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d2f8792-ed70-438b-b9a7-07dd45f63306_624x312.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Bxai!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d2f8792-ed70-438b-b9a7-07dd45f63306_624x312.png 424w, https://substackcdn.com/image/fetch/$s_!Bxai!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d2f8792-ed70-438b-b9a7-07dd45f63306_624x312.png 848w, https://substackcdn.com/image/fetch/$s_!Bxai!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d2f8792-ed70-438b-b9a7-07dd45f63306_624x312.png 1272w, https://substackcdn.com/image/fetch/$s_!Bxai!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d2f8792-ed70-438b-b9a7-07dd45f63306_624x312.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Bxai!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d2f8792-ed70-438b-b9a7-07dd45f63306_624x312.png" width="624" height="312" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0d2f8792-ed70-438b-b9a7-07dd45f63306_624x312.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:312,&quot;width&quot;:624,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:24283,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d2f8792-ed70-438b-b9a7-07dd45f63306_624x312.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Bxai!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d2f8792-ed70-438b-b9a7-07dd45f63306_624x312.png 424w, https://substackcdn.com/image/fetch/$s_!Bxai!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d2f8792-ed70-438b-b9a7-07dd45f63306_624x312.png 848w, https://substackcdn.com/image/fetch/$s_!Bxai!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d2f8792-ed70-438b-b9a7-07dd45f63306_624x312.png 1272w, https://substackcdn.com/image/fetch/$s_!Bxai!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d2f8792-ed70-438b-b9a7-07dd45f63306_624x312.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129513; 10 Practice Exercises</h2><p>Try writing these queries in PostgreSQL. (I can give full runnable solutions if you want next.)</p><ol><li><p>Create a <code>sales(region, rep, sales_amount)</code> table. Show each rep&#8217;s sales and total sales of their region using a window function.</p></li><li><p>Create <code>students(name, score)</code> and rank them using <code>ROW_NUMBER()</code>, <code>RANK()</code>, and <code>DENSE_RANK()</code>.</p></li><li><p>Create <code>orders(customer, order_date, amount)</code> and compute each customer&#8217;s running total of spending.</p></li><li><p>Create a <code>temperature(city, reading_date, temp)</code> table and compute 7-day moving average temperature.</p></li><li><p>Using <code>LAG()</code>, find daily price changes for a <code>stock(symbol, date, price)</code> table.</p></li><li><p>Using <code>LEAD()</code>, predict next day&#8217;s value for each row in a time-series table.</p></li><li><p>Create <code>scores(student, subject, marks)</code> and find percentile ranks using <code>PERCENT_RANK()</code>.</p></li><li><p>Using <code>LAG()</code>, detect when an IoT device changes its status (ON &#8594; OFF or OFF &#8594; ON).</p></li><li><p>Combine <code>RANK()</code> + <code>PARTITION BY region</code> to find top 2 sales reps per region.</p></li><li><p>Combine multiple window functions: for each customer, show total spent, running total, and percentage of total revenue.</p></li></ol><div><hr></div><h1>Chapter 6 &#8212; Data Manipulation (INSERT &#183; UPDATE &#183; DELETE &#183; MERGE &#183; Transactions)</h1><p><em>(Plain-English explanations + fully runnable SQL + 10 hands-on exercises)</em></p><div><hr></div><h2>&#127919; Why this matters</h2><p>Up to now you&#8217;ve learned how to <strong>read and analyze data</strong>.<br>This chapter teaches you how to <strong>change it safely</strong>: add new rows, fix mistakes, remove bad data, and merge new information &#8212; the day-to-day skills of any data engineer or AI-pipeline maintainer.</p><div><hr></div><h2>&#129521; Core ideas in very simple words</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Z7yO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97f2dde-3791-4fe1-9641-fbf87975aa57_754x293.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Z7yO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97f2dde-3791-4fe1-9641-fbf87975aa57_754x293.png 424w, https://substackcdn.com/image/fetch/$s_!Z7yO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97f2dde-3791-4fe1-9641-fbf87975aa57_754x293.png 848w, https://substackcdn.com/image/fetch/$s_!Z7yO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97f2dde-3791-4fe1-9641-fbf87975aa57_754x293.png 1272w, https://substackcdn.com/image/fetch/$s_!Z7yO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97f2dde-3791-4fe1-9641-fbf87975aa57_754x293.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Z7yO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97f2dde-3791-4fe1-9641-fbf87975aa57_754x293.png" width="754" height="293" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b97f2dde-3791-4fe1-9641-fbf87975aa57_754x293.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:293,&quot;width&quot;:754,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:23737,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97f2dde-3791-4fe1-9641-fbf87975aa57_754x293.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Z7yO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97f2dde-3791-4fe1-9641-fbf87975aa57_754x293.png 424w, https://substackcdn.com/image/fetch/$s_!Z7yO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97f2dde-3791-4fe1-9641-fbf87975aa57_754x293.png 848w, https://substackcdn.com/image/fetch/$s_!Z7yO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97f2dde-3791-4fe1-9641-fbf87975aa57_754x293.png 1272w, https://substackcdn.com/image/fetch/$s_!Z7yO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb97f2dde-3791-4fe1-9641-fbf87975aa57_754x293.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129513; Example 1 &#8212; INSERT (single &amp; multiple rows)</h2><pre><code><code>-- EX1: INSERT rows
DROP TABLE IF EXISTS ex1_products;
CREATE TABLE ex1_products (
  product_id SERIAL PRIMARY KEY,
  name TEXT,
  price NUMERIC(8,2),
  category TEXT
);

-- one row
INSERT INTO ex1_products (name, price, category)
VALUES (&#8217;Notebook&#8217;, 3.50, &#8216;Stationery&#8217;);

-- multiple rows
INSERT INTO ex1_products (name, price, category) VALUES
(&#8217;Pen&#8217;, 1.00, &#8216;Stationery&#8217;),
(&#8217;Espresso Beans&#8217;, 12.00, &#8216;Beverage&#8217;),
(&#8217;Green Tea&#8217;, 9.00, &#8216;Beverage&#8217;);

SELECT * FROM ex1_products;
</code></code></pre><p><strong>Plain talk:</strong> <code>INSERT</code> adds new sheets to your filing cabinet. You can insert one or many rows in a single shot.</p><div><hr></div><h2>&#129513; Example 2 &#8212; UPDATE (change existing data)</h2><pre><code><code>-- EX2: UPDATE
UPDATE ex1_products
SET price = price * 1.10
WHERE category = &#8216;Beverage&#8217;;  -- raise Beverage prices by 10%

-- give Pen a better name
UPDATE ex1_products
SET name = &#8216;Blue Pen&#8217;
WHERE name = &#8216;Pen&#8217;;

SELECT * FROM ex1_products;
</code></code></pre><p><strong>What&#8217;s happening:</strong> <code>SET</code> tells PostgreSQL which columns to change. <code>WHERE</code> ensures you only change the right rows.<br>&#9888; Without <code>WHERE</code>, you&#8217;d update <em>every</em> row.</p><div><hr></div><h2>&#129513; Example 3 &#8212; DELETE (remove rows)</h2><pre><code><code>-- EX3: DELETE
DELETE FROM ex1_products
WHERE price &lt; 2.00;  -- remove cheap items

SELECT * FROM ex1_products;
</code></code></pre><p><strong>Tip:</strong> Always run a <code>SELECT &#8230; WHERE &#8230;</code> first to preview which rows will be deleted.</p><div><hr></div><h2>&#129513; Example 4 &#8212; RETURNING clause</h2><p>PostgreSQL can return changed rows immediately.</p><pre><code><code>-- EX4: UPDATE &#8230; RETURNING
UPDATE ex1_products
SET price = price + 1.00
WHERE category = &#8216;Stationery&#8217;
RETURNING product_id, name, price;
</code></code></pre><p><strong>Why useful:</strong> When your Python script updates data, <code>RETURNING</code> lets you grab new values without another query.</p><div><hr></div><h2>&#129513; Example 5 &#8212; INSERT &#8230; RETURNING id</h2><pre><code><code>-- EX5: get new ID right after insert
INSERT INTO ex1_products (name, price, category)
VALUES (&#8217;Mug&#8217;, 6.00, &#8216;Merch&#8217;)
RETURNING product_id, name;
</code></code></pre><p>Perfect when you need to insert then use that new ID immediately in another table.</p><div><hr></div><h2>&#129513; Example 6 &#8212; MERGE (UPSERT)</h2><pre><code><code>-- EX6: MERGE (PostgreSQL 15+)
DROP TABLE IF EXISTS ex6_inventory;
CREATE TABLE ex6_inventory (
  sku TEXT PRIMARY KEY,
  stock INT,
  price NUMERIC(8,2)
);

INSERT INTO ex6_inventory VALUES
(&#8217;A1&#8217;,10,5.00),
(&#8217;A2&#8217;,20,7.00);

-- new data to merge
DROP TABLE IF EXISTS ex6_updates;
CREATE TABLE ex6_updates (sku TEXT, stock INT, price NUMERIC(8,2));
INSERT INTO ex6_updates VALUES
(&#8217;A2&#8217;,25,7.50),  -- existing -&gt; update
(&#8217;A3&#8217;,10,6.00);  -- new -&gt; insert

MERGE INTO ex6_inventory AS inv
USING ex6_updates AS upd
ON inv.sku = upd.sku
WHEN MATCHED THEN
  UPDATE SET stock = upd.stock, price = upd.price
WHEN NOT MATCHED THEN
  INSERT (sku, stock, price) VALUES (upd.sku, upd.stock, upd.price);

SELECT * FROM ex6_inventory;
</code></code></pre><p><strong>Plain explanation:</strong><br>If the SKU already exists &#8594; update it.<br>If it&#8217;s new &#8594; insert it.<br>That&#8217;s an <strong>upsert</strong> &#8212; a combo of &#8220;update + insert&#8221;.</p><div><hr></div><h2>&#129513; Example 7 &#8212; Transaction safety (BEGIN / COMMIT / ROLLBACK)</h2><pre><code><code>-- EX7: Transactions
BEGIN;

INSERT INTO ex1_products (name, price, category)
VALUES (&#8217;Temp Product&#8217;, 1.00, &#8216;Test&#8217;);

-- Oops! decide to cancel
ROLLBACK;

-- check: no &#8220;Temp Product&#8221; remains
SELECT * FROM ex1_products;
</code></code></pre><p><strong>Layman&#8217;s view:</strong><br>A transaction is like writing in pencil until you&#8217;re sure.<br><code>BEGIN</code> starts the block.<br><code>COMMIT</code> = keep changes.<br><code>ROLLBACK</code> = erase everything since BEGIN.</p><div><hr></div><h2>&#129513; Example 8 &#8212; COMMIT success path</h2><pre><code><code>BEGIN;
UPDATE ex1_products SET price = price + 0.5 WHERE category=&#8217;Merch&#8217;;
COMMIT;
</code></code></pre><p>Now the price bump stays permanently.</p><div><hr></div><h2>&#129513; Example 9 &#8212; Bulk INSERT using COPY (simulated)</h2><pre><code><code>-- EX9: COPY for bulk load (works in psql or pgAdmin)
-- COPY ex1_products(name,price,category)
-- FROM &#8216;/path/to/file.csv&#8217;
-- DELIMITER &#8216;,&#8217; CSV HEADER;
</code></code></pre><p><strong>Plain note:</strong> For large AI datasets you&#8217;ll load CSVs quickly using <code>COPY</code>; it&#8217;s faster than millions of INSERTs.</p><div><hr></div><h2>&#129513; Example 10 &#8212; DELETE with JOIN (subquery style)</h2><pre><code><code>-- EX10: Delete discontinued items using subquery
DROP TABLE IF EXISTS ex10_products;
DROP TABLE IF EXISTS ex10_discontinued;

CREATE TABLE ex10_products (id SERIAL PRIMARY KEY, name TEXT);
CREATE TABLE ex10_discontinued (name TEXT);

INSERT INTO ex10_products (name) VALUES
(&#8217;Pen&#8217;),(&#8217;Pencil&#8217;),(&#8217;Notebook&#8217;),(&#8217;Marker&#8217;);

INSERT INTO ex10_discontinued (name) VALUES
(&#8217;Pencil&#8217;),(&#8217;Marker&#8217;);

DELETE FROM ex10_products
WHERE name IN (SELECT name FROM ex10_discontinued);

SELECT * FROM ex10_products;
</code></code></pre><p><strong>Why:</strong> Sometimes deletions depend on another table &#8212; subqueries make it easy.</p><div><hr></div><h2>&#9881;&#65039; Quick real-world hints</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!e7YX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6bf6918-4a3c-4d0f-b9a2-7c7e6a42035f_694x274.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!e7YX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6bf6918-4a3c-4d0f-b9a2-7c7e6a42035f_694x274.png 424w, https://substackcdn.com/image/fetch/$s_!e7YX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6bf6918-4a3c-4d0f-b9a2-7c7e6a42035f_694x274.png 848w, https://substackcdn.com/image/fetch/$s_!e7YX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6bf6918-4a3c-4d0f-b9a2-7c7e6a42035f_694x274.png 1272w, https://substackcdn.com/image/fetch/$s_!e7YX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6bf6918-4a3c-4d0f-b9a2-7c7e6a42035f_694x274.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!e7YX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6bf6918-4a3c-4d0f-b9a2-7c7e6a42035f_694x274.png" width="694" height="274" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d6bf6918-4a3c-4d0f-b9a2-7c7e6a42035f_694x274.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:274,&quot;width&quot;:694,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:19393,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6bf6918-4a3c-4d0f-b9a2-7c7e6a42035f_694x274.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!e7YX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6bf6918-4a3c-4d0f-b9a2-7c7e6a42035f_694x274.png 424w, https://substackcdn.com/image/fetch/$s_!e7YX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6bf6918-4a3c-4d0f-b9a2-7c7e6a42035f_694x274.png 848w, https://substackcdn.com/image/fetch/$s_!e7YX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6bf6918-4a3c-4d0f-b9a2-7c7e6a42035f_694x274.png 1272w, https://substackcdn.com/image/fetch/$s_!e7YX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd6bf6918-4a3c-4d0f-b9a2-7c7e6a42035f_694x274.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129513; 10 Practice Exercises</h2><ol><li><p>Create a <code>users</code> table and insert 5 rows. Update one user&#8217;s email, then delete another.</p></li><li><p>Insert 10 rows into a <code>books</code> table in a single <code>INSERT</code> statement.</p></li><li><p>Build an <code>inventory(sku, stock)</code> table; write a MERGE that updates stock if SKU exists else inserts it.</p></li><li><p>Create <code>orders(order_id, amount)</code> and <code>refunds(order_id, amount)</code>; use a transaction to deduct refunds safely.</p></li><li><p>Simulate a mistake: begin a transaction, delete all rows, then ROLLBACK &#8212; verify restoration.</p></li><li><p>Use <code>RETURNING</code> to get the IDs of newly added products.</p></li><li><p>Create <code>customers</code> and <code>addresses</code>; insert a customer, then insert address using the returned ID.</p></li><li><p>Create a <code>students</code> table and bulk-insert sample data (5 rows at once).</p></li><li><p>Write an UPDATE that increases all salaries in the <code>employees</code> table by 5 %.</p></li><li><p>Using <code>DELETE &#8230; WHERE id IN (SELECT &#8230;)</code>, remove inactive users listed in another table.</p></li></ol><div><hr></div><h1>Chapter 7 &#8212; Data Cleaning &amp; Transformation</h1><p><em>(Plain-English + fully runnable PostgreSQL examples + 10 exercises)</em></p><div><hr></div><h2>&#127919; Why this matters</h2><p>In real AI and data science work, <strong>raw data is always messy</strong>.<br>Before it can be used for analysis or model training, you need to <strong>clean, standardize, and transform it</strong> &#8212; fixing spaces, inconsistent cases, dates, duplicates, missing values, and bad formats.</p><p>In PostgreSQL, this is easy once you know <strong>string functions</strong>, <strong>date/time functions</strong>, <strong>type conversions</strong>, and even <strong>pivot/unpivot operations</strong>.</p><p>This chapter shows you <em>exactly how to clean and shape data</em> so your AI scripts or Power BI dashboards work flawlessly.</p><div><hr></div><h2>&#129504; What You&#8217;ll Learn</h2><ul><li><p>Clean text fields (trim, lower, replace, split)</p></li><li><p>Work with dates and times (extract parts, add/subtract days)</p></li><li><p>Convert data types safely</p></li><li><p>Handle NULLs and default values</p></li><li><p>Pivot/unpivot data for analytics</p></li><li><p>Use conditional transforms (<code>CASE WHEN</code>)</p></li></ul><p>Each example is <strong>fully copy-paste runnable</strong> &#8212; each creates its own small tables.</p><div><hr></div><h2>&#129513; Example 1 &#8212; Trimming, Upper/Lower Case, Replacing</h2><pre><code><code>-- EX1: String cleaning basics
DROP TABLE IF EXISTS ex1_customers;
CREATE TABLE ex1_customers (
  id SERIAL PRIMARY KEY,
  raw_name TEXT,
  raw_email TEXT
);

INSERT INTO ex1_customers (raw_name, raw_email) VALUES
(&#8217;   anita  &#8216;, &#8216;Anita@Example.COM  &#8216;),
(&#8217;BEN&#8217;, &#8216;ben@example.com&#8217;),
(&#8217; cArMen &#8216;, &#8216;CARMEN@EXAMPLE.COM&#8217;);

SELECT
  id,
  raw_name,
  TRIM(raw_name) AS name_trimmed,
  INITCAP(TRIM(raw_name)) AS name_clean,      -- Capitalize first letter
  LOWER(TRIM(raw_email)) AS email_clean       -- lowercase all
FROM ex1_customers;
</code></code></pre><p><strong>Plain Explanation:</strong></p><ul><li><p><code>TRIM()</code> removes unwanted spaces.</p></li><li><p><code>INITCAP()</code> makes &#8220;cArMen&#8221; &#8594; &#8220;Carmen&#8221;.</p></li><li><p><code>LOWER()</code> fixes inconsistent email cases.</p></li><li><p>Combining these gives uniform data &#8212; perfect for ML preprocessing or joins.</p></li></ul><div><hr></div><h2>&#129513; Example 2 &#8212; REPLACE, SUBSTRING, CONCAT, and String Splitting</h2><pre><code><code>-- EX2: Replace and extract text
DROP TABLE IF EXISTS ex2_products;
CREATE TABLE ex2_products (
  raw_code TEXT
);

INSERT INTO ex2_products VALUES
(&#8217; SKU-123-RED &#8216;),
(&#8217;SKU-456-BLUE&#8217;),
(&#8217; sku-789-green &#8216;);

SELECT
  TRIM(UPPER(raw_code)) AS code_clean,
  REPLACE(TRIM(UPPER(raw_code)),&#8217;SKU-&#8217;,&#8217;&#8216;) AS code_no_prefix,
  SUBSTRING(raw_code FROM 5 FOR 3) AS part_extract,
  CONCAT(&#8217;Product:&#8217;, TRIM(raw_code)) AS label,
  SPLIT_PART(TRIM(UPPER(raw_code)),&#8217;-&#8217;,3) AS color
FROM ex2_products;
</code></code></pre><p><strong>Plain Explanation:</strong></p><ul><li><p><code>REPLACE()</code> deletes unwanted text.</p></li><li><p><code>SUBSTRING()</code> extracts part of a string.</p></li><li><p><code>CONCAT()</code> glues text together.</p></li><li><p><code>SPLIT_PART()</code> extracts parts separated by a character (like color in code).</p></li></ul><div><hr></div><h2>&#129513; Example 3 &#8212; Handling NULLs: COALESCE &amp; NULLIF</h2><pre><code><code>-- EX3: COALESCE and NULLIF
DROP TABLE IF EXISTS ex3_payments;
CREATE TABLE ex3_payments (
  id SERIAL PRIMARY KEY,
  card_number TEXT,
  backup_card TEXT
);

INSERT INTO ex3_payments (card_number, backup_card) VALUES
(NULL, &#8216;1234-XXXX&#8217;),
(&#8217;9876-YYYY&#8217;, NULL),
(NULL, NULL);

SELECT
  id,
  card_number,
  backup_card,
  COALESCE(card_number, backup_card, &#8216;NO CARD&#8217;) AS chosen_card
FROM ex3_payments;
</code></code></pre><p><strong>Plain Explanation:</strong></p><ul><li><p><code>COALESCE()</code> returns the first non-NULL value.<br>(If both are NULL &#8594; &#8220;NO CARD&#8221;).</p></li><li><p><code>NULLIF(a,b)</code> returns NULL if <code>a=b</code>, useful for removing dummy values like &#8220;N/A&#8221;.</p></li></ul><div><hr></div><h2>&#129513; Example 4 &#8212; Date Cleaning &amp; Extracting</h2><pre><code><code>-- EX4: Working with dates
DROP TABLE IF EXISTS ex4_orders;
CREATE TABLE ex4_orders (
  order_id SERIAL PRIMARY KEY,
  raw_date TEXT
);

INSERT INTO ex4_orders (raw_date) VALUES
(&#8217;2025-03-05&#8217;),
(&#8217; 2025/03/06 &#8216;),
(&#8217;March 07 2025&#8217;);

SELECT
  order_id,
  raw_date,
  TO_DATE(TRIM(raw_date),&#8217;YYYY-MM-DD&#8217;) AS fmt_1,
  TO_DATE(TRIM(raw_date),&#8217;YYYY/MM/DD&#8217;) AS fmt_2,
  TO_DATE(TRIM(raw_date),&#8217;Month DD YYYY&#8217;) AS fmt_3
FROM ex4_orders;

-- Use EXTRACT to get date parts
SELECT
  CURRENT_DATE AS today,
  EXTRACT(YEAR FROM CURRENT_DATE) AS this_year,
  EXTRACT(MONTH FROM CURRENT_DATE) AS month_no,
  EXTRACT(DAY FROM CURRENT_DATE) AS day_no;
</code></code></pre><p><strong>Plain Explanation:</strong></p><ul><li><p><code>TO_DATE(text, format)</code> converts strings into real dates.</p></li><li><p><code>EXTRACT()</code> pulls out parts like year/month/day for grouping or trend analysis.</p></li></ul><div><hr></div><h2>&#129513; Example 5 &#8212; DATE Arithmetic (Add/Subtract days)</h2><pre><code><code>-- EX5: Date math
SELECT
  CURRENT_DATE AS today,
  CURRENT_DATE + INTERVAL &#8216;7 days&#8217; AS plus_7days,
  CURRENT_DATE - INTERVAL &#8216;1 month&#8217; AS last_month,
  AGE(CURRENT_DATE, DATE &#8216;2024-12-31&#8217;) AS diff_age;
</code></code></pre><p><strong>Why important:</strong> For time-based AI features like &#8220;days since signup&#8221; or &#8220;tenure before churn&#8221;.</p><div><hr></div><h2>&#129513; Example 6 &#8212; Type Conversion (CAST and ::)</h2><pre><code><code>-- EX6: Type conversions
DROP TABLE IF EXISTS ex6_conversion;
CREATE TABLE ex6_conversion (
  txt_num TEXT
);

INSERT INTO ex6_conversion VALUES (&#8217;100&#8217;), (&#8217;250.75&#8217;), (&#8217;NaN&#8217;);

SELECT
  txt_num,
  CAST(txt_num AS NUMERIC) AS num_value,
  txt_num::NUMERIC AS short_cast
FROM ex6_conversion
WHERE txt_num ~ &#8216;^[0-9.]+$&#8217;; -- regex to keep numeric-looking rows
</code></code></pre><p><strong>Plain Explanation:</strong><br><code>CAST()</code> or <code>::</code> changes data type &#8212; text to number, date to text, etc.<br>We used regex (<code>~ &#8216;^[0-9.]+$&#8217;</code>) to ignore &#8220;NaN&#8221;.</p><div><hr></div><h2>&#129513; Example 7 &#8212; Conditional Transformation with CASE WHEN</h2><pre><code><code>-- EX7: CASE WHEN cleaning
DROP TABLE IF EXISTS ex7_feedback;
CREATE TABLE ex7_feedback (
  rating INTEGER
);

INSERT INTO ex7_feedback VALUES (5),(4),(3),(2),(1),(NULL);

SELECT
  rating,
  CASE
    WHEN rating &gt;= 4 THEN &#8216;Positive&#8217;
    WHEN rating = 3 THEN &#8216;Neutral&#8217;
    WHEN rating &lt; 3 THEN &#8216;Negative&#8217;
    ELSE &#8216;No Rating&#8217;
  END AS sentiment
FROM ex7_feedback;
</code></code></pre><p><strong>Plain Explanation:</strong><br><code>CASE WHEN</code> gives logic inside SQL &#8212; like <code>if-elif-else</code> in Python.</p><div><hr></div><h2>&#129513; Example 8 &#8212; Pivoting data (rows &#8594; columns)</h2><pre><code><code>-- EX8: Pivot data using crosstab()
CREATE EXTENSION IF NOT EXISTS tablefunc;

DROP TABLE IF EXISTS ex8_sales;
CREATE TABLE ex8_sales (
  region TEXT,
  month TEXT,
  amount NUMERIC(8,2)
);

INSERT INTO ex8_sales VALUES
(&#8217;East&#8217;,&#8217;Jan&#8217;,100),(&#8217;East&#8217;,&#8217;Feb&#8217;,120),(&#8217;West&#8217;,&#8217;Jan&#8217;,150),(&#8217;West&#8217;,&#8217;Feb&#8217;,130);

SELECT * FROM crosstab(
  &#8216;SELECT region, month, amount FROM ex8_sales ORDER BY 1,2&#8217;,
  $$VALUES (&#8217;Jan&#8217;), (&#8217;Feb&#8217;)$$
) AS ct(region TEXT, Jan NUMERIC, Feb NUMERIC);
</code></code></pre><p><strong>Plain Explanation:</strong><br><code>crosstab()</code> rotates rows into columns.<br>Used for quick summaries &#8212; like Excel pivot tables.</p><div><hr></div><h2>&#129513; Example 9 &#8212; Unpivoting data (columns &#8594; rows)</h2><pre><code><code>-- EX9: Unpivot with UNION ALL
DROP TABLE IF EXISTS ex9_quarter_sales;
CREATE TABLE ex9_quarter_sales (
  region TEXT,
  q1 NUMERIC,
  q2 NUMERIC
);

INSERT INTO ex9_quarter_sales VALUES (&#8217;East&#8217;,100,200), (&#8217;West&#8217;,150,180);

SELECT region, &#8216;Q1&#8217; AS quarter, q1 AS sales FROM ex9_quarter_sales
UNION ALL
SELECT region, &#8216;Q2&#8217;, q2 FROM ex9_quarter_sales;
</code></code></pre><p><strong>Plain Explanation:</strong><br><code>UNION ALL</code> stacks columns vertically to normalize data &#8212; great for analytics pipelines.</p><div><hr></div><h2>&#129513; Example 10 &#8212; Combining multiple cleaning operations</h2><pre><code><code>-- EX10: All-in-one cleaning
DROP TABLE IF EXISTS ex10_raw_users;
CREATE TABLE ex10_raw_users (
  id SERIAL,
  full_name TEXT,
  join_date TEXT,
  country TEXT
);

INSERT INTO ex10_raw_users (full_name, join_date, country) VALUES
(&#8217;  alice smith &#8216;, &#8216;2025/01/05 &#8216;, &#8216;usa&#8217;),
(&#8217;BEN &#8216;, &#8216;05-01-2025&#8217;, &#8216;Uk &#8216;),
(&#8217;  carmen de souza&#8217;, &#8216;2025-01-07&#8217;, &#8216; INDIA&#8217;);

SELECT
  id,
  INITCAP(TRIM(full_name)) AS clean_name,
  TO_DATE(TRIM(join_date), &#8216;YYYY/MM/DD&#8217;) 
     FILTER (WHERE join_date LIKE &#8216;2025/%&#8217;) 
     AS join_date1,
  COALESCE(TO_DATE(TRIM(join_date), &#8216;DD-MM-YYYY&#8217;),
           TO_DATE(TRIM(join_date), &#8216;YYYY-MM-DD&#8217;)) AS join_date_fixed,
  UPPER(TRIM(country)) AS country_clean
FROM ex10_raw_users;
</code></code></pre><p><strong>Explanation:</strong><br>We combined trimming, case fixing, date parsing, and null-safe conversions &#8212; exactly what real-world cleaning looks like before AI preprocessing.</p><div><hr></div><h2>&#129513; 10 Practice Exercises</h2><p>Try these in PostgreSQL:</p><ol><li><p>Create a <code>users</code> table with messy names and emails; use <code>TRIM</code>, <code>INITCAP</code>, and <code>LOWER</code> to clean them.</p></li><li><p>Use <code>REPLACE</code> to remove &#8220;SKU-&#8221; prefix from product codes and <code>SPLIT_PART</code> to extract the color name.</p></li><li><p>Use <code>COALESCE</code> to fill NULL phone numbers with a default &#8220;Not Provided&#8221;.</p></li><li><p>Convert a text date column <code>&#8216;2025/03/10&#8217;</code> to a real DATE type using <code>TO_DATE</code>.</p></li><li><p>Extract YEAR and MONTH from a timestamp column using <code>EXTRACT()</code>.</p></li><li><p>Add 30 days to all subscription start dates using <code>INTERVAL &#8216;30 days&#8217;</code>.</p></li><li><p>Use <code>CASE WHEN</code> to classify ratings into &#8220;Good&#8221;, &#8220;Average&#8221;, &#8220;Poor&#8221;.</p></li><li><p>Pivot a small table with sales by month into columns using <code>crosstab()</code>.</p></li><li><p>Unpivot quarterly columns into rows using <code>UNION ALL</code>.</p></li><li><p>Create a combined cleaning query that trims spaces, fixes case, and converts a join_date to DATE type.</p></li></ol><div><hr></div><h1>Chapter 8 &#8212; JSON, Arrays &amp; Advanced Data Types in PostgreSQL</h1><p><em>(Plain-English + fully runnable examples + 10 practice exercises)</em></p><div><hr></div><h2>&#127919; Why this matters</h2><p>In modern AI, ML, and analytics projects, data often comes in <strong>semi-structured formats</strong> &#8212; JSON from APIs, logs from IoT devices, lists of tags or labels, etc.<br>PostgreSQL shines here because it natively understands <strong>JSON</strong>, <strong>arrays</strong>, and <strong>key-value data</strong> &#8212; letting you store, query, and transform complex data without extra tools.</p><p>This chapter will show you how to use these features cleanly and safely.</p><div><hr></div><h2>&#129504; What You&#8217;ll Learn</h2><ul><li><p>What JSON and JSONB are, and when to use them</p></li><li><p>How to insert, query, and update JSON values</p></li><li><p>Access nested JSON keys with &#8594; and &#8594;&gt;</p></li><li><p>Use JSON functions (<code>jsonb_each</code>, <code>jsonb_array_elements</code>, etc.)</p></li><li><p>Store and search arrays (<code>ARRAY[]</code>, <code>unnest()</code>)</p></li><li><p>Use range and enum types for clean data modelling</p></li></ul><p>Every example below is <strong>copy-paste runnable</strong> and self-contained.</p><div><hr></div><h2>&#129513; Example 1 &#8212; Storing and Retrieving JSON</h2><pre><code><code>-- EX1: JSON basics
DROP TABLE IF EXISTS ex1_profiles;
CREATE TABLE ex1_profiles (
  id SERIAL PRIMARY KEY,
  user_info JSONB
);

INSERT INTO ex1_profiles (user_info) VALUES
(&#8217;{&#8221;name&#8221;: &#8220;Alice&#8221;, &#8220;age&#8221;: 28, &#8220;skills&#8221;: [&#8221;Python&#8221;, &#8220;SQL&#8221;, &#8220;ML&#8221;]}&#8217;),
(&#8217;{&#8221;name&#8221;: &#8220;Ben&#8221;, &#8220;age&#8221;: 35, &#8220;skills&#8221;: [&#8221;Java&#8221;, &#8220;DevOps&#8221;]}&#8217;);

-- select entire JSON
SELECT user_info FROM ex1_profiles;

-- extract individual keys
SELECT
  user_info-&gt;&gt;&#8217;name&#8217; AS name,
  user_info-&gt;&gt;&#8217;age&#8217;  AS age,
  user_info-&gt;&#8217;skills&#8217; AS skills_array
FROM ex1_profiles;
</code></code></pre><p><strong>Layman&#8217;s explanation:</strong></p><ul><li><p><code>-&gt;</code> gives a JSON object or array.</p></li><li><p><code>-&gt;&gt;</code> gives plain text.</p></li><li><p>JSONB stores JSON in a binary format for faster search.</p></li></ul><div><hr></div><h2>&#129513; Example 2 &#8212; Filtering JSON fields</h2><pre><code><code>-- EX2: filter by JSON key
SELECT *
FROM ex1_profiles
WHERE (user_info-&gt;&gt;&#8217;age&#8217;)::INT &gt; 30;
</code></code></pre><p><strong>Explanation:</strong> cast the extracted text to integer and filter &#8212; same as any normal column.</p><div><hr></div><h2>&#129513; Example 3 &#8212; Querying inside JSON arrays</h2><pre><code><code>-- EX3: search within skills array
SELECT
  user_info-&gt;&gt;&#8217;name&#8217; AS name,
  user_info-&gt;&#8217;skills&#8217; AS skills
FROM ex1_profiles
WHERE user_info-&gt;&#8217;skills&#8217; @&gt; &#8216;[&#8221;SQL&#8221;]&#8217;::jsonb;
</code></code></pre><p><strong>Explanation:</strong><br><code>@&gt;</code> means &#8220;contains&#8221;.<br>So <code>skills @&gt; [&#8221;SQL&#8221;]</code> finds anyone whose skills include SQL.</p><div><hr></div><h2>&#129513; Example 4 &#8212; Expanding JSON arrays to rows</h2><pre><code><code>-- EX4: jsonb_array_elements()
SELECT
  user_info-&gt;&gt;&#8217;name&#8217; AS name,
  skill.value AS each_skill
FROM ex1_profiles,
     jsonb_array_elements(user_info-&gt;&#8217;skills&#8217;) AS skill;
</code></code></pre><p><strong>Plain talk:</strong><br><code>jsonb_array_elements()</code> unpacks an array so you can treat each element as a row &#8212; perfect for normalizing JSON data.</p><div><hr></div><h2>&#129513; Example 5 &#8212; Updating JSON fields</h2><pre><code><code>-- EX5: update a key inside JSON
UPDATE ex1_profiles
SET user_info = jsonb_set(user_info, &#8216;{city}&#8217;, &#8216;&#8221;Brussels&#8221;&#8217;)
WHERE user_info-&gt;&gt;&#8217;name&#8217; = &#8216;Alice&#8217;;

SELECT user_info FROM ex1_profiles;
</code></code></pre><p><strong>Explanation:</strong><br><code>jsonb_set(target, path, new_value)</code> inserts or replaces a value at a JSON path.<br><code>&#8216;{city}&#8217;</code> means top-level key &#8220;city&#8221;.</p><div><hr></div><h2>&#129513; Example 6 &#8212; Nested JSON structure</h2><pre><code><code>-- EX6: nested JSON example
DROP TABLE IF EXISTS ex6_orders;
CREATE TABLE ex6_orders (data JSONB);

INSERT INTO ex6_orders VALUES
(&#8217;{
   &#8220;order_id&#8221;:101,
   &#8220;customer&#8221;:{&#8221;name&#8221;:&#8221;Asha&#8221;,&#8221;city&#8221;:&#8221;Paris&#8221;},
   &#8220;items&#8221;:[{&#8221;product&#8221;:&#8221;Pen&#8221;,&#8221;qty&#8221;:3},{&#8221;product&#8221;:&#8221;Notebook&#8221;,&#8221;qty&#8221;:2}]
 }&#8217;);

-- access nested keys
SELECT
  data-&gt;&#8217;customer&#8217;-&gt;&gt;&#8217;name&#8217; AS customer_name,
  data-&gt;&#8217;items&#8217;-&gt;0-&gt;&gt;&#8217;product&#8217; AS first_product
FROM ex6_orders;
</code></code></pre><p><strong>Plain Explanation:</strong><br>Use chained <code>-&gt;</code> and <code>-&gt;&gt;</code> to drill down into nested levels.</p><div><hr></div><h2>&#129513; Example 7 &#8212; JSON aggregation</h2><pre><code><code>-- EX7: aggregate to JSON
DROP TABLE IF EXISTS ex7_books;
CREATE TABLE ex7_books (author TEXT, title TEXT);

INSERT INTO ex7_books VALUES
(&#8217;Alice&#8217;,&#8217;Postgres Made Easy&#8217;),
(&#8217;Alice&#8217;,&#8217;Python for Data&#8217;),
(&#8217;Ben&#8217;,&#8217;DevOps 101&#8217;);

SELECT author, jsonb_agg(title) AS books
FROM ex7_books
GROUP BY author;
</code></code></pre><p><strong>Explanation:</strong><br><code>jsonb_agg()</code> gathers rows into a JSON array &#8212; very handy for building API responses.</p><div><hr></div><h2>&#129513; Example 8 &#8212; Arrays in PostgreSQL</h2><pre><code><code>-- EX8: array basics
DROP TABLE IF EXISTS ex8_students;
CREATE TABLE ex8_students (
  name TEXT,
  scores INT[]
);

INSERT INTO ex8_students VALUES
(&#8217;Anita&#8217;, ARRAY[85,90,95]),
(&#8217;Ben&#8217;, ARRAY[70,75,80]);

SELECT
  name,
  scores,
  scores[1] AS first_exam,
  unnest(scores) AS each_score
FROM ex8_students;
</code></code></pre><p><strong>Plain Explanation:</strong></p><ul><li><p>Arrays are declared as <code>type[]</code>.</p></li><li><p>Use <code>[n]</code> to access an element.</p></li><li><p><code>unnest()</code> turns array elements into rows.</p></li></ul><div><hr></div><h2>&#129513; Example 9 &#8212; Searching arrays</h2><pre><code><code>-- EX9: find students who scored 90
SELECT name, scores
FROM ex8_students
WHERE 90 = ANY(scores);

-- who has all scores &gt; 80
SELECT name
FROM ex8_students
WHERE NOT EXISTS (
  SELECT 1 FROM unnest(scores) s WHERE s &lt; 80
);
</code></code></pre><p><strong>Explanation:</strong><br><code>ANY()</code> checks if a value is in the array.<br>You can also unnest to run more complex conditions.</p><div><hr></div><h2>&#129513; Example 10 &#8212; Range and Enum types</h2><pre><code><code>-- EX10: ranges and enums
DROP TABLE IF EXISTS ex10_tasks;
CREATE TYPE task_status AS ENUM (&#8217;todo&#8217;,&#8217;in_progress&#8217;,&#8217;done&#8217;);

CREATE TABLE ex10_tasks (
  id SERIAL,
  title TEXT,
  status task_status,
  active_period DATERANGE
);

INSERT INTO ex10_tasks (title,status,active_period) VALUES
(&#8217;Build API&#8217;,&#8217;in_progress&#8217;,&#8217;[2025-01-01,2025-01-10)&#8217;),
(&#8217;Write Docs&#8217;,&#8217;todo&#8217;,&#8217;[2025-02-01,2025-02-05)&#8217;);

SELECT
  title,
  status,
  LOWER(active_period) AS start_date,
  UPPER(active_period) AS end_date,
  UPPER(active_period) - LOWER(active_period) AS days_span
FROM ex10_tasks;
</code></code></pre><p><strong>Plain Explanation:</strong></p><ul><li><p><code>ENUM</code> keeps only predefined values (great for data consistency).</p></li><li><p><code>DATERANGE</code> stores a start-to-end range.<br><code>LOWER()</code> and <code>UPPER()</code> pull the endpoints.</p></li></ul><div><hr></div><h2>&#129513; 10 Practice Exercises</h2><p>Try these yourself:</p><ol><li><p>Create a <code>profiles</code> table with a JSONB column and store name, age, and city. Extract only names where city=&#8217;Paris&#8217;.</p></li><li><p>From a JSON column containing arrays of skills, unnest all skills into separate rows.</p></li><li><p>Update a JSONB object by adding a new key <code>&#8220;country&#8221;: &#8220;Belgium&#8221;</code>.</p></li><li><p>Create a nested JSON of orders and access the second item&#8217;s product name.</p></li><li><p>Use <code>jsonb_agg()</code> to group employee names by department.</p></li><li><p>Build a <code>students(name, grades int[])</code> table and find who has any score below 60.</p></li><li><p>Use <code>unnest()</code> to list all scores for each student.</p></li><li><p>Create an ENUM type <code>mood (&#8217;happy&#8217;,&#8217;neutral&#8217;,&#8217;sad&#8217;)</code> and insert sample data.</p></li><li><p>Create a <code>daterange</code> column for a project timeline; show duration using <code>UPPER() - LOWER()</code>.</p></li><li><p>Combine JSON and array: store user profile JSON with a list of preferred languages and query users who include &#8216;Python&#8217;.</p></li></ol><div><hr></div><h1>Chapter 9 &#8212; Performance &amp; Optimization</h1><p><em>(Simple explanations + runnable SQL demos + 10 practice exercises)</em></p><div><hr></div><h2>&#127919; Why this chapter matters</h2><p>When your tables grow from a few hundred rows to <strong>millions</strong>, even correct SQL can crawl.<br>Learning a handful of tuning tricks&#8212;<strong>indexes</strong>, <strong>query plans</strong>, and <strong>query-writing habits</strong>&#8212;makes the difference between a 5-second and a 5-millisecond result.</p><div><hr></div><h2>&#129504; What You&#8217;ll Learn</h2><ul><li><p>How PostgreSQL looks for data (execution plans)</p></li><li><p>How and when to create <strong>indexes</strong></p></li><li><p>Primary vs secondary indexes</p></li><li><p>Reading <code>EXPLAIN</code> output</p></li><li><p>Reducing work with selective <code>WHERE</code> clauses and <code>LIMIT</code></p></li><li><p>Using materialized views for expensive reports</p></li><li><p>Avoiding common slow-query mistakes</p></li></ul><p>Every block below is safe to copy-paste&#8212;it drops and rebuilds its own tables.</p><div><hr></div><h2>&#129513; Example 1 &#8212; Why indexes exist</h2><pre><code><code>-- EX1: full table scan
DROP TABLE IF EXISTS ex1_users;
CREATE TABLE ex1_users(id SERIAL PRIMARY KEY, name TEXT, city TEXT);
INSERT INTO ex1_users(name, city)
SELECT &#8216;User&#8217;||g, CASE WHEN g%3=0 THEN &#8216;Brussels&#8217;
                       WHEN g%3=1 THEN &#8216;London&#8217;
                       ELSE &#8216;Paris&#8217; END
FROM generate_series(1,50000) g;

-- Without index
EXPLAIN ANALYZE SELECT * FROM ex1_users WHERE city=&#8217;Paris&#8217;;

-- Add index and rerun
CREATE INDEX idx_city ON ex1_users(city);
EXPLAIN ANALYZE SELECT * FROM ex1_users WHERE city=&#8217;Paris&#8217;;
</code></code></pre><p><strong>Layman:</strong><br>Before the index, PostgreSQL had to read <em>every</em> page&#8212;like flipping every sheet in a filing cabinet.<br>After the index, it jumps straight to the &#8220;Paris&#8221; pages.</p><div><hr></div><h2>&#129513; Example 2 &#8212; Understanding <code>EXPLAIN</code></h2><pre><code><code>EXPLAIN SELECT * FROM ex1_users WHERE city=&#8217;Paris&#8217;;
EXPLAIN ANALYZE SELECT * FROM ex1_users WHERE city=&#8217;Paris&#8217;;
</code></code></pre><p><strong>Plain English:</strong></p><ul><li><p><code>EXPLAIN</code> = show plan (what Postgres <em>will</em> do).</p></li><li><p><code>EXPLAIN ANALYZE</code> = run it + show actual time.<br>Look for:</p></li></ul><ul><li><p><code>Seq Scan</code> &#8594; sequential scan = no index used.</p></li><li><p><code>Index Scan</code> &#8594; index used &#9989;.</p></li><li><p><code>Rows removed by filter</code> &#8594; how many were checked but discarded.</p></li></ul><div><hr></div><h2>&#129513; Example 3 &#8212; Composite (index on multiple columns)</h2><pre><code><code>DROP INDEX IF EXISTS idx_city;
CREATE INDEX idx_city_name ON ex1_users(city, name);
EXPLAIN ANALYZE SELECT * FROM ex1_users
WHERE city=&#8217;Paris&#8217; AND name LIKE &#8216;User1%&#8217;;
</code></code></pre><p><strong>Tip:</strong> put the more selective column (city) first; Postgres filters it first.</p><div><hr></div><h2>&#129513; Example 4 &#8212; Unique and Partial Indexes</h2><pre><code><code>-- unique index automatically created by PRIMARY KEY
-- partial index example: only London users
CREATE INDEX idx_london_only ON ex1_users(name)
WHERE city=&#8217;London&#8217;;

EXPLAIN ANALYZE SELECT * FROM ex1_users
WHERE city=&#8217;London&#8217; AND name LIKE &#8216;User2%&#8217;;
</code></code></pre><p>Partial indexes speed up queries that always include a specific condition.</p><div><hr></div><h2>&#129513; Example 5 &#8212; Avoid functions on indexed columns</h2><pre><code><code>-- Bad: function disables index
EXPLAIN SELECT * FROM ex1_users WHERE LOWER(city)=&#8217;paris&#8217;;

-- Good: store lowercase in another column or use expression index
CREATE INDEX idx_lower_city ON ex1_users((LOWER(city)));
EXPLAIN SELECT * FROM ex1_users WHERE LOWER(city)=&#8217;paris&#8217;;
</code></code></pre><p><strong>Rule:</strong> if you wrap the column in a function, create a matching <strong>expression index</strong>.</p><div><hr></div><h2>&#129513; Example 6 &#8212; Materialized Views (caching heavy queries)</h2><pre><code><code>-- EX6: cache total users per city
DROP MATERIALIZED VIEW IF EXISTS mv_city_counts;
CREATE MATERIALIZED VIEW mv_city_counts AS
SELECT city, COUNT(*) AS total
FROM ex1_users GROUP BY city;

SELECT * FROM mv_city_counts;

-- refresh when data changes
REFRESH MATERIALIZED VIEW mv_city_counts;
</code></code></pre><p>Think of materialized views as <strong>stored snapshots</strong>&#8212;faster for dashboards.</p><div><hr></div><h2>&#129513; Example 7 &#8212; Limit and Pagination</h2><pre><code><code>EXPLAIN ANALYZE SELECT * FROM ex1_users ORDER BY id LIMIT 10 OFFSET 100;
</code></code></pre><p><code>LIMIT</code> reduces work; combine with indexes on <code>ORDER BY</code> columns for speed.</p><div><hr></div><h2>&#129513; Example 8 &#8212; Using <code>VACUUM ANALYZE</code></h2><pre><code><code>VACUUM ANALYZE ex1_users;
</code></code></pre><p>Tells PostgreSQL to clean old rows and refresh statistics so the planner picks good indexes.</p><div><hr></div><h2>&#129513; Example 9 &#8212; Rewriting for performance</h2><pre><code><code>-- slow
SELECT * FROM ex1_users WHERE city IN (SELECT city FROM ex1_users WHERE id&lt;10);

-- faster equivalent using join
SELECT u.* FROM ex1_users u
JOIN (SELECT DISTINCT city FROM ex1_users WHERE id&lt;10) c USING(city);
</code></code></pre><p>Joins are often faster than <code>IN</code> when subquery returns many rows.</p><div><hr></div><h2>&#129513; Example 10 &#8212; EXPLAIN buffers and I/O timing</h2><pre><code><code>EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM ex1_users WHERE city=&#8217;Paris&#8217;;
</code></code></pre><p>Shows memory/disk reads; use it to catch &#8220;I/O bound&#8221; queries.</p><div><hr></div><h2>&#9881;&#65039; Quick Tuning Checklist</h2><p>&#9989; Create indexes for columns used often in <code>WHERE</code>, <code>JOIN</code>, <code>ORDER BY</code>.<br>&#9989; Avoid wildcards at the start of <code>LIKE &#8216;%term&#8217;</code>.<br>&#9989; Use the smallest data type possible (<code>INT</code> vs <code>BIGINT</code>).<br>&#9989; Run <code>ANALYZE</code> after large changes.<br>&#9989; Batch inserts; avoid one row per transaction.<br>&#9989; Cache expensive aggregates in materialized views.</p><div><hr></div><h2>&#129513; 10 Practice Exercises</h2><ol><li><p>Build a <code>customers(city, country)</code> table with 100 K rows and test query speed with and without an index.</p></li><li><p>Create a composite index on <code>(country, city)</code> and compare <code>EXPLAIN</code> plans.</p></li><li><p>Write a query that benefits from a partial index (<code>WHERE active=true</code>).</p></li><li><p>Add an expression index on <code>LOWER(email)</code> and verify its use.</p></li><li><p>Use <code>EXPLAIN ANALYZE</code> to compare <code>IN</code> vs <code>JOIN</code> performance.</p></li><li><p>Create a materialized view summarizing total sales per month and refresh it.</p></li><li><p>Demonstrate a transaction with many inserts followed by one <code>COMMIT</code>; compare to per-row commits.</p></li><li><p>Delete 10 000 rows, run <code>VACUUM ANALYZE</code>, and note the difference in plan cost.</p></li><li><p>Show how <code>LIMIT 10</code> changes query time compared to full scan.</p></li><li><p>Turn a slow correlated subquery into a join and confirm via <code>EXPLAIN</code> that the plan improves.</p></li></ol><div><hr></div><h1>Chapter 10 &#8212; AI / Data-Specific SQL Use Cases</h1><p><em>(Feature Engineering &#183; Time Series &#183; ETL Data Quality &#183; Integration with Python)</em></p><div><hr></div><h2>&#127919; Why this chapter matters</h2><p>Everything you learned so far becomes truly powerful when you apply it to <strong>AI &amp; ML data preparation</strong>.<br>In real projects, 70&#8211;80 % of the work before model training is <strong>SQL-based data wrangling</strong>&#8212;joining multiple data sources, engineering features, detecting anomalies, and validating ETL pipelines.</p><p>This chapter shows exactly how those techniques appear in production pipelines.</p><div><hr></div><h2>&#129504; What You&#8217;ll Learn</h2><ul><li><p>Write SQL for <strong>feature engineering</strong> (ratios, lags, aggregates).</p></li><li><p>Do <strong>time-series transformations</strong> directly in PostgreSQL.</p></li><li><p>Build <strong>ETL data-quality checks</strong> with SQL.</p></li><li><p>Detect anomalies or missing values.</p></li><li><p>Combine SQL + Python for real-world model input pipelines.</p></li></ul><p>All examples are copy-paste runnable.</p><div><hr></div><h2>&#129513; Example 1 &#8212; Feature Engineering: ratios &amp; counts</h2><pre><code><code>-- EX1: User activity features
DROP TABLE IF EXISTS ex1_activity;
CREATE TABLE ex1_activity(
  user_id INT, sessions INT, purchases INT, revenue NUMERIC(8,2)
);
INSERT INTO ex1_activity VALUES
(1,10,2,200),(2,15,5,500),(3,8,0,0),(4,20,10,900);

SELECT
  user_id,
  sessions,
  purchases,
  revenue,
  ROUND(revenue/purchases,2) AS avg_order_value,
  ROUND(purchases::NUMERIC/sessions,2) AS conversion_rate
FROM ex1_activity;
</code></code></pre><p><strong>Idea:</strong> Create derived columns that describe behavior&#8212;these become model features.</p><div><hr></div><h2>&#129513; Example 2 &#8212; Time-Series: rolling metrics</h2><pre><code><code>-- EX2: rolling 7-day sales
DROP TABLE IF EXISTS ex2_sales;
CREATE TABLE ex2_sales(day DATE, revenue NUMERIC);
INSERT INTO ex2_sales
SELECT d::DATE, (100 + random()*50)::INT
FROM generate_series(&#8217;2025-01-01&#8217;,&#8217;2025-01-20&#8217;,&#8217;1 day&#8217;) d;

SELECT
  day,
  revenue,
  ROUND(AVG(revenue) OVER(
      ORDER BY day ROWS BETWEEN 6 PRECEDING AND CURRENT ROW),2) AS avg_7d,
  SUM(revenue)  OVER(
      ORDER BY day ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS sum_7d
FROM ex2_sales
ORDER BY day;
</code></code></pre><p><strong>Why:</strong> Rolling windows capture short-term trends for forecasting.</p><div><hr></div><h2>&#129513; Example 3 &#8212; Feature Lag for Prediction</h2><pre><code><code>-- EX3: previous-day revenue
SELECT
  day,
  revenue,
  LAG(revenue) OVER(ORDER BY day) AS prev_day,
  revenue - LAG(revenue) OVER(ORDER BY day) AS diff
FROM ex2_sales
ORDER BY day;
</code></code></pre><p><strong>Use:</strong> previous-value deltas often feed time-series regression models.</p><div><hr></div><h2>&#129513; Example 4 &#8212; Outlier &amp; Anomaly Detection</h2><pre><code><code>-- EX4: find abnormal sales
WITH stats AS (
  SELECT AVG(revenue) AS mean, STDDEV_POP(revenue) AS sd FROM ex2_sales
)
SELECT s.day, s.revenue,
       CASE WHEN s.revenue &gt; mean+2*sd THEN &#8216;High Outlier&#8217;
            WHEN s.revenue &lt; mean-2*sd THEN &#8216;Low Outlier&#8217;
            ELSE &#8216;Normal&#8217; END AS flag
FROM ex2_sales s, stats;
</code></code></pre><p><strong>Layman:</strong> anything &gt; 2 &#963; from mean is flagged&#8212;quick anomaly check before training.</p><div><hr></div><h2>&#129513; Example 5 &#8212; Data Quality / ETL Checks</h2><pre><code><code>-- EX5: data-validation example
DROP TABLE IF EXISTS ex5_orders;
CREATE TABLE ex5_orders(id INT, amount NUMERIC, customer_id INT, order_date DATE);
INSERT INTO ex5_orders VALUES
(1,100,10,&#8217;2025-01-05&#8217;),
(2,NULL,11,&#8217;2025-01-06&#8217;),
(3,120,10,NULL),
(4,90,NULL,&#8217;2025-01-07&#8217;);

SELECT
  COUNT(*) FILTER(WHERE amount IS NULL)     AS missing_amount,
  COUNT(*) FILTER(WHERE customer_id IS NULL)AS missing_customer,
  COUNT(*) FILTER(WHERE order_date IS NULL) AS missing_date,
  COUNT(DISTINCT id)                        AS unique_ids
FROM ex5_orders;
</code></code></pre><p><strong>Why:</strong> ETL jobs run these checks daily to prevent dirty data from entering AI pipelines.</p><div><hr></div><h2>&#129513; Example 6 &#8212; Deduplication</h2><pre><code><code>-- EX6: remove duplicates keeping latest
DROP TABLE IF EXISTS ex6_logs;
CREATE TABLE ex6_logs(user_id INT, event_ts TIMESTAMP, source TEXT);
INSERT INTO ex6_logs VALUES
(1,&#8217;2025-01-01 10:00&#8217;,&#8217;web&#8217;),
(1,&#8217;2025-01-01 12:00&#8217;,&#8217;mobile&#8217;),
(1,&#8217;2025-01-01 12:00&#8217;,&#8217;mobile&#8217;); -- duplicate

DELETE FROM ex6_logs a
USING ex6_logs b
WHERE a.ctid&lt;b.ctid AND a.user_id=b.user_id AND a.event_ts=b.event_ts;

SELECT * FROM ex6_logs;
</code></code></pre><p><strong>Idea:</strong> Keep one row per unique key.</p><div><hr></div><h2>&#129513; Example 7 &#8212; Creating Train/Test Splits</h2><pre><code><code>-- EX7: random split
DROP TABLE IF EXISTS ex7_dataset;
CREATE TABLE ex7_dataset(id SERIAL, feature NUMERIC);
INSERT INTO ex7_dataset(feature)
SELECT random()*100 FROM generate_series(1,20);

SELECT id, feature,
       CASE WHEN random()&lt;0.8 THEN &#8216;train&#8217; ELSE &#8216;test&#8217; END AS dataset_split
FROM ex7_dataset;
</code></code></pre><p><strong>Use:</strong> simple SQL-based splitting before exporting to Python.</p><div><hr></div><h2>&#129513; Example 8 &#8212; Feature Scaling and Normalization</h2><pre><code><code>-- EX8: z-score normalization
SELECT
  feature,
  ROUND((feature - AVG(feature) OVER()) /
        STDDEV_POP(feature) OVER(),2) AS z_score
FROM ex7_dataset;
</code></code></pre><p><strong>Why:</strong> scaled features help many ML models converge faster.</p><div><hr></div><h2>&#129513; Example 9 &#8212; Combine SQL + Python (pandas integration)</h2><pre><code><code># Python snippet (run separately)
import pandas as pd, sqlalchemy as sa
engine = sa.create_engine(&#8221;postgresql://user:pwd@localhost/db&#8221;)

df = pd.read_sql(&#8221;&#8220;&#8221;
    SELECT id, feature,
           (feature - AVG(feature) OVER()) / STDDEV_POP(feature) OVER() AS z
    FROM ex7_dataset
&#8220;&#8221;&#8220;, engine)

print(df.head())
</code></code></pre><p><strong>Takeaway:</strong> use SQL for heavy lifting, pandas for downstream modeling.</p><div><hr></div><h2>&#129513; Example 10 &#8212; Time-based Feature Store</h2><pre><code><code>-- EX10: daily aggregates ready for ML
WITH daily AS (
  SELECT DATE(event_ts) AS day, user_id, COUNT(*) AS actions
  FROM ex6_logs
  GROUP BY 1,2
),
user_stats AS (
  SELECT user_id,
         AVG(actions) AS avg_actions,
         MAX(actions) AS max_actions
  FROM daily GROUP BY user_id
)
SELECT * FROM user_stats;
</code></code></pre><p><strong>Purpose:</strong> store compact per-user summaries for model input.</p><div><hr></div><h2>&#9881;&#65039; Quick Checklist for AI Data in SQL</h2><p>&#9989; Use window functions for temporal features.<br>&#9989; Normalize or bucket numeric columns.<br>&#9989; Run quality checks (<code>COUNT NULL</code>, outliers) before export.<br>&#9989; Use <code>CTEs</code> to chain transformations cleanly.<br>&#9989; Push as much aggregation logic as possible into PostgreSQL before moving data to Python.</p><div><hr></div><h2>&#129513; 10 Practice Exercises</h2><ol><li><p>Create a transactions table and build features: total_spend, avg_spend, transactions_last_7d.</p></li><li><p>Compute daily revenue change % using <code>LAG()</code>.</p></li><li><p>Detect outliers beyond 3 &#215; standard deviation.</p></li><li><p>Count missing fields per column for a dataset.</p></li><li><p>Write a deduplication query keeping the newest timestamp.</p></li><li><p>Generate a random 80/20 train-test split.</p></li><li><p>Standardize a numeric feature with z-score formula in SQL.</p></li><li><p>Create aggregated features per customer for ML (avg_order, max_order).</p></li><li><p>Build a materialized view that stores yesterday&#8217;s metrics for quick access.</p></li><li><p>Export aggregated data to Python (pandas) for model training.</p></li></ol><div><hr></div><h1>Chapter 11 &#8212; Python Integration &amp; Automation</h1><p><em>(PostgreSQL + Python with pandas, SQLAlchemy, psycopg2 &#8212; ETL scripting, automation, and data pipelines)</em></p><div><hr></div><h2>&#127919; Why this chapter matters</h2><p>In real-world AI, ML, or data-engineering jobs, you rarely work inside the SQL shell.<br>You use <strong>Python as the controller</strong> &#8212; to run queries, fetch data, clean it, transform it further, and load it into models or dashboards.</p><p>This chapter connects everything you&#8217;ve learned in SQL to Python &#8212; turning PostgreSQL into a <strong>powerful backend for data pipelines, ETL jobs, and feature engineering systems.</strong></p><div><hr></div><h2>&#129504; What You&#8217;ll Learn</h2><ul><li><p>How to connect Python to PostgreSQL</p></li><li><p>Run queries and fetch results into pandas</p></li><li><p>Write data back to the database</p></li><li><p>Automate ETL scripts (Extract&#8211;Transform&#8211;Load)</p></li><li><p>Parameterize queries</p></li><li><p>Handle transactions safely in Python</p></li><li><p>Schedule recurring jobs</p></li></ul><div><hr></div><h2>&#129513; Example 1 &#8212; Connecting Python to PostgreSQL (SQLAlchemy + pandas)</h2><pre><code><code># EX1: Basic connection and read
import pandas as pd
from sqlalchemy import create_engine

# connection string format:
# postgresql://username:password@host:port/database
engine = create_engine(&#8221;postgresql://postgres:password@localhost:5432/ai_course&#8221;)

# read data directly into pandas
df = pd.read_sql(&#8221;SELECT * FROM ex1_users LIMIT 5;&#8221;, engine)
print(df.head())
</code></code></pre><p><strong>Plain Explanation:</strong></p><ul><li><p>SQLAlchemy builds the connection engine.</p></li><li><p><code>pd.read_sql()</code> executes SQL and returns a DataFrame.</p></li><li><p>You can now use pandas functions like <code>.describe()</code> or <code>.plot()</code> on SQL data.</p></li></ul><div><hr></div><h2>&#129513; Example 2 &#8212; Writing Data from pandas to PostgreSQL</h2><pre><code><code># EX2: Write dataframe to SQL
data = {
    &#8220;user_id&#8221;: [1, 2, 3],
    &#8220;score&#8221;: [85, 92, 76],
    &#8220;subject&#8221;: [&#8221;Math&#8221;, &#8220;AI&#8221;, &#8220;Data Science&#8221;]
}
df_new = pd.DataFrame(data)

df_new.to_sql(&#8221;student_scores&#8221;, engine, if_exists=&#8221;replace&#8221;, index=False)

print(&#8221;&#9989; Data written to PostgreSQL successfully!&#8221;)
</code></code></pre><p><strong>Explanation:</strong></p><ul><li><p><code>if_exists=&#8221;replace&#8221;</code> overwrites the table (use <code>&#8220;append&#8221;</code> to add).</p></li><li><p>pandas handles type conversion automatically.</p></li></ul><div><hr></div><h2>&#129513; Example 3 &#8212; Parameterized Query (Safe Against SQL Injection)</h2><pre><code><code># EX3: parameterized query
import pandas as pd
from sqlalchemy import text

query = text(&#8221;SELECT * FROM ex1_users WHERE city = :city_name LIMIT 5&#8221;)
df_paris = pd.read_sql(query, engine, params={&#8221;city_name&#8221;: &#8220;Paris&#8221;})
print(df_paris)
</code></code></pre><p><strong>Why this matters:</strong><br>Using placeholders (<code>:city_name</code>) avoids injection and lets you pass variables dynamically.</p><div><hr></div><h2>&#129513; Example 4 &#8212; psycopg2 Low-Level Connection</h2><pre><code><code># EX4: psycopg2 basics
import psycopg2

conn = psycopg2.connect(
    dbname=&#8221;ai_course&#8221;,
    user=&#8221;postgres&#8221;,
    password=&#8221;password&#8221;,
    host=&#8221;localhost&#8221;,
    port=&#8221;5432&#8221;
)
cur = conn.cursor()
cur.execute(&#8221;SELECT COUNT(*) FROM ex1_users;&#8221;)
print(&#8221;Total users:&#8221;, cur.fetchone()[0])
conn.close()
</code></code></pre><p><strong>Explanation:</strong><br><code>psycopg2</code> is PostgreSQL&#8217;s official driver &#8212; lower-level than SQLAlchemy, but gives fine-grained control for transactions and cursors.</p><div><hr></div><h2>&#129513; Example 5 &#8212; ETL Script (Extract &#8594; Transform &#8594; Load)</h2><pre><code><code># EX5: Simple ETL job
import pandas as pd

# Step 1: Extract from PostgreSQL
df = pd.read_sql(&#8221;SELECT * FROM ex2_sales;&#8221;, engine)

# Step 2: Transform
df[&#8221;rolling_avg&#8221;] = df[&#8221;revenue&#8221;].rolling(3, min_periods=1).mean().round(2)
df[&#8221;pct_change&#8221;] = df[&#8221;revenue&#8221;].pct_change().round(2)

# Step 3: Load results into a new table
df.to_sql(&#8221;sales_features&#8221;, engine, if_exists=&#8221;replace&#8221;, index=False)
print(&#8221;&#9989; ETL completed successfully!&#8221;)
</code></code></pre><p><strong>Use Case:</strong><br>This is how you generate ML features automatically every night.</p><div><hr></div><h2>&#129513; Example 6 &#8212; Handling Transactions in Python</h2><pre><code><code># EX6: Transaction handling
try:
    with engine.begin() as conn:
        conn.execute(text(&#8221;INSERT INTO ex1_users(name, city) VALUES(&#8217;Nina&#8217;,&#8217;Paris&#8217;)&#8221;))
        conn.execute(text(&#8221;UPDATE ex1_users SET city=&#8217;London&#8217; WHERE id=2&#8221;))
    print(&#8221;&#9989; Transaction committed successfully.&#8221;)
except Exception as e:
    print(&#8221;&#10060; Rolled back due to error:&#8221;, e)
</code></code></pre><p><strong>Layman Explanation:</strong><br><code>with engine.begin()</code> ensures <strong>all statements succeed or none do</strong> &#8212; same as <code>BEGIN ... COMMIT / ROLLBACK</code> in SQL.</p><div><hr></div><h2>&#129513; Example 7 &#8212; Scheduling Automatic ETL Jobs (Python + cron / schedule)</h2><pre><code><code># EX7: schedule daily job
import schedule, time

def run_daily_etl():
    print(&#8221;Running daily ETL...&#8221;)
    df = pd.read_sql(&#8221;SELECT * FROM ex2_sales;&#8221;, engine)
    df[&#8221;daily_norm&#8221;] = (df[&#8221;revenue&#8221;] - df[&#8221;revenue&#8221;].mean()) / df[&#8221;revenue&#8221;].std()
    df.to_sql(&#8221;daily_normalized_sales&#8221;, engine, if_exists=&#8221;replace&#8221;, index=False)
    print(&#8221;&#9989; Daily ETL finished.&#8221;)

# run every 24 hours
schedule.every(24).hours.do(run_daily_etl)

while True:
    schedule.run_pending()
    time.sleep(10)
</code></code></pre><p><strong>Explanation:</strong><br>The <code>schedule</code> library triggers your ETL job automatically &#8212; ideal for nightly feature refreshes.</p><div><hr></div><h2>&#129513; Example 8 &#8212; Reading Materialized Views or Aggregates</h2><pre><code><code># EX8: materialized view read
df_summary = pd.read_sql(&#8221;SELECT * FROM mv_city_counts;&#8221;, engine)
print(df_summary)
</code></code></pre><p>This lets your dashboard or notebook pull <strong>precomputed aggregates</strong> instantly.</p><div><hr></div><h2>&#129513; Example 9 &#8212; Export Query Results to CSV for Model Training</h2><pre><code><code># EX9: export data to CSV
df = pd.read_sql(&#8221;SELECT * FROM sales_features;&#8221;, engine)
df.to_csv(&#8221;train_dataset.csv&#8221;, index=False)
print(&#8221;&#9989; train_dataset.csv created.&#8221;)
</code></code></pre><p><strong>Use:</strong> easily move cleaned SQL data into your ML workflow.</p><div><hr></div><h2>&#129513; Example 10 &#8212; Integrating SQL + pandas + scikit-learn</h2><pre><code><code># EX10: Build a small ML model from SQL data
import pandas as pd
from sklearn.linear_model import LinearRegression

# read features
df = pd.read_sql(&#8221;SELECT day, revenue, avg_7d, sum_7d FROM sales_features;&#8221;, engine)
X = df[[&#8221;avg_7d&#8221;, &#8220;sum_7d&#8221;]]
y = df[&#8221;revenue&#8221;]

model = LinearRegression()
model.fit(X, y)
print(&#8221;Coefficients:&#8221;, model.coef_)
</code></code></pre><p><strong>Explanation:</strong><br>This is the real bridge &#8212; SQL cleans and prepares your dataset, pandas loads it, and scikit-learn trains the model.</p><div><hr></div><h2>&#9881;&#65039; Real-World Integration Workflow</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SkLa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7962267-3538-4c43-8f1f-9efe3b487808_710x321.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SkLa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7962267-3538-4c43-8f1f-9efe3b487808_710x321.png 424w, https://substackcdn.com/image/fetch/$s_!SkLa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7962267-3538-4c43-8f1f-9efe3b487808_710x321.png 848w, https://substackcdn.com/image/fetch/$s_!SkLa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7962267-3538-4c43-8f1f-9efe3b487808_710x321.png 1272w, https://substackcdn.com/image/fetch/$s_!SkLa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7962267-3538-4c43-8f1f-9efe3b487808_710x321.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SkLa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7962267-3538-4c43-8f1f-9efe3b487808_710x321.png" width="710" height="321" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b7962267-3538-4c43-8f1f-9efe3b487808_710x321.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:321,&quot;width&quot;:710,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:21632,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7962267-3538-4c43-8f1f-9efe3b487808_710x321.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SkLa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7962267-3538-4c43-8f1f-9efe3b487808_710x321.png 424w, https://substackcdn.com/image/fetch/$s_!SkLa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7962267-3538-4c43-8f1f-9efe3b487808_710x321.png 848w, https://substackcdn.com/image/fetch/$s_!SkLa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7962267-3538-4c43-8f1f-9efe3b487808_710x321.png 1272w, https://substackcdn.com/image/fetch/$s_!SkLa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7962267-3538-4c43-8f1f-9efe3b487808_710x321.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129513; 10 Practice Exercises</h2><ol><li><p>Connect to your PostgreSQL database using SQLAlchemy and print table names.</p></li><li><p>Use pandas to read 100 rows from a large table.</p></li><li><p>Write a new DataFrame into PostgreSQL with <code>to_sql</code>.</p></li><li><p>Run a parameterized query to filter users by city name.</p></li><li><p>Build an ETL job that extracts, transforms (normalize one column), and writes back.</p></li><li><p>Wrap multiple inserts in one transaction and test rollback on error.</p></li><li><p>Schedule a Python function to refresh a materialized view every hour.</p></li><li><p>Read a view into pandas and export it to CSV.</p></li><li><p>Use SQL + pandas to calculate moving averages and plot them.</p></li><li><p>Combine SQL (data extraction) and scikit-learn (regression model) end-to-end.</p></li></ol><div><hr></div><h1>Chapter 12 &#8212; Final Project: End-to-End AI Data Pipeline</h1><p><em>(PostgreSQL + SQL + Python + Feature Engineering + ETL + Automation)</em></p><div><hr></div><h2>&#127919; Project Goal</h2><p>This final project brings everything together into a <strong>real-world AI data pipeline</strong>, where:</p><ol><li><p>Data is collected and stored in PostgreSQL.</p></li><li><p>SQL transforms raw logs into clean, feature-rich tables.</p></li><li><p>Python automates ETL and triggers model training.</p></li><li><p>The pipeline runs daily &#8212; automatically refreshing features.</p></li></ol><p>By the end, you&#8217;ll have a <strong>production-style mini data pipeline</strong>, like what Data Engineers and AI Developers build in real jobs.</p><div><hr></div><h2>&#129504; Project Scenario</h2><p>You&#8217;re working for an <strong>AI-driven e-commerce platform</strong> called <strong>ShopAI</strong>.<br>You have two main datasets:</p><ul><li><p><code>orders</code> &#8594; every purchase made by a user.</p></li><li><p><code>users</code> &#8594; information about customers.</p></li></ul><p>Your job is to:</p><ol><li><p>Clean and prepare this raw data.</p></li><li><p>Generate analytical features for churn prediction and spend forecasting.</p></li><li><p>Automate the pipeline using Python and schedule it daily.</p></li></ol><div><hr></div><h2>&#128202; Database Setup (SQL Schema)</h2><pre><code><code>-- DROP old tables
DROP TABLE IF EXISTS users CASCADE;
DROP TABLE IF EXISTS orders CASCADE;

-- USERS TABLE
CREATE TABLE users (
  user_id SERIAL PRIMARY KEY,
  name TEXT,
  signup_date DATE,
  city TEXT
);

-- ORDERS TABLE
CREATE TABLE orders (
  order_id SERIAL PRIMARY KEY,
  user_id INT REFERENCES users(user_id),
  order_date DATE,
  amount NUMERIC(8,2)
);
</code></code></pre><div><hr></div><h2>&#129513; Step 1 &#8212; Insert Sample Data</h2><pre><code><code>INSERT INTO users (name, signup_date, city) VALUES
(&#8217;Alice&#8217;,&#8217;2025-01-01&#8217;,&#8217;Paris&#8217;),
(&#8217;Ben&#8217;,&#8217;2025-01-03&#8217;,&#8217;London&#8217;),
(&#8217;Carmen&#8217;,&#8217;2025-01-05&#8217;,&#8217;Paris&#8217;),
(&#8217;David&#8217;,&#8217;2025-01-10&#8217;,&#8217;Berlin&#8217;);

INSERT INTO orders (user_id, order_date, amount) VALUES
(1,&#8217;2025-01-02&#8217;,100),
(1,&#8217;2025-01-05&#8217;,120),
(1,&#8217;2025-01-10&#8217;,80),
(2,&#8217;2025-01-04&#8217;,200),
(2,&#8217;2025-01-07&#8217;,150),
(3,&#8217;2025-01-10&#8217;,50),
(4,&#8217;2025-01-11&#8217;,300),
(4,&#8217;2025-01-14&#8217;,200);
</code></code></pre><div><hr></div><h2>&#129513; Step 2 &#8212; Clean the Data</h2><pre><code><code>-- remove duplicates if any
DELETE FROM orders a USING orders b
WHERE a.ctid &lt; b.ctid
  AND a.user_id=b.user_id
  AND a.order_date=b.order_date;

-- fix nulls with COALESCE
UPDATE users SET city = COALESCE(city, &#8216;Unknown&#8217;);
</code></code></pre><p><strong>Why:</strong> ensures data consistency before analysis.</p><div><hr></div><h2>&#129513; Step 3 &#8212; Generate Features (SQL Feature Engineering)</h2><h3>1&#65039;&#8419; Total spend, average spend, last order date</h3><pre><code><code>CREATE OR REPLACE VIEW user_features AS
SELECT
  u.user_id,
  u.name,
  u.city,
  COUNT(o.order_id) AS total_orders,
  SUM(o.amount) AS total_spend,
  ROUND(AVG(o.amount),2) AS avg_spend,
  MAX(o.order_date) AS last_order,
  CURRENT_DATE - MAX(o.order_date) AS days_since_last_order
FROM users u
LEFT JOIN orders o ON u.user_id=o.user_id
GROUP BY u.user_id, u.name, u.city;
</code></code></pre><h3>2&#65039;&#8419; Add ranking per city (window function)</h3><pre><code><code>SELECT *,
  RANK() OVER (PARTITION BY city ORDER BY total_spend DESC) AS rank_in_city
FROM user_features;
</code></code></pre><div><hr></div><h2>&#129513; Step 4 &#8212; Create Materialized Feature Store</h2><pre><code><code>DROP MATERIALIZED VIEW IF EXISTS user_feature_store;
CREATE MATERIALIZED VIEW user_feature_store AS
SELECT *,
       CASE
         WHEN days_since_last_order &gt; 5 THEN &#8216;Inactive&#8217;
         ELSE &#8216;Active&#8217;
       END AS activity_flag
FROM user_features;

-- refresh manually when new orders arrive
REFRESH MATERIALIZED VIEW user_feature_store;

SELECT * FROM user_feature_store;
</code></code></pre><p><strong>Purpose:</strong><br>Materialized views store snapshots of features for faster model input.</p><div><hr></div><h2>&#129513; Step 5 &#8212; Build Python ETL Script</h2><pre><code><code># etl_shopai.py
import pandas as pd
from sqlalchemy import create_engine, text
import datetime

engine = create_engine(&#8221;postgresql://postgres:password@localhost:5432/ai_course&#8221;)

print(&#8221;&#129513; Starting ETL at&#8221;, datetime.datetime.now())

# 1. Extract data
df_users = pd.read_sql(&#8221;SELECT * FROM users;&#8221;, engine)
df_orders = pd.read_sql(&#8221;SELECT * FROM orders;&#8221;, engine)

# 2. Transform (feature engineering)
df_features = (
    df_orders.groupby(&#8221;user_id&#8221;)
    .agg(total_orders=(&#8221;order_id&#8221;,&#8221;count&#8221;),
         total_spend=(&#8221;amount&#8221;,&#8221;sum&#8221;),
         avg_spend=(&#8221;amount&#8221;,&#8221;mean&#8221;),
         last_order=(&#8221;order_date&#8221;,&#8221;max&#8221;))
    .reset_index()
)

df_features[&#8221;days_since_last_order&#8221;] = (
    pd.Timestamp(&#8221;2025-01-15&#8221;) - pd.to_datetime(df_features[&#8221;last_order&#8221;])
).dt.days

# 3. Join with users table
df_final = pd.merge(df_users, df_features, on=&#8221;user_id&#8221;, how=&#8221;left&#8221;)
df_final[&#8221;activity_flag&#8221;] = df_final[&#8221;days_since_last_order&#8221;].apply(
    lambda x: &#8220;Inactive&#8221; if x&gt;5 else &#8220;Active&#8221;
)

# 4. Load to PostgreSQL
df_final.to_sql(&#8221;user_feature_store_py&#8221;, engine, if_exists=&#8221;replace&#8221;, index=False)
print(&#8221;&#9989; ETL completed and stored in PostgreSQL.&#8221;)
</code></code></pre><div><hr></div><h2>&#129513; Step 6 &#8212; Schedule Daily Feature Updates</h2><p>You can schedule this ETL using <strong>Python&#8217;s schedule</strong> module or <strong>cron</strong>.</p><pre><code><code>import schedule, time
from subprocess import run

def run_daily_pipeline():
    run([&#8221;python3&#8221;,&#8221;etl_shopai.py&#8221;])

schedule.every().day.at(&#8221;02:00&#8221;).do(run_daily_pipeline)

while True:
    schedule.run_pending()
    time.sleep(60)
</code></code></pre><div><hr></div><h2>&#129513; Step 7 &#8212; Use Features in a Machine Learning Model</h2><pre><code><code>import pandas as pd
from sqlalchemy import create_engine
from sklearn.linear_model import LogisticRegression

engine = create_engine(&#8221;postgresql://postgres:password@localhost:5432/ai_course&#8221;)
df = pd.read_sql(&#8221;SELECT * FROM user_feature_store_py;&#8221;, engine)

# Example target: Inactive=1, Active=0
df[&#8221;target&#8221;] = (df[&#8221;activity_flag&#8221;]==&#8221;Inactive&#8221;).astype(int)

X = df[[&#8221;total_orders&#8221;,&#8221;total_spend&#8221;,&#8221;avg_spend&#8221;,&#8221;days_since_last_order&#8221;]]
y = df[&#8221;target&#8221;]

model = LogisticRegression()
model.fit(X, y)

print(&#8221;Model coefficients:&#8221;, model.coef_)
print(&#8221;&#9989; Model trained on SQL-generated features.&#8221;)
</code></code></pre><div><hr></div><h2>&#129513; Step 8 &#8212; Monitor and Refresh</h2><ol><li><p>Set <code>REFRESH MATERIALIZED VIEW user_feature_store;</code> nightly in SQL.</p></li><li><p>Or schedule Python ETL to rerun daily.</p></li><li><p>Monitor data quality (check missing, anomalies).</p></li></ol><div><hr></div><h2>&#9881;&#65039; Full Pipeline Flow</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Yf-B!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71bee271-6a53-499e-b158-4d34a61a2a05_706x370.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Yf-B!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71bee271-6a53-499e-b158-4d34a61a2a05_706x370.png 424w, https://substackcdn.com/image/fetch/$s_!Yf-B!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71bee271-6a53-499e-b158-4d34a61a2a05_706x370.png 848w, https://substackcdn.com/image/fetch/$s_!Yf-B!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71bee271-6a53-499e-b158-4d34a61a2a05_706x370.png 1272w, https://substackcdn.com/image/fetch/$s_!Yf-B!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71bee271-6a53-499e-b158-4d34a61a2a05_706x370.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Yf-B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71bee271-6a53-499e-b158-4d34a61a2a05_706x370.png" width="706" height="370" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/71bee271-6a53-499e-b158-4d34a61a2a05_706x370.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:370,&quot;width&quot;:706,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:28007,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71bee271-6a53-499e-b158-4d34a61a2a05_706x370.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Yf-B!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71bee271-6a53-499e-b158-4d34a61a2a05_706x370.png 424w, https://substackcdn.com/image/fetch/$s_!Yf-B!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71bee271-6a53-499e-b158-4d34a61a2a05_706x370.png 848w, https://substackcdn.com/image/fetch/$s_!Yf-B!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71bee271-6a53-499e-b158-4d34a61a2a05_706x370.png 1272w, https://substackcdn.com/image/fetch/$s_!Yf-B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71bee271-6a53-499e-b158-4d34a61a2a05_706x370.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129513; 10 Practice Exercises</h2><ol><li><p>Add a <code>refunds</code> table and compute <code>net_spend = total_spend - refunds</code>.</p></li><li><p>Include a <code>days_since_signup</code> feature from the users table.</p></li><li><p>Rank users globally and per city.</p></li><li><p>Detect high-value customers (top 10% spenders).</p></li><li><p>Automate feature refresh every hour using Python&#8217;s <code>schedule</code>.</p></li><li><p>Add a daily anomaly detection query for negative order amounts.</p></li><li><p>Export final features to CSV for ML.</p></li><li><p>Visualize daily spend trend in Python with <code>matplotlib</code>.</p></li><li><p>Extend ETL to include new feature: &#8220;average gap between orders&#8221;.</p></li><li><p>Package ETL as a CLI command (<code>python etl_shopai.py --refresh</code>).</p></li></ol><div><hr></div><h2>&#127937; You&#8217;ve Completed the Full PostgreSQL + AI Data Mastery Roadmap &#127881;</h2><p>By finishing this course and project, you now understand:<br>&#9989; SQL for data retrieval and joins<br>&#9989; Advanced analytics (window functions, subqueries, aggregates)<br>&#9989; Data cleaning and optimization<br>&#9989; JSON/arrays and semi-structured data<br>&#9989; Python integration and ETL automation<br>&#9989; Full feature-engineering workflow for AI</p><div><hr></div><p></p><h2>&#127942; 10. Resume/Portfolio Description</h2><p><strong>Title:</strong> <em>AI-Driven Data Pipeline with PostgreSQL and Python</em><br><strong>Duration:</strong> 3 weeks<br><strong>Tech Stack:</strong> PostgreSQL, SQL, Python, pandas, SQLAlchemy, scikit-learn, schedule</p><p><br><strong>Description:</strong></p><p>Designed and implemented an automated data pipeline that extracts transactional data from PostgreSQL, performs SQL-based feature engineering, loads cleaned data into a materialized view, and triggers Python-based model training daily. Included anomaly detection and activity segmentation features used for churn prediction.</p><p><strong>Highlights:</strong></p><ul><li><p>Built ETL pipeline using pandas + SQLAlchemy</p></li><li><p>Created 10+ AI-ready features using SQL window functions</p></li><li><p>Designed automated feature refresh using Python scheduler</p></li><li><p>Trained ML model for churn prediction on SQL-generated features</p></li></ul><div><hr></div><h2>&#128188; 11. GitHub &#129514; Assessment (For Learners)</h2><p>Students enrolled in the CareerByteCode <strong>AI Data Pipeline Course</strong> must use this repository as part of their practical assessment.</p><p><strong>Objective:</strong><br>Identify, debug, and fix small intentional issues in the project to gain real-world experience.</p><p>Git Repo : <a href="https://github.com/careerbytecode/ShopAI_Project.git">https://github.com/careerbytecode/ShopAI_Project.git</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JmYN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350afe33-5f78-42f5-9a18-ed356898f133_677x413.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JmYN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350afe33-5f78-42f5-9a18-ed356898f133_677x413.png 424w, https://substackcdn.com/image/fetch/$s_!JmYN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350afe33-5f78-42f5-9a18-ed356898f133_677x413.png 848w, https://substackcdn.com/image/fetch/$s_!JmYN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350afe33-5f78-42f5-9a18-ed356898f133_677x413.png 1272w, https://substackcdn.com/image/fetch/$s_!JmYN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350afe33-5f78-42f5-9a18-ed356898f133_677x413.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JmYN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350afe33-5f78-42f5-9a18-ed356898f133_677x413.png" width="677" height="413" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/350afe33-5f78-42f5-9a18-ed356898f133_677x413.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:413,&quot;width&quot;:677,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:38385,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350afe33-5f78-42f5-9a18-ed356898f133_677x413.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JmYN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350afe33-5f78-42f5-9a18-ed356898f133_677x413.png 424w, https://substackcdn.com/image/fetch/$s_!JmYN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350afe33-5f78-42f5-9a18-ed356898f133_677x413.png 848w, https://substackcdn.com/image/fetch/$s_!JmYN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350afe33-5f78-42f5-9a18-ed356898f133_677x413.png 1272w, https://substackcdn.com/image/fetch/$s_!JmYN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F350afe33-5f78-42f5-9a18-ed356898f133_677x413.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h3>&#9989; Completion Criteria</h3><p>You&#8217;ve successfully completed the project when:</p><ul><li><p>All scripts and Python files run end-to-end without errors</p></li><li><p><code>user_feature_store_py</code> populates correctly</p></li><li><p>Model trains successfully with visible coefficients</p></li><li><p>Scheduler triggers ETL automatically</p></li><li><p>You can explain every step (schema &#8594; ETL &#8594; model)</p></li></ul><div><hr></div><h3>&#128161; Bonus Challenges</h3><ul><li><p>Create an additional <strong>materialized view</strong> that aggregates daily revenue</p></li><li><p>Add a <strong>plot or visualization</strong> of average spend per city using Python</p></li><li><p>Build a <strong>Dockerfile</strong> to containerize the project</p></li><li><p>Deploy the PostgreSQL + ETL pipeline using <strong>Docker Compose</strong></p></li><li><p>Integrate with <strong>Grafana</strong> or <strong>Metabase</strong> for dashboard visualization</p></li></ul><div><hr></div><h2>&#129504; Learning Outcomes</h2><p>After completing this project, you&#8217;ll master:</p><ul><li><p><strong>SQL for AI &amp; Feature Engineering</strong></p></li><li><p><strong>Python + PostgreSQL ETL Automation</strong></p></li><li><p><strong>Data Cleaning and Quality Validation</strong></p></li><li><p><strong>Feature Store Design for ML Models</strong></p></li><li><p><strong>Automation and Scheduling Concepts</strong></p></li></ul><div><hr></div><h1>&#128216; Chapter 13 &#8212; PostgreSQL with Python (Integration)</h1><p>This chapter teaches how to connect PostgreSQL with Python, run SQL queries programmatically, perform CRUD operations, handle exceptions, and integrate with libraries like <strong>pandas</strong> for AI workflows.</p><p>Each concept is explained in <strong>layman&#8217;s terms</strong>, includes <strong>5+ runnable examples (with tables + data)</strong>, and ends with <strong>10 exercises</strong> for practice.</p><div><hr></div><h2>&#127919; Goal of This Chapter</h2><p>By the end of this chapter, you&#8217;ll learn how to:</p><ul><li><p>Connect Python to PostgreSQL</p></li><li><p>Run SQL commands (SELECT, INSERT, UPDATE, DELETE) from Python</p></li><li><p>Handle database transactions safely</p></li><li><p>Fetch and process query results in Python</p></li><li><p>Use pandas + SQLAlchemy for data analysis and ETL</p></li><li><p>Build mini real-world examples (AI data preparation, feature extraction)</p></li></ul><div><hr></div><h2>&#129504; 1. Introduction</h2><p>PostgreSQL is a <strong>database system</strong> that stores and manages data.<br>Python is a <strong>programming language</strong> that can <strong>talk</strong> to this database to insert, retrieve, and analyze data.</p><p>To connect them, we use <strong>connectors</strong> like:</p><ul><li><p><code>psycopg2</code> &#8212; The most popular PostgreSQL driver.</p></li><li><p><code>SQLAlchemy</code> &#8212; A high-level ORM (Object Relational Mapper).</p></li><li><p><code>pandas</code> &#8212; For data analysis and loading query results into DataFrames.</p></li></ul><div><hr></div><h2>&#129513; 2. Installing Dependencies</h2><p>Run these commands in your terminal:</p><pre><code><code>pip install psycopg2-binary sqlalchemy pandas
</code></code></pre><ul><li><p><strong>psycopg2-binary:</strong> For connecting and running SQL queries</p></li><li><p><strong>SQLAlchemy:</strong> For engine-based connections</p></li><li><p><strong>pandas:</strong> For loading SQL query results into dataframes</p></li></ul><div><hr></div><h2>&#129513; 3. Establishing Connection with psycopg2</h2><p>Here&#8217;s how you can connect Python to PostgreSQL.</p><h3>&#129521; Example 1 &#8212; Basic Connection Test</h3><pre><code><code>import psycopg2

try:
    conn = psycopg2.connect(
        host=&#8221;localhost&#8221;,
        database=&#8221;ai_course&#8221;,
        user=&#8221;postgres&#8221;,
        password=&#8221;password&#8221;
    )
    print(&#8221;&#9989; Connection successful!&#8221;)
    conn.close()
except Exception as e:
    print(&#8221;&#10060; Connection failed:&#8221;, e)
</code></code></pre><p><strong>Explanation:</strong><br>This code connects Python to PostgreSQL using your credentials and prints success or error messages.</p><div><hr></div><h2>&#129513; 4. Creating a Table from Python</h2><p>We can use Python to <strong>create tables</strong> dynamically.</p><h3>&#129521; Example 2 &#8212; Create Table &#8220;students&#8221;</h3><pre><code><code>import psycopg2

conn = psycopg2.connect(host=&#8221;localhost&#8221;, database=&#8221;ai_course&#8221;, user=&#8221;postgres&#8221;, password=&#8221;password&#8221;)
cur = conn.cursor()

cur.execute(&#8221;&#8220;&#8221;
CREATE TABLE IF NOT EXISTS students (
    id SERIAL PRIMARY KEY,
    name VARCHAR(50),
    age INT,
    marks NUMERIC(5,2)
)
&#8220;&#8221;&#8220;)
conn.commit()
print(&#8221;&#9989; Table created successfully&#8221;)

cur.close()
conn.close()
</code></code></pre><div><hr></div><h2>&#129513; 5. Inserting Data into Table</h2><p>We can insert data directly from Python using SQL commands.</p><h3>&#129521; Example 3 &#8212; Insert Records</h3><pre><code><code>import psycopg2

conn = psycopg2.connect(host=&#8221;localhost&#8221;, database=&#8221;ai_course&#8221;, user=&#8221;postgres&#8221;, password=&#8221;password&#8221;)
cur = conn.cursor()

data = [
    (&#8217;Alice&#8217;, 22, 88.5),
    (&#8217;Ben&#8217;, 24, 92.0),
    (&#8217;Carmen&#8217;, 21, 75.0)
]

for row in data:
    cur.execute(&#8221;INSERT INTO students (name, age, marks) VALUES (%s, %s, %s)&#8221;, row)

conn.commit()
print(&#8221;&#9989; Data inserted successfully&#8221;)

cur.close()
conn.close()
</code></code></pre><div><hr></div><h2>&#129513; 6. Fetching Data from PostgreSQL</h2><p>You can fetch data from PostgreSQL into Python using <code>fetchall()</code> or <code>fetchone()</code>.</p><h3>&#129521; Example 4 &#8212; Read All Data</h3><pre><code><code>import psycopg2

conn = psycopg2.connect(host=&#8221;localhost&#8221;, database=&#8221;ai_course&#8221;, user=&#8221;postgres&#8221;, password=&#8221;password&#8221;)
cur = conn.cursor()

cur.execute(&#8221;SELECT * FROM students&#8221;)
rows = cur.fetchall()

for row in rows:
    print(row)

cur.close()
conn.close()
</code></code></pre><p><strong>Output:</strong></p><pre><code><code>(1, &#8216;Alice&#8217;, 22, 88.5)
(2, &#8216;Ben&#8217;, 24, 92.0)
(3, &#8216;Carmen&#8217;, 21, 75.0)
</code></code></pre><div><hr></div><h2>&#129513; 7. Updating &amp; Deleting Records</h2><p>You can update and delete rows using Python queries.</p><h3>&#129521; Example 5 &#8212; Update Marks &amp; Delete Record</h3><pre><code><code>import psycopg2

conn = psycopg2.connect(host=&#8221;localhost&#8221;, database=&#8221;ai_course&#8221;, user=&#8221;postgres&#8221;, password=&#8221;password&#8221;)
cur = conn.cursor()

# Update
cur.execute(&#8221;UPDATE students SET marks = marks + 5 WHERE name = &#8216;Carmen&#8217;&#8221;)

# Delete
cur.execute(&#8221;DELETE FROM students WHERE name = &#8216;Ben&#8217;&#8221;)

conn.commit()
print(&#8221;&#9989; Updated and deleted successfully&#8221;)

cur.close()
conn.close()
</code></code></pre><div><hr></div><h2>&#129513; 8. Using Pandas to Query PostgreSQL</h2><p>You can load SQL results directly into a <strong>DataFrame</strong> using <code>pandas.read_sql()</code>.</p><h3>&#129521; Example 6 &#8212; Load Table into pandas</h3><pre><code><code>import pandas as pd
import psycopg2

conn = psycopg2.connect(host=&#8221;localhost&#8221;, database=&#8221;ai_course&#8221;, user=&#8221;postgres&#8221;, password=&#8221;password&#8221;)

df = pd.read_sql(&#8221;SELECT * FROM students&#8221;, conn)
print(df)

conn.close()
</code></code></pre><p><strong>Output:</strong></p><pre><code><code>   id   name  age  marks
0   1  Alice   22   88.5
1   3  Carmen  21   80.0
</code></code></pre><div><hr></div><h2>&#129513; 9. Using SQLAlchemy for Cleaner Code</h2><p>SQLAlchemy allows connection reuse and ORM-like access.</p><h3>&#129521; Example 7 &#8212; Using SQLAlchemy Engine</h3><pre><code><code>from sqlalchemy import create_engine
import pandas as pd

engine = create_engine(&#8221;postgresql://postgres:password@localhost:5432/ai_course&#8221;)

# Read
df = pd.read_sql(&#8221;SELECT * FROM students&#8221;, engine)
print(df)

# Write
new_data = pd.DataFrame({&#8217;name&#8217;: [&#8217;David&#8217;], &#8216;age&#8217;: [25], &#8216;marks&#8217;: [89.5]})
new_data.to_sql(&#8217;students&#8217;, engine, if_exists=&#8217;append&#8217;, index=False)
print(&#8221;&#9989; Inserted using pandas + SQLAlchemy&#8221;)
</code></code></pre><div><hr></div><h2>&#129513; 10. Using Python + PostgreSQL for AI Use Case</h2><p>Let&#8217;s simulate a <strong>mini AI data preparation example</strong>.</p><p>We&#8217;ll:</p><ul><li><p>Store customer purchase data</p></li><li><p>Calculate average spend per user</p></li><li><p>Export clean data for model training</p></li></ul><h3>&#129521; Example 8 &#8212; Mini AI Pipeline</h3><pre><code><code>from sqlalchemy import create_engine
import pandas as pd

engine = create_engine(&#8221;postgresql://postgres:password@localhost:5432/ai_course&#8221;)

# Create a table
with engine.connect() as conn:
    conn.execute(&#8221;&#8220;&#8221;
    CREATE TABLE IF NOT EXISTS orders (
        id SERIAL PRIMARY KEY,
        user_name TEXT,
        amount NUMERIC(8,2)
    )
    &#8220;&#8221;&#8220;)
    conn.execute(&#8221;INSERT INTO orders (user_name, amount) VALUES (&#8217;Alice&#8217;,100),(&#8217;Alice&#8217;,150),(&#8217;Ben&#8217;,200),(&#8217;Carmen&#8217;,50)&#8221;)
    conn.commit()

# Load into pandas
df = pd.read_sql(&#8221;SELECT user_name, AVG(amount) as avg_spend, SUM(amount) as total_spend FROM orders GROUP BY user_name&#8221;, engine)

print(df)
</code></code></pre><p><strong>Output:</strong></p><pre><code><code>  user_name  avg_spend  total_spend
0     Alice      125.0        250.0
1       Ben      200.0        200.0
2    Carmen       50.0         50.0
</code></code></pre><div><hr></div><h2>&#129504; 11. Handling Exceptions and Transactions</h2><p>Always use <strong>try-except-finally</strong> to avoid connection leaks.</p><h3>&#129521; Example 9 &#8212; Error Handling</h3><pre><code><code>import psycopg2

try:
    conn = psycopg2.connect(host=&#8221;localhost&#8221;, database=&#8221;ai_course&#8221;, user=&#8221;postgres&#8221;, password=&#8221;wrongpass&#8221;)
    cur = conn.cursor()
    cur.execute(&#8221;SELECT * FROM students&#8221;)
    print(cur.fetchall())
except Exception as e:
    print(&#8221;&#10060; Something went wrong:&#8221;, e)
finally:
    if conn:
        conn.close()
</code></code></pre><div><hr></div><h2>&#129513; 12. Real-World Data Integration Flow</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!r_Mg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ade193b-cde9-45f2-9cf3-615f6a2e6c32_722x280.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!r_Mg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ade193b-cde9-45f2-9cf3-615f6a2e6c32_722x280.png 424w, https://substackcdn.com/image/fetch/$s_!r_Mg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ade193b-cde9-45f2-9cf3-615f6a2e6c32_722x280.png 848w, https://substackcdn.com/image/fetch/$s_!r_Mg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ade193b-cde9-45f2-9cf3-615f6a2e6c32_722x280.png 1272w, https://substackcdn.com/image/fetch/$s_!r_Mg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ade193b-cde9-45f2-9cf3-615f6a2e6c32_722x280.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!r_Mg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ade193b-cde9-45f2-9cf3-615f6a2e6c32_722x280.png" width="722" height="280" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7ade193b-cde9-45f2-9cf3-615f6a2e6c32_722x280.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:280,&quot;width&quot;:722,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:18678,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ade193b-cde9-45f2-9cf3-615f6a2e6c32_722x280.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!r_Mg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ade193b-cde9-45f2-9cf3-615f6a2e6c32_722x280.png 424w, https://substackcdn.com/image/fetch/$s_!r_Mg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ade193b-cde9-45f2-9cf3-615f6a2e6c32_722x280.png 848w, https://substackcdn.com/image/fetch/$s_!r_Mg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ade193b-cde9-45f2-9cf3-615f6a2e6c32_722x280.png 1272w, https://substackcdn.com/image/fetch/$s_!r_Mg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ade193b-cde9-45f2-9cf3-615f6a2e6c32_722x280.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129504; 13. Summary</h2><p>&#9989; PostgreSQL and Python work hand-in-hand for AI and data analytics.<br>&#9989; You can connect, query, clean, and transform SQL data in Python seamlessly.<br>&#9989; This integration forms the <strong>backbone of AI Data Pipelines</strong>.</p><div><hr></div><h2>&#129513; 14. Exercises</h2><p>Try these for hands-on practice:</p><ol><li><p>Create a new table <code>employees (id, name, dept, salary)</code> and insert 5 records.</p></li><li><p>Fetch only employees earning above a certain salary using Python.</p></li><li><p>Write a Python function that accepts user input and inserts data.</p></li><li><p>Write a query to find average salary per department.</p></li><li><p>Update all salaries by +10% using Python.</p></li><li><p>Delete employees with salary &lt; 50000.</p></li><li><p>Fetch all rows into a pandas DataFrame.</p></li><li><p>Export DataFrame results to a CSV file using <code>df.to_csv()</code>.</p></li><li><p>Handle invalid connections using try-except.</p></li><li><p>Create a simple dashboard (print stats) of department-wise salary spend.</p></li></ol><div><hr></div><h1>&#128216; Chapter 14 &#8212; Data Warehousing &amp; Analytical Extensions</h1><div><hr></div><h2>&#127919; Goal of This Chapter</h2><p>By the end of this chapter, you will learn:</p><p>&#9989; What a Data Warehouse is and how PostgreSQL can act as one<br>&#9989; How to use advanced PostgreSQL features for analytics (CTEs, Materialized Views, Partitions, Window Functions)<br>&#9989; How to design <strong>star and snowflake schemas</strong><br>&#9989; How to build and optimize <strong>analytical queries</strong><br>&#9989; How to use <strong>extensions</strong> like <code>cube</code>, <code>tablefunc</code>, and <code>pg_partman</code> for analytics<br>&#9989; How to prepare aggregated data for <strong>AI/BI tools</strong> (Power BI, Tableau, Looker)</p><div><hr></div><h2>&#129504; 1. What Is a Data Warehouse?</h2><p>A <strong>Data Warehouse (DW)</strong> is a <strong>central storage system</strong> used for analysis and reporting &#8212; not for frequent updates.</p><p>It&#8217;s different from a transactional database (OLTP).</p><p>Type Purpose Example OLTP Stores live, transactional data eCommerce order DB OLAP / DW Stores aggregated, historical data Reporting, analytics, AI model data</p><p>In AI/ML workflows, you typically:</p><ol><li><p><strong>Extract</strong> raw data from sources</p></li><li><p><strong>Transform</strong> it (clean, aggregate, enrich)</p></li><li><p><strong>Load</strong> into the warehouse</p></li><li><p><strong>Query</strong> for analytics or feature generation</p></li></ol><p>PostgreSQL can do all this!</p><div><hr></div><h2>&#129513; 2. PostgreSQL as a Data Warehouse</h2><p>PostgreSQL supports:</p><ul><li><p><strong>Indexes</strong> for fast queries</p></li><li><p><strong>Materialized views</strong> for snapshots</p></li><li><p><strong>CTEs</strong> and <strong>window functions</strong> for analytics</p></li><li><p><strong>Partitioning</strong> for large datasets</p></li><li><p><strong>Extensions</strong> for advanced aggregation</p></li></ul><p>Let&#8217;s simulate a small <strong>Retail Data Warehouse</strong>.</p><div><hr></div><h2>&#129521; Example Schema: Retail Analytics</h2><pre><code><code>-- Drop existing tables
DROP TABLE IF EXISTS sales, customers, products CASCADE;

-- Dimension Tables
CREATE TABLE customers (
    customer_id SERIAL PRIMARY KEY,
    name TEXT,
    city TEXT,
    signup_date DATE
);

CREATE TABLE products (
    product_id SERIAL PRIMARY KEY,
    product_name TEXT,
    category TEXT,
    price NUMERIC(8,2)
);

-- Fact Table
CREATE TABLE sales (
    sale_id SERIAL PRIMARY KEY,
    customer_id INT REFERENCES customers(customer_id),
    product_id INT REFERENCES products(product_id),
    quantity INT,
    sale_date DATE
);
</code></code></pre><div><hr></div><h2>&#129513; 3. Insert Sample Data</h2><pre><code><code>INSERT INTO customers (name, city, signup_date) VALUES
(&#8217;Alice&#8217;,&#8217;Paris&#8217;,&#8217;2024-01-10&#8217;),
(&#8217;Ben&#8217;,&#8217;London&#8217;,&#8217;2024-01-15&#8217;),
(&#8217;Carmen&#8217;,&#8217;Paris&#8217;,&#8217;2024-02-01&#8217;),
(&#8217;David&#8217;,&#8217;Berlin&#8217;,&#8217;2024-02-05&#8217;);

INSERT INTO products (product_name, category, price) VALUES
(&#8217;Laptop&#8217;,&#8217;Electronics&#8217;,1200),
(&#8217;Phone&#8217;,&#8217;Electronics&#8217;,800),
(&#8217;Shoes&#8217;,&#8217;Fashion&#8217;,150),
(&#8217;Watch&#8217;,&#8217;Fashion&#8217;,300);

INSERT INTO sales (customer_id, product_id, quantity, sale_date) VALUES
(1,1,1,&#8217;2024-02-10&#8217;),
(1,3,2,&#8217;2024-02-15&#8217;),
(2,2,1,&#8217;2024-02-12&#8217;),
(3,4,1,&#8217;2024-02-14&#8217;),
(4,3,3,&#8217;2024-02-15&#8217;);
</code></code></pre><div><hr></div><h2>&#129504; 4. Star Schema Design</h2><p>Your <strong>fact table (sales)</strong> links to dimension tables <strong>(customers, products)</strong>.</p><p>Visually:</p><pre><code><code>       customers        products
           \              /
            \            /
             \          /
              \        /
               \      /
                 sales (fact)
</code></code></pre><p>This is a <strong>Star Schema</strong>, ideal for analytical queries and AI feature generation.</p><div><hr></div><h2>&#129513; 5. Analytical Queries</h2><p>Let&#8217;s see how PostgreSQL can be used like a warehouse:</p><h3>&#129521; Example 1 &#8212; Total Sales by City</h3><pre><code><code>SELECT c.city, SUM(p.price * s.quantity) AS total_sales
FROM sales s
JOIN customers c ON s.customer_id = c.customer_id
JOIN products p ON s.product_id = p.product_id
GROUP BY c.city;
</code></code></pre><p><strong>Result:</strong></p><p>city total_sales Paris 1650 London 800 Berlin 450</p><div><hr></div><h3>&#129521; Example 2 &#8212; Top-Selling Product Category</h3><pre><code><code>SELECT p.category, SUM(s.quantity) AS total_quantity
FROM sales s
JOIN products p ON s.product_id = p.product_id
GROUP BY p.category
ORDER BY total_quantity DESC;
</code></code></pre><p><strong>Result:</strong></p><p>category total_quantity Fashion 6 Electronics 2</p><div><hr></div><h3>&#129521; Example 3 &#8212; Monthly Revenue Trend</h3><pre><code><code>SELECT DATE_TRUNC(&#8217;month&#8217;, sale_date) AS month, 
       SUM(p.price * s.quantity) AS total_revenue
FROM sales s
JOIN products p ON s.product_id = p.product_id
GROUP BY month
ORDER BY month;
</code></code></pre><div><hr></div><h3>&#129521; Example 4 &#8212; Cumulative Revenue (Window Function)</h3><pre><code><code>SELECT 
    DATE_TRUNC(&#8217;month&#8217;, sale_date) AS month,
    SUM(p.price * s.quantity) AS monthly_revenue,
    SUM(SUM(p.price * s.quantity)) OVER (ORDER BY DATE_TRUNC(&#8217;month&#8217;, sale_date)) AS cumulative_revenue
FROM sales s
JOIN products p ON s.product_id = p.product_id
GROUP BY month
ORDER BY month;
</code></code></pre><div><hr></div><h2>&#129513; 6. Materialized Views for Precomputed Analytics</h2><p>Materialized views store snapshots of results &#8212; great for dashboards.</p><pre><code><code>CREATE MATERIALIZED VIEW city_sales_summary AS
SELECT c.city, SUM(p.price * s.quantity) AS total_sales
FROM sales s
JOIN customers c ON s.customer_id = c.customer_id
JOIN products p ON s.product_id = p.product_id
GROUP BY c.city;

-- Refresh manually
REFRESH MATERIALIZED VIEW city_sales_summary;
SELECT * FROM city_sales_summary;
</code></code></pre><div><hr></div><h2>&#129513; 7. Using Partitioning for Performance</h2><p>Partitioning improves performance on large datasets.</p><h3>&#129521; Example &#8212; Partition Sales by Month</h3><pre><code><code>CREATE TABLE sales_partitioned (
    sale_id SERIAL,
    customer_id INT,
    product_id INT,
    quantity INT,
    sale_date DATE
) PARTITION BY RANGE (sale_date);

CREATE TABLE sales_2024_01 PARTITION OF sales_partitioned
FOR VALUES FROM (&#8217;2024-01-01&#8217;) TO (&#8217;2024-02-01&#8217;);

CREATE TABLE sales_2024_02 PARTITION OF sales_partitioned
FOR VALUES FROM (&#8217;2024-02-01&#8217;) TO (&#8217;2024-03-01&#8217;);
</code></code></pre><p><strong>Now:</strong><br>When you query by <code>WHERE sale_date BETWEEN ...</code>, PostgreSQL scans only relevant partitions.</p><div><hr></div><h2>&#129513; 8. Analytical Extensions</h2><p>PostgreSQL supports several <strong>extensions</strong> that make it behave like a true analytical engine.</p><h3>&#129521; Example 1 &#8212; <code>cube</code> Extension (for Multidimensional Aggregation)</h3><pre><code><code>CREATE EXTENSION IF NOT EXISTS cube;
CREATE EXTENSION IF NOT EXISTS earthdistance;
</code></code></pre><p><strong>Use Case:</strong> Geographic distance calculations, multi-dimensional grouping (great for BI and ML features).</p><div><hr></div><h3>&#129521; Example 2 &#8212; <code>tablefunc</code> (Pivot Tables)</h3><pre><code><code>CREATE EXTENSION IF NOT EXISTS tablefunc;

SELECT * FROM crosstab(
  &#8216;SELECT city, category, SUM(price * quantity)
   FROM sales s
   JOIN customers c ON s.customer_id=c.customer_id
   JOIN products p ON s.product_id=p.product_id
   GROUP BY city, category
   ORDER BY city&#8217;,
  &#8216;SELECT DISTINCT category FROM products ORDER BY category&#8217;
) AS pivot(city TEXT, electronics NUMERIC, fashion NUMERIC);
</code></code></pre><p>This transforms data into a <strong>pivot table</strong> (like Excel / Power BI).</p><div><hr></div><h3>&#129521; Example 3 &#8212; <code>pg_partman</code> for Automatic Partition Management</h3><p>Install:</p><pre><code><code>CREATE EXTENSION IF NOT EXISTS pg_partman;
</code></code></pre><p>It automatically creates time-based partitions (daily/monthly).<br>Example: great for IoT or AI time series data pipelines.</p><div><hr></div><h2>&#129513; 9. Aggregation and Feature Store Use Case</h2><p>In AI projects, we often convert raw tables into <strong>aggregated features</strong> (a mini feature store).</p><h3>&#129521; Example &#8212; Customer Feature Summary</h3><pre><code><code>CREATE VIEW customer_features AS
SELECT 
    c.customer_id,
    c.city,
    COUNT(s.sale_id) AS total_orders,
    SUM(p.price * s.quantity) AS total_spend,
    ROUND(AVG(p.price * s.quantity),2) AS avg_order_value,
    MAX(s.sale_date) AS last_order_date
FROM sales s
JOIN customers c ON s.customer_id = c.customer_id
JOIN products p ON s.product_id = p.product_id
GROUP BY c.customer_id, c.city;
</code></code></pre><p>Now this <code>customer_features</code> view can directly feed <strong>Python ML models</strong> for churn prediction or segmentation.</p><div><hr></div><h2>&#129504; 10. Data Warehouse Summary Query Patterns</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3ZAr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c173151-dc68-477e-9cf4-e4e1c5e82c54_719x350.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3ZAr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c173151-dc68-477e-9cf4-e4e1c5e82c54_719x350.png 424w, https://substackcdn.com/image/fetch/$s_!3ZAr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c173151-dc68-477e-9cf4-e4e1c5e82c54_719x350.png 848w, https://substackcdn.com/image/fetch/$s_!3ZAr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c173151-dc68-477e-9cf4-e4e1c5e82c54_719x350.png 1272w, https://substackcdn.com/image/fetch/$s_!3ZAr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c173151-dc68-477e-9cf4-e4e1c5e82c54_719x350.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3ZAr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c173151-dc68-477e-9cf4-e4e1c5e82c54_719x350.png" width="719" height="350" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1c173151-dc68-477e-9cf4-e4e1c5e82c54_719x350.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:350,&quot;width&quot;:719,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:30424,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c173151-dc68-477e-9cf4-e4e1c5e82c54_719x350.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3ZAr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c173151-dc68-477e-9cf4-e4e1c5e82c54_719x350.png 424w, https://substackcdn.com/image/fetch/$s_!3ZAr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c173151-dc68-477e-9cf4-e4e1c5e82c54_719x350.png 848w, https://substackcdn.com/image/fetch/$s_!3ZAr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c173151-dc68-477e-9cf4-e4e1c5e82c54_719x350.png 1272w, https://substackcdn.com/image/fetch/$s_!3ZAr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1c173151-dc68-477e-9cf4-e4e1c5e82c54_719x350.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129513; 11. Exercises</h2><p>Practice these to master PostgreSQL Data Warehousing:</p><ol><li><p>Create a new table <code>returns (sale_id, return_date, reason)</code> and join with <code>sales</code> to calculate return rate.</p></li><li><p>Create a <strong>daily revenue materialized view</strong> and refresh it.</p></li><li><p>Use a <strong>window function</strong> to calculate 7-day rolling average sales.</p></li><li><p>Partition the <code>sales</code> table by city.</p></li><li><p>Build a <strong>pivot table</strong> showing sales per category per city.</p></li><li><p>Use <code>DATE_TRUNC()</code> to build a monthly sales trend report.</p></li><li><p>Add a <strong>feature view</strong> showing customer recency (<code>days_since_last_order</code>).</p></li><li><p>Integrate with Python using pandas to load aggregated tables.</p></li><li><p>Compare performance between partitioned vs non-partitioned tables.</p></li><li><p>Export analytical query results to a CSV for Power BI.</p></li></ol><div><hr></div><h2>&#129534; Summary</h2><p>&#9989; PostgreSQL can be used as a full-featured <strong>analytical warehouse</strong>.<br>&#9989; Materialized Views, Window Functions, and Extensions power advanced AI pipelines.<br>&#9989; You can store <strong>aggregated, historical, and computed features</strong> directly in PostgreSQL.<br>&#9989; Python and BI tools can consume these features for <strong>dashboards or AI models</strong>.</p><div><hr></div><h3></h3><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!leLA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e40183e-00c9-45c1-a67d-27d1807236bc_842x1000.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!leLA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e40183e-00c9-45c1-a67d-27d1807236bc_842x1000.png 424w, https://substackcdn.com/image/fetch/$s_!leLA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e40183e-00c9-45c1-a67d-27d1807236bc_842x1000.png 848w, https://substackcdn.com/image/fetch/$s_!leLA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e40183e-00c9-45c1-a67d-27d1807236bc_842x1000.png 1272w, https://substackcdn.com/image/fetch/$s_!leLA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e40183e-00c9-45c1-a67d-27d1807236bc_842x1000.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!leLA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e40183e-00c9-45c1-a67d-27d1807236bc_842x1000.png" width="842" height="1000" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9e40183e-00c9-45c1-a67d-27d1807236bc_842x1000.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1000,&quot;width&quot;:842,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:243965,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e40183e-00c9-45c1-a67d-27d1807236bc_842x1000.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!leLA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e40183e-00c9-45c1-a67d-27d1807236bc_842x1000.png 424w, https://substackcdn.com/image/fetch/$s_!leLA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e40183e-00c9-45c1-a67d-27d1807236bc_842x1000.png 848w, https://substackcdn.com/image/fetch/$s_!leLA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e40183e-00c9-45c1-a67d-27d1807236bc_842x1000.png 1272w, https://substackcdn.com/image/fetch/$s_!leLA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e40183e-00c9-45c1-a67d-27d1807236bc_842x1000.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h1>&#127937; PostgreSQL for AI/Data/ML &#8211; Course Summary &amp; Certification Guide</h1><div><hr></div><h2>&#127891; Course Overview</h2><p>This comprehensive 14-chapter program transforms learners from <strong>SQL beginners</strong> into <strong>PostgreSQL professionals</strong> ready for AI and Data Engineering roles.</p><p>Through this journey, you&#8217;ve covered:</p><ul><li><p>Core SQL fundamentals</p></li><li><p>Analytical and AI-driven queries</p></li><li><p>Feature engineering concepts</p></li><li><p>Integration with Python</p></li><li><p>Data warehousing and performance optimization</p></li></ul><p>Each topic was built progressively &#8212; connecting <strong>real-world data</strong>, <strong>AI problem-solving</strong>, and <strong>hands-on coding</strong> that works out of the box.</p><div><hr></div><h2>&#129517; Full Course Path (All 14 Chapters)</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Boi4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e81d69-f1a7-44f6-a806-793ea5a7cd4d_793x880.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Boi4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e81d69-f1a7-44f6-a806-793ea5a7cd4d_793x880.png 424w, https://substackcdn.com/image/fetch/$s_!Boi4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e81d69-f1a7-44f6-a806-793ea5a7cd4d_793x880.png 848w, https://substackcdn.com/image/fetch/$s_!Boi4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e81d69-f1a7-44f6-a806-793ea5a7cd4d_793x880.png 1272w, https://substackcdn.com/image/fetch/$s_!Boi4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e81d69-f1a7-44f6-a806-793ea5a7cd4d_793x880.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Boi4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e81d69-f1a7-44f6-a806-793ea5a7cd4d_793x880.png" width="793" height="880" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27e81d69-f1a7-44f6-a806-793ea5a7cd4d_793x880.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:880,&quot;width&quot;:793,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:78192,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e81d69-f1a7-44f6-a806-793ea5a7cd4d_793x880.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Boi4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e81d69-f1a7-44f6-a806-793ea5a7cd4d_793x880.png 424w, https://substackcdn.com/image/fetch/$s_!Boi4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e81d69-f1a7-44f6-a806-793ea5a7cd4d_793x880.png 848w, https://substackcdn.com/image/fetch/$s_!Boi4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e81d69-f1a7-44f6-a806-793ea5a7cd4d_793x880.png 1272w, https://substackcdn.com/image/fetch/$s_!Boi4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e81d69-f1a7-44f6-a806-793ea5a7cd4d_793x880.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#128202; Real-World Skills You&#8217;ve Gained</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Z8Yt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e1ca07d-6d90-4ec8-a54c-d7a71f90a48b_707x491.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Z8Yt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e1ca07d-6d90-4ec8-a54c-d7a71f90a48b_707x491.png 424w, https://substackcdn.com/image/fetch/$s_!Z8Yt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e1ca07d-6d90-4ec8-a54c-d7a71f90a48b_707x491.png 848w, https://substackcdn.com/image/fetch/$s_!Z8Yt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e1ca07d-6d90-4ec8-a54c-d7a71f90a48b_707x491.png 1272w, https://substackcdn.com/image/fetch/$s_!Z8Yt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e1ca07d-6d90-4ec8-a54c-d7a71f90a48b_707x491.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Z8Yt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e1ca07d-6d90-4ec8-a54c-d7a71f90a48b_707x491.png" width="707" height="491" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6e1ca07d-6d90-4ec8-a54c-d7a71f90a48b_707x491.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:491,&quot;width&quot;:707,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:49254,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e1ca07d-6d90-4ec8-a54c-d7a71f90a48b_707x491.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Z8Yt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e1ca07d-6d90-4ec8-a54c-d7a71f90a48b_707x491.png 424w, https://substackcdn.com/image/fetch/$s_!Z8Yt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e1ca07d-6d90-4ec8-a54c-d7a71f90a48b_707x491.png 848w, https://substackcdn.com/image/fetch/$s_!Z8Yt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e1ca07d-6d90-4ec8-a54c-d7a71f90a48b_707x491.png 1272w, https://substackcdn.com/image/fetch/$s_!Z8Yt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e1ca07d-6d90-4ec8-a54c-d7a71f90a48b_707x491.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129513; Project Recap &#8211; ShopAI Data Pipeline</h2><p>You built (and/or debugged) a complete <strong>ShopAI Project</strong> integrating:</p><ul><li><p><strong>PostgreSQL schema design</strong></p></li><li><p><strong>ETL automation with Python</strong></p></li><li><p><strong>Feature store creation</strong></p></li><li><p><strong>Machine learning model integration</strong></p></li><li><p><strong>Scheduler for daily data refresh</strong></p></li></ul><p>This mirrors real-world AI pipelines used by data engineers and MLOps teams.</p><div><hr></div><h2>&#128216; Recommended Tools for Post-Certification Practice</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DUDv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5190834e-e880-467c-bfce-cb856f7226e7_593x354.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DUDv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5190834e-e880-467c-bfce-cb856f7226e7_593x354.png 424w, https://substackcdn.com/image/fetch/$s_!DUDv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5190834e-e880-467c-bfce-cb856f7226e7_593x354.png 848w, https://substackcdn.com/image/fetch/$s_!DUDv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5190834e-e880-467c-bfce-cb856f7226e7_593x354.png 1272w, https://substackcdn.com/image/fetch/$s_!DUDv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5190834e-e880-467c-bfce-cb856f7226e7_593x354.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DUDv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5190834e-e880-467c-bfce-cb856f7226e7_593x354.png" width="593" height="354" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5190834e-e880-467c-bfce-cb856f7226e7_593x354.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:354,&quot;width&quot;:593,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:23059,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5190834e-e880-467c-bfce-cb856f7226e7_593x354.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DUDv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5190834e-e880-467c-bfce-cb856f7226e7_593x354.png 424w, https://substackcdn.com/image/fetch/$s_!DUDv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5190834e-e880-467c-bfce-cb856f7226e7_593x354.png 848w, https://substackcdn.com/image/fetch/$s_!DUDv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5190834e-e880-467c-bfce-cb856f7226e7_593x354.png 1272w, https://substackcdn.com/image/fetch/$s_!DUDv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5190834e-e880-467c-bfce-cb856f7226e7_593x354.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129504; AI Career Application Areas</h2><p>After mastering this course, you can confidently handle:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iUrw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd57de03e-2365-46c5-959f-1cb1d07b3cf6_641x313.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iUrw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd57de03e-2365-46c5-959f-1cb1d07b3cf6_641x313.png 424w, https://substackcdn.com/image/fetch/$s_!iUrw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd57de03e-2365-46c5-959f-1cb1d07b3cf6_641x313.png 848w, https://substackcdn.com/image/fetch/$s_!iUrw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd57de03e-2365-46c5-959f-1cb1d07b3cf6_641x313.png 1272w, https://substackcdn.com/image/fetch/$s_!iUrw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd57de03e-2365-46c5-959f-1cb1d07b3cf6_641x313.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iUrw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd57de03e-2365-46c5-959f-1cb1d07b3cf6_641x313.png" width="641" height="313" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d57de03e-2365-46c5-959f-1cb1d07b3cf6_641x313.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:313,&quot;width&quot;:641,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:30612,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd57de03e-2365-46c5-959f-1cb1d07b3cf6_641x313.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iUrw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd57de03e-2365-46c5-959f-1cb1d07b3cf6_641x313.png 424w, https://substackcdn.com/image/fetch/$s_!iUrw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd57de03e-2365-46c5-959f-1cb1d07b3cf6_641x313.png 848w, https://substackcdn.com/image/fetch/$s_!iUrw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd57de03e-2365-46c5-959f-1cb1d07b3cf6_641x313.png 1272w, https://substackcdn.com/image/fetch/$s_!iUrw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd57de03e-2365-46c5-959f-1cb1d07b3cf6_641x313.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#129534; Certification Checklist</h2><p>Before issuing your course completion certificate, ensure the learner has completed these 10 verifiable checkpoints:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iXiJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00daabfe-9874-4e57-b18a-62165ead6e97_734x495.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iXiJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00daabfe-9874-4e57-b18a-62165ead6e97_734x495.png 424w, https://substackcdn.com/image/fetch/$s_!iXiJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00daabfe-9874-4e57-b18a-62165ead6e97_734x495.png 848w, https://substackcdn.com/image/fetch/$s_!iXiJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00daabfe-9874-4e57-b18a-62165ead6e97_734x495.png 1272w, https://substackcdn.com/image/fetch/$s_!iXiJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00daabfe-9874-4e57-b18a-62165ead6e97_734x495.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iXiJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00daabfe-9874-4e57-b18a-62165ead6e97_734x495.png" width="734" height="495" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/00daabfe-9874-4e57-b18a-62165ead6e97_734x495.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:495,&quot;width&quot;:734,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:54263,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175359630?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00daabfe-9874-4e57-b18a-62165ead6e97_734x495.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iXiJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00daabfe-9874-4e57-b18a-62165ead6e97_734x495.png 424w, https://substackcdn.com/image/fetch/$s_!iXiJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00daabfe-9874-4e57-b18a-62165ead6e97_734x495.png 848w, https://substackcdn.com/image/fetch/$s_!iXiJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00daabfe-9874-4e57-b18a-62165ead6e97_734x495.png 1272w, https://substackcdn.com/image/fetch/$s_!iXiJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00daabfe-9874-4e57-b18a-62165ead6e97_734x495.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>&#127942; Certification Template (Example)</h2><pre><code><code>-----------------------------------------------
&#127891; CareerByteCode | PostgreSQL for AI/Data/ML

This certifies that ___________________________
has successfully completed the 14-Chapter 
PostgreSQL for AI/Data/ML Program.

Skills Acquired:
&#10004; SQL Querying and Optimization
&#10004; Data Cleaning and Transformation
&#10004; Python Integration
&#10004; Feature Engineering
&#10004; Data Warehousing &amp; ETL Automation

Date of Completion: ___________________________
Authorized by: ________________________________

CareerByteCode | Building AI-Ready Data Engineers
-----------------------------------------------
</code></code></pre><div><hr></div><h2>&#128172; Suggested Next Step (After This Course)</h2><p>Once learners complete this PostgreSQL track, they can continue into:</p><ol><li><p><strong>Python for AI &amp; Data Science (50 Projects Series)</strong></p></li><li><p><strong>Building Real-Time Data Pipelines with Airflow + PostgreSQL</strong></p></li><li><p><strong>MLOps Foundations: Deploying AI Pipelines on Cloud (AWS/Azure)</strong></p></li><li><p><strong>Power BI / Tableau Visualization with PostgreSQL Backends</strong></p></li></ol><div><hr></div><h2>&#129517; Final Words</h2><p>&#127919; You&#8217;ve built a rock-solid foundation in <strong>PostgreSQL for AI and Data Engineering</strong>.<br>You now understand <strong>how to query, clean, model, and automate</strong> your data pipeline.</p><p>This knowledge bridges SQL and AI &#8212; empowering you to move confidently into <strong>Data Science, AI Engineering, or MLOps roles</strong>.</p><blockquote><p><em>&#8220;The strongest AI models are built on clean, structured, and well-engineered data &#8212; and that&#8217;s exactly what you now know how to create.&#8221;</em></p></blockquote><div><hr></div><p>&#9989; <strong>Congratulations &#8212; You&#8217;ve Completed the Full PostgreSQL for AI/Data/ML Program!</strong></p>]]></content:encoded></item><item><title><![CDATA[Master Kubernetes the Easy Way: Introduction to Helm for Beginners]]></title><description><![CDATA[Why Every DevOps Engineer Must Learn Helm]]></description><link>https://careerbytecode.substack.com/p/master-kubernetes-the-easy-way-introduction-to-helm-for-beginners</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/master-kubernetes-the-easy-way-introduction-to-helm-for-beginners</guid><dc:creator><![CDATA[CareerByteCode]]></dc:creator><pubDate>Thu, 02 Oct 2025 19:37:15 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!j3ok!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a644d14-a115-4970-8fe1-3475cb79e965_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!j3ok!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a644d14-a115-4970-8fe1-3475cb79e965_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!j3ok!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a644d14-a115-4970-8fe1-3475cb79e965_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!j3ok!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a644d14-a115-4970-8fe1-3475cb79e965_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!j3ok!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a644d14-a115-4970-8fe1-3475cb79e965_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!j3ok!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a644d14-a115-4970-8fe1-3475cb79e965_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!j3ok!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a644d14-a115-4970-8fe1-3475cb79e965_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2a644d14-a115-4970-8fe1-3475cb79e965_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:210006,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/175134649?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a644d14-a115-4970-8fe1-3475cb79e965_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!j3ok!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a644d14-a115-4970-8fe1-3475cb79e965_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!j3ok!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a644d14-a115-4970-8fe1-3475cb79e965_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!j3ok!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a644d14-a115-4970-8fe1-3475cb79e965_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!j3ok!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a644d14-a115-4970-8fe1-3475cb79e965_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h1>&#128216; <strong>Helm for Kubernetes &#8211; Course Syllabus</strong></h1><div><hr></div><h2><strong>Course Overview</strong></h2><p>Helm is the <strong>package manager for Kubernetes</strong>. It simplifies deploying, upgrading, and managing complex applications on Kubernetes. This course provides a <strong>hands-on, structured learning path</strong> &#8212; starting from basics, then moving to <strong>chart creation, customization, best practices, and real-world deployments in Azure AKS</strong>.</p><div><hr></div><h2><strong>Learning Objectives</strong></h2><p>By the end of this course, students will be able to:<br>&#9989; Understand what Helm is and why it is used in Kubernetes.<br>&#9989; Install and configure Helm in different environments.<br>&#9989; Explore the structure of Helm charts and how they work.<br>&#9989; Create custom Helm charts from scratch.<br>&#9989; Manage releases: install, upgrade, rollback, and uninstall.<br>&#9989; Customize charts for Dev, Staging, and Production environments.<br>&#9989; Apply best practices for Helm chart development.<br>&#9989; Use Helm advanced templating functions for dynamic manifests.<br>&#9989; Deploy real-world projects in Kubernetes using Helm.<br>&#9989; Integrate Helm with CI/CD pipelines and GitOps tools.</p><div><hr></div><h2><strong>Target Audience</strong></h2><ul><li><p>DevOps Engineers</p></li><li><p>Cloud Administrators</p></li><li><p>Developers working with Kubernetes</p></li><li><p>Students preparing for <strong>Cloud &amp; DevOps interviews</strong></p></li></ul><div><hr></div><h2><strong>Prerequisites</strong></h2><ul><li><p>Basic understanding of Kubernetes (pods, deployments, services).</p></li><li><p>Familiarity with YAML.</p></li><li><p>Access to a Kubernetes cluster (e.g., Minikube, Kind, or Azure AKS).</p></li></ul><div><hr></div><h2><strong>Course Modules</strong></h2><div><hr></div><h3><strong>Module 1: Introduction to Helm</strong></h3><ul><li><p>What is Helm?</p></li><li><p>Why use Helm in Kubernetes?</p></li><li><p>Helm vs Kubernetes manifests</p></li><li><p>Key concepts: <strong>Chart, Values, Release, Repository</strong></p></li><li><p>Hands-on: Deploy Nginx using a Helm chart</p></li></ul><div><hr></div><h3><strong>Module 2: Installing &amp; Configuring Helm</strong></h3><ul><li><p>Installing Helm on Linux, Windows, macOS</p></li><li><p>Setting up Helm in Azure Cloud Shell</p></li><li><p>Adding and updating repositories</p></li><li><p>Verifying Helm installation</p></li><li><p>Hands-on: Install Bitnami Nginx chart</p></li></ul><div><hr></div><h3><strong>Module 3: Exploring Helm Chart Structure</strong></h3><ul><li><p>Anatomy of a chart: <code>Chart.yaml</code>, <code>values.yaml</code>, <code>templates/</code>, <code>_helpers.tpl</code></p></li><li><p>Understanding templating basics (<code>{{ .Values }}</code>)</p></li><li><p>Editing default chart values</p></li><li><p>Hands-on: Create a chart and explore its files</p></li></ul><div><hr></div><h3><strong>Module 4: Creating Your First Helm Chart</strong></h3><ul><li><p>Helm create command</p></li><li><p>Writing <code>deployment.yaml</code> with values</p></li><li><p>Writing <code>service.yaml</code> with values</p></li><li><p>Adding dependencies (MySQL, Redis)</p></li><li><p>Hands-on: Create a chart for Nginx + MySQL</p></li></ul><div><hr></div><h3><strong>Module 5: Deploying &amp; Managing Releases</strong></h3><ul><li><p>Installing a release</p></li><li><p>Upgrading a release (new values, new image tag)</p></li><li><p>Rolling back to previous version</p></li><li><p>Managing releases across namespaces</p></li><li><p>Hands-on: Multiple releases for Dev/Prod</p></li></ul><div><hr></div><h3><strong>Module 6: Customizing Helm Charts</strong></h3><ul><li><p>Using <code>values-dev.yaml</code>, <code>values-prod.yaml</code></p></li><li><p>Overriding values from CLI (<code>--set</code>, <code>-f</code>)</p></li><li><p>Secrets and ConfigMaps with Helm</p></li><li><p>Ingress rules per environment</p></li><li><p>Autoscaling with Helm charts</p></li><li><p>Hands-on: Deploy app with different configs in Dev/Prod</p></li></ul><div><hr></div><h3><strong>Module 7: Best Practices for Helm Development</strong></h3><ul><li><p>Chart linting (<code>helm lint</code>)</p></li><li><p>Validating charts with <code>kubectl dry-run</code></p></li><li><p>Using dependencies properly</p></li><li><p>Unit testing Helm charts (<code>helm unittest</code>)</p></li><li><p>RBAC &amp; Security for Helm</p></li><li><p>Hands-on: Secure chart with RBAC + test configs</p></li></ul><div><hr></div><h3><strong>Module 8: Advanced Templating</strong></h3><ul><li><p>Loops (<code>range</code>) for multiple resources</p></li><li><p>Conditionals (<code>if/else</code>) for optional resources</p></li><li><p>Pipelines (<code>upper</code>, <code>default</code>) for transformations</p></li><li><p>Helpers (<code>_helpers.tpl</code>) for reusability</p></li><li><p>Combining loops + conditionals</p></li><li><p>Hands-on: Build dynamic configs with templates</p></li></ul><div><hr></div><h3><strong>Module 9: Real-World Project in Azure</strong></h3><ul><li><p>Setting up AKS cluster</p></li><li><p>Creating namespaces for Dev, Staging, Prod</p></li><li><p>Deploying API + MySQL with Helm</p></li><li><p>Managing upgrades, rollbacks, scaling</p></li><li><p>Integrating Helm with CI/CD (Azure DevOps, GitHub Actions)</p></li><li><p>Hands-on: End-to-end deployment project</p></li></ul><div><hr></div><h3><strong>Module 10: Wrap-Up &amp; Advanced Practices</strong></h3><ul><li><p>GitOps with Helm (ArgoCD, Flux)</p></li><li><p>Helm repository management</p></li><li><p>Security &amp; compliance best practices</p></li><li><p>CI/CD pipelines with Helm</p></li><li><p>Final project: Deploy full microservice app with Helm in Azure</p></li></ul><div><hr></div><h2><strong>Course Deliverables</strong></h2><ul><li><p><strong>Lecture slides</strong> (concepts + architecture diagrams)</p></li><li><p><strong>Hands-on labs</strong> (Helm exercises in AKS/Minikube)</p></li><li><p><strong>Cheat sheet</strong> (Helm commands, templates, values)</p></li><li><p><strong>Capstone project</strong> (deploy a real-world microservice app in Azure using Helm)</p></li></ul><div><hr></div><h2><strong>Assessment</strong></h2><ul><li><p>Chapter-wise exercises (10 per chapter &#8594; 100 total).</p></li><li><p>Mini-project: Create and deploy a custom Helm chart.</p></li><li><p>Final project: End-to-end multi-environment deployment with Helm in Azure.</p></li></ul><div><hr></div><h1>Helm Chart Tutorial: Step-by-Step with Real Examples</h1><p><em>(Azure Lab Setup + Hands-On)</em></p><div><hr></div><h2><strong>Chapter 1: Setting Up the Lab Environment in Azure Cloud</strong></h2><p>Before we dive into Helm, we need a <strong>Kubernetes cluster + environment</strong> in Azure. Helm works on top of Kubernetes, so our lab setup is critical.</p><div><hr></div><h3><strong>Step 1: Create Resource Group in Azure</strong></h3><p>Resource groups organize your resources.</p><pre><code><code>az group create --name helm-lab-rg --location eastus
</code></code></pre><div><hr></div><h3><strong>Step 2: Create Azure Kubernetes Service (AKS) Cluster</strong></h3><p>We&#8217;ll provision a small AKS cluster (3 nodes, Standard_B2s VM size).</p><pre><code><code>az aks create \
  --resource-group helm-lab-rg \
  --name helmLabCluster \
  --node-count 3 \
  --node-vm-size Standard_B2s \
  --generate-ssh-keys
</code></code></pre><div><hr></div><h3><strong>Step 3: Connect kubectl to AKS</strong></h3><pre><code><code>az aks get-credentials --resource-group helm-lab-rg --name helmLabCluster
</code></code></pre><p>Verify cluster is running:</p><pre><code><code>kubectl get nodes
</code></code></pre><p>&#9989; You should see 3 nodes in <strong>Ready</strong> status.</p><div><hr></div><h3><strong>Step 4: Install Helm on Your Machine</strong></h3><p>On your local machine (Cloud Shell or local terminal):</p><pre><code><code>curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
</code></code></pre><p>Verify installation:</p><pre><code><code>helm version
</code></code></pre><p>&#9989; You should see something like <code>version.BuildInfo{Version:&#8221;v3.14.0&#8221; ...}</code></p><div><hr></div><h3><strong>Step 5: Verify Helm with Kubernetes</strong></h3><p>Test Helm&#8217;s connection with the cluster.</p><pre><code><code>kubectl create ns helm-test
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-nginx bitnami/nginx --namespace helm-test
</code></code></pre><p>Check pods:</p><pre><code><code>kubectl get pods -n helm-test
</code></code></pre><p>&#9989; Nginx pod should be running.</p><div><hr></div><h3><strong>Example Config Files for Lab Setup</strong></h3><ol><li><p><strong>Azure CLI Config (resource group + cluster)</strong></p></li></ol><pre><code><code># aks-config.yaml
resourceGroup: helm-lab-rg
clusterName: helmLabCluster
nodeCount: 3
nodeSize: Standard_B2s
location: eastus
</code></code></pre><ol start="2"><li><p><strong>Sample Helm Values Override for Nginx</strong></p></li></ol><pre><code><code># nginx-values.yaml
service:
  type: LoadBalancer
  port: 80
replicaCount: 2
</code></code></pre><p>Run:</p><pre><code><code>helm upgrade my-nginx bitnami/nginx -f nginx-values.yaml -n helm-test
</code></code></pre><div><hr></div><h3>&#9989; What You Achieved</h3><ul><li><p>AKS cluster created in Azure</p></li><li><p>Helm installed &amp; connected</p></li><li><p>First Helm deployment (Bitnami Nginx)</p></li></ul><div><hr></div><h1><strong>Chapter 2: What Is Helm and Why Use It?</strong></h1><div><hr></div><h3>&#128313; <strong>What Is Helm?</strong></h3><p>Helm is a <strong>package manager for Kubernetes</strong> &#8212; think of it like <strong>apt/yum</strong> for Linux or <strong>pip</strong> for Python.</p><ul><li><p>A <strong>Helm chart</strong> = a package that defines a Kubernetes application.</p></li><li><p>A <strong>release</strong> = an instance of that chart running in your cluster.</p></li><li><p>Helm makes Kubernetes deployments <strong>repeatable, versioned, and manageable</strong>.</p></li></ul><div><hr></div><h3>&#128313; <strong>Why Use Helm?</strong></h3><ol><li><p><strong>Simplifies Complex Deployments</strong> &#8211; Instead of writing 10 YAML files for an app, you just install a chart.</p></li><li><p><strong>Reusable &amp; Versioned</strong> &#8211; Same chart can be reused across environments (dev, staging, prod).</p></li><li><p><strong>Customization via Values</strong> &#8211; Override settings (replicas, images, ports) without touching YAML.</p></li><li><p><strong>Rollback Easily</strong> &#8211; If something breaks, one command restores the previous version.</p></li><li><p><strong>Ecosystem of Prebuilt Charts</strong> &#8211; Thousands of ready-to-use charts exist (e.g., MySQL, Redis, Nginx).</p></li></ol><div><hr></div><h2>&#9989; <strong>5 Real-World Examples of Helm in Action</strong></h2><div><hr></div><h3><strong>Example 1: Deploying Nginx</strong></h3><p>Without Helm &#8594; You need 3 YAML files (Deployment, Service, ConfigMap).<br>With Helm &#8594; Just one command:</p><pre><code><code>helm install my-nginx bitnami/nginx
</code></code></pre><p><strong>Customize with values:</strong></p><pre><code><code># nginx-values.yaml
service:
  type: LoadBalancer
replicaCount: 3
</code></code></pre><p>Apply:</p><pre><code><code>helm upgrade my-nginx bitnami/nginx -f nginx-values.yaml
</code></code></pre><div><hr></div><h3><strong>Example 2: Installing MySQL Database</strong></h3><p>Instead of writing StatefulSets, PVs, PVCs manually:</p><pre><code><code>helm repo add bitnami https://charts.bitnami.com/bitnami
helm install my-mysql bitnami/mysql
</code></code></pre><p>Override values:</p><pre><code><code># mysql-values.yaml
auth:
  rootPassword: mysecurepassword
  database: myappdb
primary:
  persistence:
    size: 10Gi
</code></code></pre><p>Upgrade with:</p><pre><code><code>helm upgrade my-mysql bitnami/mysql -f mysql-values.yaml
</code></code></pre><div><hr></div><h3><strong>Example 3: Multi-Environment Deployment</strong></h3><p>You can use <strong>different values files</strong> for dev/staging/prod.</p><pre><code><code># values-dev.yaml
replicaCount: 1
resources:
  requests:
    cpu: 200m
    memory: 256Mi

# values-prod.yaml
replicaCount: 5
resources:
  requests:
    cpu: 500m
    memory: 1Gi
</code></code></pre><p>Deploy to environments:</p><pre><code><code>helm upgrade myapp ./mychart -f values-dev.yaml   # dev
helm upgrade myapp ./mychart -f values-prod.yaml  # prod
</code></code></pre><div><hr></div><h3><strong>Example 4: Rollback to Previous Release</strong></h3><p>Suppose you upgrade your app and it breaks.</p><pre><code><code>helm history my-nginx
helm rollback my-nginx 1
</code></code></pre><p>&#9989; Instantly returns to version <code>1</code>.</p><div><hr></div><h3><strong>Example 5: Continuous Delivery with Helm</strong></h3><p>Integrate Helm into CI/CD pipelines.<br>For example, in <strong>GitHub Actions</strong>:</p><pre><code><code>- name: Deploy with Helm
  run: |
    helm upgrade myapp ./mychart \
      --install \
      --namespace production \
      -f values-prod.yaml
</code></code></pre><p>&#9989; Every commit automatically upgrades your app in Kubernetes.</p><div><hr></div><h3>&#128273; <strong>Key Takeaways</strong></h3><ul><li><p>Helm = package manager for Kubernetes apps.</p></li><li><p>Charts make complex apps simple.</p></li><li><p>Easy to <strong>install, upgrade, rollback, and customize</strong>.</p></li><li><p>Works perfectly for <strong>multi-environment setups</strong>.</p></li><li><p>Can be integrated into <strong>CI/CD pipelines</strong>.</p></li></ul><div><hr></div><p></p><h1><strong>Chapter 3: Installing &amp; Configuring Helm</strong></h1><div><hr></div><h2>&#128313; Step 1: Install Helm (Different Environments)</h2><div><hr></div><h3><strong>Example 1: Install Helm on Linux (Ubuntu/Debian)</strong></h3><pre><code><code>curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
</code></code></pre><p>Verify:</p><pre><code><code>helm version
</code></code></pre><div><hr></div><h3><strong>Example 2: Install Helm on Windows (PowerShell + Chocolatey)</strong></h3><pre><code><code>choco install kubernetes-helm
</code></code></pre><p>Verify:</p><pre><code><code>helm version
</code></code></pre><div><hr></div><h3><strong>Example 3: Install Helm on macOS (Homebrew)</strong></h3><pre><code><code>brew install helm
</code></code></pre><p>Verify:</p><pre><code><code>helm version
</code></code></pre><div><hr></div><h3><strong>Example 4: Install Helm in Azure Cloud Shell</strong></h3><p>Azure Cloud Shell already has <code>kubectl</code>. Just install Helm:</p><pre><code><code>curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
</code></code></pre><p>Check version:</p><pre><code><code>helm version
</code></code></pre><div><hr></div><h3><strong>Example 5: Install Helm on a GitHub Actions Runner (CI/CD)</strong></h3><p>In <code>.github/workflows/deploy.yaml</code>:</p><pre><code><code>- name: Install Helm
  run: |
    curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
    helm version
</code></code></pre><div><hr></div><h2>&#128313; Step 2: Add Helm Repositories</h2><p>Repositories are like &#8220;app stores&#8221; for Helm.</p><pre><code><code>helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
</code></code></pre><p>Check:</p><pre><code><code>helm search repo nginx
</code></code></pre><div><hr></div><h2>&#128313; Step 3: Configure Helm for Your Cluster</h2><p>Make sure Helm can talk to Kubernetes.</p><pre><code><code>kubectl config current-context
helm list -A
</code></code></pre><p>&#9989; If this works, Helm is connected to AKS.</p><div><hr></div><h2>&#128313; Step 4: Install a Test App (Nginx)</h2><pre><code><code>helm install my-nginx bitnami/nginx --namespace helm-lab --create-namespace
</code></code></pre><p>Check pods:</p><pre><code><code>kubectl get pods -n helm-lab
</code></code></pre><div><hr></div><h2>&#128313; Step 5: Verify &amp; Manage Configurations</h2><p>Helm stores configs in <strong>releases</strong>.<br>Check what&#8217;s installed:</p><pre><code><code>helm list -n helm-lab
</code></code></pre><p>Inspect values:</p><pre><code><code>helm get values my-nginx -n helm-lab
</code></code></pre><p>Upgrade values:</p><pre><code><code>helm upgrade my-nginx bitnami/nginx -n helm-lab --set replicaCount=3
</code></code></pre><p>Rollback:</p><pre><code><code>helm rollback my-nginx 1 -n helm-lab
</code></code></pre><div><hr></div><h2>&#9989; What You Achieved</h2><ul><li><p>Installed Helm on <strong>Linux, Windows, macOS, Cloud Shell, GitHub Actions</strong></p></li><li><p>Configured Helm repositories</p></li><li><p>Verified Helm-Kubernetes connection</p></li><li><p>Deployed &amp; managed your first Helm app</p></li></ul><div><hr></div><p></p><h1><strong>Chapter 4: Exploring the Structure of a Helm Chart</strong></h1><div><hr></div><h2>&#128313; What Is a Helm Chart?</h2><p>A Helm chart is basically a <strong>directory with files</strong> that describe how to deploy an application on Kubernetes.<br>When you run <code>helm create mychart</code>, Helm scaffolds a default chart with this structure:</p><pre><code><code>mychart/
&#9474;&#9472;&#9472; Chart.yaml
&#9474;&#9472;&#9472; values.yaml
&#9474;&#9472;&#9472; charts/
&#9474;&#9472;&#9472; templates/
&#9474;   &#9500;&#9472;&#9472; deployment.yaml
&#9474;   &#9500;&#9472;&#9472; service.yaml
&#9474;   &#9500;&#9472;&#9472; _helpers.tpl
&#9474;   &#9492;&#9472;&#9472; ingress.yaml
</code></code></pre><div><hr></div><h2>&#128313; Key Files &amp; Folders</h2><ol><li><p><strong>Chart.yaml</strong> &#8594; Metadata (name, version, description, maintainers)</p></li><li><p><strong>values.yaml</strong> &#8594; Default configuration values (replicas, image, service type)</p></li><li><p><strong>charts/</strong> &#8594; Dependency charts (e.g., MySQL for WordPress)</p></li><li><p><strong>templates/</strong> &#8594; Kubernetes manifests with Go templating (<code>{{ }}</code> syntax)</p></li><li><p><strong>_helpers.tpl</strong> &#8594; Reusable template helpers</p></li></ol><div><hr></div><h2>&#9989; <strong>5 Examples of Helm Chart Structure</strong></h2><div><hr></div><h3><strong>Example 1: Chart.yaml (Metadata File)</strong></h3><pre><code><code>apiVersion: v2
name: my-nginx
description: A Helm chart for deploying Nginx
type: application
version: 0.1.0
appVersion: &#8220;1.23.0&#8221;
maintainers:
  - name: Bavi
    email: bavi@example.com
</code></code></pre><p>&#128073; This tells Helm what the chart is, versioning info, and who maintains it.</p><div><hr></div><h3><strong>Example 2: values.yaml (Configuration Defaults)</strong></h3><pre><code><code>replicaCount: 2

image:
  repository: nginx
  tag: &#8220;1.23.0&#8221;
  pullPolicy: IfNotPresent

service:
  type: LoadBalancer
  port: 80
</code></code></pre><p>&#128073; Instead of hardcoding values in templates, you define them here.<br>This makes your chart <strong>reusable</strong> across environments.</p><div><hr></div><h3><strong>Example 3: templates/deployment.yaml (Application Deployment)</strong></h3><pre><code><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-deployment
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app: {{ .Release.Name }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: &#8220;{{ .Values.image.repository }}:{{ .Values.image.tag }}&#8221;
          ports:
            - containerPort: {{ .Values.service.port }}
</code></code></pre><p>&#128073; Notice <code>{{ .Values... }}</code> &#8594; this injects data from <code>values.yaml</code>.</p><div><hr></div><h3><strong>Example 4: templates/service.yaml (Expose Application)</strong></h3><pre><code><code>apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}-service
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: {{ .Values.service.port }}
  selector:
    app: {{ .Release.Name }}
</code></code></pre><p>&#128073; Service type (ClusterIP, NodePort, LoadBalancer) is driven by <code>values.yaml</code>.</p><div><hr></div><h3><strong>Example 5: _helpers.tpl (Reusable Functions)</strong></h3><pre><code><code>{{/*
Return the full name of the app
*/}}
{{- define &#8220;my-nginx.fullname&#8221; -}}
{{ .Release.Name }}-{{ .Chart.Name }}
{{- end }}
</code></code></pre><p>&#128073; Reusable snippets prevent duplication across templates.</p><div><hr></div><h2>&#128313; Running a Custom Chart</h2><p>Let&#8217;s generate and test our first custom chart:</p><pre><code><code>helm create my-nginx
cd my-nginx
</code></code></pre><p>Deploy:</p><pre><code><code>helm install test-nginx ./my-nginx
</code></code></pre><p>Check:</p><pre><code><code>kubectl get all
</code></code></pre><p>Upgrade replicas:</p><pre><code><code>helm upgrade test-nginx ./my-nginx --set replicaCount=3
</code></code></pre><div><hr></div><h2>&#9989; What You Learned</h2><ul><li><p><strong>Chart.yaml</strong> &#8594; metadata</p></li><li><p><strong>values.yaml</strong> &#8594; configurable defaults</p></li><li><p><strong>templates/</strong> &#8594; Kubernetes YAML with templating</p></li><li><p><strong>charts/</strong> &#8594; dependencies</p></li><li><p><strong>_helpers.tpl</strong> &#8594; reusable helpers</p></li><li><p>How Helm <strong>injects values dynamically</strong> into Kubernetes manifests</p></li></ul><div><hr></div><p></p><h1><strong>Chapter 5: Creating Your First Helm Chart</strong></h1><div><hr></div><h2>&#128313; Step 1: Scaffold a New Chart</h2><p>Helm provides a <code>create</code> command to generate boilerplate:</p><pre><code><code>helm create myapp
cd myapp
</code></code></pre><p>This creates the chart structure we saw in Chapter 4.</p><div><hr></div><h2>&#128313; Step 2: Understand the Default Files</h2><p>Inside <code>myapp/</code>:</p><ul><li><p><code>Chart.yaml</code> &#8594; chart metadata</p></li><li><p><code>values.yaml</code> &#8594; default values</p></li><li><p><code>templates/</code> &#8594; Kubernetes manifests (Deployment, Service, Ingress)</p></li></ul><div><hr></div><h2>&#128313; Step 3: Customize Your Chart</h2><p>We&#8217;ll now go through <strong>5 examples</strong>, each one more advanced.</p><div><hr></div><h3><strong>Example 1: Nginx Chart</strong></h3><ol><li><p>Edit <code>values.yaml</code>:</p></li></ol><pre><code><code>replicaCount: 2
image:
  repository: nginx
  tag: &#8220;1.23.0&#8221;
service:
  type: LoadBalancer
  port: 80
</code></code></pre><ol start="2"><li><p>Install:</p></li></ol><pre><code><code>helm install nginx-release ./myapp
</code></code></pre><ol start="3"><li><p>Verify:</p></li></ol><pre><code><code>kubectl get pods,svc
</code></code></pre><p>&#9989; Nginx service exposed via LoadBalancer.</p><div><hr></div><h3><strong>Example 2: Redis Chart</strong></h3><ol><li><p>Change <code>values.yaml</code>:</p></li></ol><pre><code><code>image:
  repository: redis
  tag: &#8220;7.0&#8221;
service:
  type: ClusterIP
  port: 6379
</code></code></pre><ol start="2"><li><p>Install:</p></li></ol><pre><code><code>helm install redis-release ./myapp
</code></code></pre><ol start="3"><li><p>Verify:</p></li></ol><pre><code><code>kubectl get pods
kubectl exec -it &lt;redis-pod&gt; -- redis-cli ping
</code></code></pre><p>&#9989; Should return <strong>PONG</strong>.</p><div><hr></div><h3><strong>Example 3: MySQL Chart</strong></h3><ol><li><p>Update <code>values.yaml</code>:</p></li></ol><pre><code><code>image:
  repository: mysql
  tag: &#8220;8.0&#8221;
service:
  type: ClusterIP
  port: 3306

mysqlRootPassword: mysecurepassword
mysqlDatabase: appdb
</code></code></pre><ol start="2"><li><p>Add environment variables in <code>templates/deployment.yaml</code>:</p></li></ol><pre><code><code>env:
  - name: MYSQL_ROOT_PASSWORD
    value: {{ .Values.mysqlRootPassword | quote }}
  - name: MYSQL_DATABASE
    value: {{ .Values.mysqlDatabase | quote }}
</code></code></pre><ol start="3"><li><p>Install:</p></li></ol><pre><code><code>helm install mysql-release ./myapp
</code></code></pre><p>&#9989; MySQL ready with <code>appdb</code>.</p><div><hr></div><h3><strong>Example 4: WordPress with Dependency (MySQL)</strong></h3><ol><li><p>Edit <code>Chart.yaml</code>:</p></li></ol><pre><code><code>dependencies:
  - name: mysql
    version: 9.4.0
    repository: &#8220;https://charts.bitnami.com/bitnami&#8221;
</code></code></pre><ol start="2"><li><p>Run:</p></li></ol><pre><code><code>helm dependency update
</code></code></pre><ol start="3"><li><p>Update <code>values.yaml</code>:</p></li></ol><pre><code><code>wordpressUsername: admin
wordpressPassword: admin123
service:
  type: LoadBalancer
</code></code></pre><ol start="4"><li><p>Install:</p></li></ol><pre><code><code>helm install wordpress-release ./myapp
</code></code></pre><p>&#9989; WordPress + MySQL deployed together.</p><div><hr></div><h3><strong>Example 5: Custom Microservice (Node.js API)</strong></h3><p>Suppose you have a Docker image: <code>bavi/my-api:1.0.0</code>.</p><ol><li><p>Edit <code>values.yaml</code>:</p></li></ol><pre><code><code>replicaCount: 3
image:
  repository: bavi/my-api
  tag: &#8220;1.0.0&#8221;
service:
  type: ClusterIP
  port: 8080
</code></code></pre><ol start="2"><li><p>Update <code>templates/deployment.yaml</code>:</p></li></ol><pre><code><code>containers:
- name: {{ .Chart.Name }}
  image: &#8220;{{ .Values.image.repository }}:{{ .Values.image.tag }}&#8221;
  ports:
    - containerPort: {{ .Values.service.port }}
</code></code></pre><ol start="3"><li><p>Install:</p></li></ol><pre><code><code>helm install api-release ./myapp
</code></code></pre><p>&#9989; Your Node.js API is running inside AKS.</p><div><hr></div><h2>&#128313; Step 4: Upgrade &amp; Rollback</h2><p>Upgrade image version:</p><pre><code><code>helm upgrade api-release ./myapp --set image.tag=1.0.1
</code></code></pre><p>Rollback if failed:</p><pre><code><code>helm rollback api-release 1
</code></code></pre><div><hr></div><h2>&#128313; Step 5: Uninstall</h2><pre><code><code>helm uninstall nginx-release
helm uninstall redis-release
</code></code></pre><div><hr></div><h2>&#9989; What You Achieved</h2><ul><li><p>Created a Helm chart (<code>helm create</code>)</p></li><li><p>Customized values for <strong>5 real apps</strong>: Nginx, Redis, MySQL, WordPress, Node.js API</p></li><li><p>Used <strong>dependencies</strong> (WordPress + MySQL)</p></li><li><p>Performed <strong>upgrade/rollback lifecycle</strong></p></li></ul><div><hr></div><p></p><h1><strong>Chapter 6: Deploying and Managing Releases</strong></h1><div><hr></div><h2>&#128313; What Is a Helm Release?</h2><ul><li><p>A <strong>release</strong> = one instance of a chart running in your cluster.</p></li><li><p>You can install the same chart multiple times under different release names.</p></li><li><p>Each release is <strong>tracked, versioned, and upgradeable</strong>.</p></li></ul><div><hr></div><h2>&#9989; <strong>5 Real-World Examples</strong></h2><div><hr></div><h3><strong>Example 1: Installing Multiple Releases of the Same Chart</strong></h3><p>Let&#8217;s install two Nginx instances with different configs.</p><pre><code><code>helm install nginx-dev ./myapp --set replicaCount=1
helm install nginx-prod ./myapp --set replicaCount=5
</code></code></pre><p>Check:</p><pre><code><code>helm list -A
</code></code></pre><p>&#128073; You&#8217;ll see both <code>nginx-dev</code> and <code>nginx-prod</code> releases.</p><div><hr></div><h3><strong>Example 2: Managing Releases Across Namespaces</strong></h3><p>Releases can live in separate namespaces.</p><pre><code><code>kubectl create namespace dev
kubectl create namespace prod

helm install api-dev ./myapp -n dev
helm install api-prod ./myapp -n prod
</code></code></pre><p>Check:</p><pre><code><code>helm list -n dev
helm list -n prod
</code></code></pre><p>&#128073; Same chart, but deployed to different namespaces.</p><div><hr></div><h3><strong>Example 3: Upgrading a Release (New Image Version)</strong></h3><p>Suppose you release a new API version (<code>1.0.1</code>).</p><pre><code><code>helm upgrade api-prod ./myapp -n prod --set image.tag=1.0.1
</code></code></pre><p>Check rollout:</p><pre><code><code>kubectl rollout status deployment/api-prod-deployment -n prod
</code></code></pre><p>&#128073; Production updated with zero downtime.</p><div><hr></div><h3><strong>Example 4: Rollback to Previous Release</strong></h3><p>Something broke in <code>1.0.1</code>? Roll back instantly.</p><pre><code><code>helm history api-prod -n prod
helm rollback api-prod 1 -n prod
</code></code></pre><p>&#128073; Restores the first version of the release.</p><div><hr></div><h3><strong>Example 5: Managing Release Versions</strong></h3><p>Helm tracks release history. You can inspect:</p><pre><code><code>helm history nginx-prod -n prod
</code></code></pre><p>Shows revision numbers, chart version, app version, status.</p><p>Delete a release:</p><pre><code><code>helm uninstall nginx-prod -n prod
</code></code></pre><p>&#128073; Removes resources from cluster but keeps history (unless <code>--keep-history=false</code>).</p><div><hr></div><h2>&#128313; Extra: Lifecycle Workflow in Enterprises</h2><ol><li><p><strong>Install</strong> &#8594; Dev environment (<code>helm install</code>)</p></li><li><p><strong>Upgrade</strong> &#8594; QA/Stage (<code>helm upgrade --reuse-values</code>)</p></li><li><p><strong>Promote to Prod</strong> &#8594; (<code>helm upgrade -f values-prod.yaml</code>)</p></li><li><p><strong>Rollback if needed</strong> &#8594; (<code>helm rollback</code>)</p></li><li><p><strong>Cleanup old releases</strong> &#8594; (<code>helm uninstall</code>)</p></li></ol><div><hr></div><h2>&#9989; What You Achieved</h2><ul><li><p>Installed multiple releases of the same chart</p></li><li><p>Deployed across namespaces (dev/prod)</p></li><li><p>Upgraded to new versions</p></li><li><p>Rolled back failed updates</p></li><li><p>Managed release history &amp; lifecycle</p></li></ul><div><hr></div><p></p><h1><strong>Chapter 7: Customizing Helm Charts for Different Environments</strong></h1><div><hr></div><h2>&#128313; Why Customize?</h2><ul><li><p>Different environments have different needs:</p><ul><li><p><strong>Dev</strong> &#8594; minimal replicas, smaller resource requests.</p></li><li><p><strong>Staging</strong> &#8594; near-production replica counts, but not full scale.</p></li><li><p><strong>Prod</strong> &#8594; high availability, monitoring, scaling enabled.</p></li></ul></li><li><p>Helm lets you <strong>separate logic (templates)</strong> from <strong>configuration (values.yaml)</strong>.</p></li></ul><div><hr></div><h2>&#9989; <strong>5 Real-World Examples</strong></h2><div><hr></div><h3><strong>Example 1: Dev vs Prod Values</strong></h3><p>Two separate values files:</p><p><strong>values-dev.yaml</strong></p><pre><code><code>replicaCount: 1
image:
  repository: bavi/my-api
  tag: &#8220;dev&#8221;
resources:
  requests:
    cpu: 100m
    memory: 128Mi
</code></code></pre><p><strong>values-prod.yaml</strong></p><pre><code><code>replicaCount: 5
image:
  repository: bavi/my-api
  tag: &#8220;stable&#8221;
resources:
  requests:
    cpu: 500m
    memory: 1Gi
</code></code></pre><p>Deploy:</p><pre><code><code>helm upgrade api ./myapp -f values-dev.yaml -n dev
helm upgrade api ./myapp -f values-prod.yaml -n prod
</code></code></pre><p>&#128073; Same chart, two very different environments.</p><div><hr></div><h3><strong>Example 2: Secrets Management</strong></h3><p>Use Helm to inject secrets securely.</p><p><strong>values.yaml</strong></p><pre><code><code>secret:
  dbPassword: &#8220;mySuperSecret123&#8221;
</code></code></pre><p><strong>templates/secret.yaml</strong></p><pre><code><code>apiVersion: v1
kind: Secret
metadata:
  name: {{ .Release.Name }}-db-secret
type: Opaque
data:
  password: {{ .Values.secret.dbPassword | b64enc | quote }}
</code></code></pre><p>&#128073; Different environments can have different DB passwords without touching templates.</p><div><hr></div><h3><strong>Example 3: Autoscaling Configuration</strong></h3><p>Enable HPA (Horizontal Pod Autoscaler) in Prod only.</p><p><strong>values-prod.yaml</strong></p><pre><code><code>autoscaling:
  enabled: true
  minReplicas: 3
  maxReplicas: 10
  cpuTargetPercentage: 75
</code></code></pre><p><strong>templates/hpa.yaml</strong></p><pre><code><code>{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: {{ .Release.Name }}-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: {{ .Release.Name }}-deployment
  minReplicas: {{ .Values.autoscaling.minReplicas }}
  maxReplicas: {{ .Values.autoscaling.maxReplicas }}
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: {{ .Values.autoscaling.cpuTargetPercentage }}
{{- end }}
</code></code></pre><p>&#128073; HPA deployed only in production.</p><div><hr></div><h3><strong>Example 4: Ingress Customization</strong></h3><p>Different environments need different ingress domains.</p><p><strong>values-dev.yaml</strong></p><pre><code><code>ingress:
  enabled: true
  hostname: dev.myapp.com
</code></code></pre><p><strong>values-prod.yaml</strong></p><pre><code><code>ingress:
  enabled: true
  hostname: myapp.com
</code></code></pre><p><strong>templates/ingress.yaml</strong></p><pre><code><code>{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ .Release.Name }}-ingress
spec:
  rules:
  - host: {{ .Values.ingress.hostname }}
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: {{ .Release.Name }}-service
            port:
              number: {{ .Values.service.port }}
{{- end }}
</code></code></pre><p>&#128073; Automatically switches hostname per environment.</p><div><hr></div><h3><strong>Example 5: Feature Flags per Environment</strong></h3><p>Enable/disable app features with Helm.</p><p><strong>values.yaml</strong></p><pre><code><code>features:
  enableDebug: false
</code></code></pre><p><strong>templates/configmap.yaml</strong></p><pre><code><code>apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-config
data:
  ENABLE_DEBUG: &#8220;{{ .Values.features.enableDebug }}&#8221;
</code></code></pre><p>Deploy in Dev:</p><pre><code><code>helm upgrade myapp ./myapp --set features.enableDebug=true -n dev
</code></code></pre><p>&#128073; Debugging enabled in Dev, disabled in Prod.</p><div><hr></div><h2>&#128313; Best Practices for Environment Customization</h2><ul><li><p>Use <strong>separate values files</strong> (<code>values-dev.yaml</code>, <code>values-staging.yaml</code>, <code>values-prod.yaml</code>).</p></li><li><p>Never hardcode secrets &#8594; use <code>b64enc</code> or external secret managers.</p></li><li><p>Use conditionals (<code>if</code>) in templates for environment-specific resources.</p></li><li><p>Keep <code>values.yaml</code> as <strong>base config</strong>, override with env-specific files.</p></li></ul><div><hr></div><h2>&#9989; What You Achieved</h2><ul><li><p>Learned how to customize Helm charts per environment</p></li><li><p>Used <strong>values overrides, secrets, HPA, ingress, and feature flags</strong></p></li><li><p>Built charts that adapt automatically to Dev/Staging/Prod</p></li></ul><div><hr></div><p></p><h1><strong>Chapter 8: Best Practices for Helm Chart Development</strong></h1><div><hr></div><h2>&#128313; Why Best Practices Matter</h2><ul><li><p>Prevent <strong>chart drift</strong> across environments.</p></li><li><p>Ensure charts are <strong>reusable and maintainable</strong>.</p></li><li><p>Catch errors early with <strong>linting &amp; testing</strong>.</p></li><li><p>Integrate into <strong>DevOps pipelines</strong>.</p></li><li><p>Improve <strong>security and compliance</strong>.</p></li></ul><div><hr></div><h2>&#9989; <strong>5 Best Practices with Examples</strong></h2><div><hr></div><h3><strong>Example 1: Linting and Validating Charts</strong></h3><p>Before deploying, always validate your charts.</p><pre><code><code>helm lint ./myapp
</code></code></pre><p>&#128073; Catches syntax errors, missing fields, bad references.</p><p>For stricter validation, render manifests and validate with <code>kubectl</code>:</p><pre><code><code>helm template ./myapp | kubectl apply --dry-run=client -f -
</code></code></pre><p>&#9989; Ensures manifests are valid before applying.</p><div><hr></div><h3><strong>Example 2: Dependency Management</strong></h3><p>Use <code>requirements.yaml</code> (Helm v2) or <code>Chart.yaml</code> (Helm v3) for dependencies.</p><p><strong>Chart.yaml</strong></p><pre><code><code>dependencies:
  - name: mysql
    version: 9.4.0
    repository: &#8220;https://charts.bitnami.com/bitnami&#8221;
  - name: redis
    version: 17.3.0
    repository: &#8220;https://charts.bitnami.com/bitnami&#8221;
</code></code></pre><p>Update dependencies:</p><pre><code><code>helm dependency update
</code></code></pre><p>&#128073; This ensures your chart is portable and includes subcharts.</p><div><hr></div><h3><strong>Example 3: Testing Charts with Helm Unittest</strong></h3><p>Install plugin:</p><pre><code><code>helm plugin install https://github.com/quintush/helm-unittest
</code></code></pre><p>Create a test in <code>tests/deployment_test.yaml</code>:</p><pre><code><code>suite: test deployment
templates:
  - deployment.yaml
tests:
  - it: should set correct replica count
    set:
      replicaCount: 3
    asserts:
      - equal:
          path: spec.replicas
          value: 3
</code></code></pre><p>Run:</p><pre><code><code>helm unittest ./myapp
</code></code></pre><p>&#9989; Ensures templates behave as expected.</p><div><hr></div><h3><strong>Example 4: GitOps Workflow with ArgoCD/Flux</strong></h3><p>Instead of <code>helm install</code> manually, use GitOps:</p><p><strong>values-prod.yaml</strong> stored in Git repo.<br>ArgoCD watches repo and applies automatically:</p><pre><code><code>apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
spec:
  project: default
  source:
    repoURL: https://github.com/bavi/helm-charts
    path: myapp
    targetRevision: main
  destination:
    server: https://kubernetes.default.svc
    namespace: prod
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
</code></code></pre><p>&#128073; Every Git commit = automatic Helm deployment.</p><div><hr></div><h3><strong>Example 5: Security &amp; RBAC</strong></h3><p>Limit Helm&#8217;s permissions with RBAC.</p><p><strong>rbac.yaml</strong></p><pre><code><code>apiVersion: v1
kind: ServiceAccount
metadata:
  name: helm-service-account
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: helm-role-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: helm-service-account
    namespace: kube-system
</code></code></pre><p>Install Helm with service account:</p><pre><code><code>helm install myapp ./myapp --service-account helm-service-account -n prod
</code></code></pre><p>&#128073; Ensures Helm runs with <strong>least-privilege access</strong>.</p><div><hr></div><h2>&#128313; Extra Tips</h2><ul><li><p>Use <strong>semantic versioning</strong> (<code>0.1.0</code>, <code>1.0.0</code>) for charts.</p></li><li><p>Keep <strong>default values minimal</strong> &#8594; override in env files.</p></li><li><p>Document your chart (<code>README.md</code> with examples).</p></li><li><p>Always store charts in a <strong>Helm repository</strong> (e.g., GitHub Pages, Azure Container Registry, JFrog).</p></li></ul><div><hr></div><h2>&#9989; What You Achieved</h2><ul><li><p>Learned <strong>linting, dependency management, unit testing, GitOps, and RBAC security</strong>.</p></li><li><p>Built charts that are <strong>production-ready</strong>.</p></li><li><p>Ensured deployments are <strong>safe, testable, and automated</strong>.</p></li></ul><div><hr></div><p></p><h1><strong>Chapter 9: Helm Advanced Templating</strong></h1><div><hr></div><h2>&#128313; Why Advanced Templating?</h2><ul><li><p>Avoid duplication &#8594; generate 10 services from a list with a loop.</p></li><li><p>Conditional logic &#8594; deploy Ingress only in Prod.</p></li><li><p>Pipelines &#8594; transform values before rendering.</p></li><li><p>Functions &#8594; manipulate strings, numbers, and YAML data.</p></li></ul><div><hr></div><h2>&#9989; <strong>5 Real-World Templating Examples</strong></h2><div><hr></div><h3><strong>Example 1: Loops &#8211; Generate Multiple Config Entries</strong></h3><p>Suppose you want multiple environment variables for your app.</p><p><strong>values.yaml</strong></p><pre><code><code>env:
  - name: DB_HOST
    value: mysql-service
  - name: CACHE_HOST
    value: redis-service
  - name: LOG_LEVEL
    value: DEBUG
</code></code></pre><p><strong>templates/deployment.yaml</strong></p><pre><code><code>env:
{{- range .Values.env }}
  - name: {{ .name }}
    value: {{ .value | quote }}
{{- end }}
</code></code></pre><p>&#128073; Renders multiple environment variables dynamically.</p><div><hr></div><h3><strong>Example 2: Conditionals (if/else)</strong></h3><p>Enable Ingress only when <code>ingress.enabled=true</code>.</p><p><strong>values.yaml</strong></p><pre><code><code>ingress:
  enabled: true
  host: myapp.com
</code></code></pre><p><strong>templates/ingress.yaml</strong></p><pre><code><code>{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ .Release.Name }}-ingress
spec:
  rules:
    - host: {{ .Values.ingress.host }}
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: {{ .Release.Name }}-service
              port:
                number: {{ .Values.service.port }}
{{- end }}
</code></code></pre><p>&#128073; If <code>enabled=false</code>, no Ingress gets created.</p><div><hr></div><h3><strong>Example 3: Pipelines (Transform Values)</strong></h3><p>Use Helm&#8217;s built-in functions.</p><p><strong>values.yaml</strong></p><pre><code><code>username: admin
</code></code></pre><p><strong>templates/configmap.yaml</strong></p><pre><code><code>apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-config
data:
  USERNAME_UPPER: {{ .Values.username | upper | quote }}
</code></code></pre><p>&#128073; Renders <code>&#8220;ADMIN&#8221;</code> instead of <code>&#8220;admin&#8221;</code>.</p><div><hr></div><h3><strong>Example 4: Using Default Values</strong></h3><p>Set a fallback value if none is provided.</p><p><strong>templates/configmap.yaml</strong></p><pre><code><code>apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-config
data:
  DB_HOST: {{ default &#8220;localhost&#8221; .Values.db.host | quote }}
</code></code></pre><p>&#128073; If <code>db.host</code> not set in values, defaults to <code>&#8220;localhost&#8221;</code>.</p><div><hr></div><h3><strong>Example 5: Including &amp; Reusing Templates</strong></h3><p>Use <code>_helpers.tpl</code> to avoid duplication.</p><p><strong>_helpers.tpl</strong></p><pre><code><code>{{- define &#8220;myapp.fullname&#8221; -}}
{{ .Release.Name }}-{{ .Chart.Name }}
{{- end }}
</code></code></pre><p><strong>templates/deployment.yaml</strong></p><pre><code><code>metadata:
  name: {{ include &#8220;myapp.fullname&#8221; . }}
</code></code></pre><p>&#128073; Reuses template logic across multiple files.</p><div><hr></div><h2>&#128313; Bonus: Combining Loops + Conditionals</h2><p><strong>values.yaml</strong></p><pre><code><code>extraServices:
  - name: metrics
    port: 8080
    enabled: true
  - name: debug
    port: 9090
    enabled: false
</code></code></pre><p><strong>templates/services.yaml</strong></p><pre><code><code>{{- range .Values.extraServices }}
{{- if .enabled }}
apiVersion: v1
kind: Service
metadata:
  name: {{ .name }}
spec:
  ports:
    - port: {{ .port }}
  selector:
    app: {{ $.Release.Name }}
---
{{- end }}
{{- end }}
</code></code></pre><p>&#128073; Generates multiple services only for those marked as <code>enabled: true</code>.</p><div><hr></div><h2>&#9989; What You Achieved</h2><ul><li><p>Used <strong>loops</strong> to generate repeated config.</p></li><li><p>Added <strong>if/else conditionals</strong> for selective resources.</p></li><li><p>Applied <strong>pipelines and functions</strong> (uppercase, default).</p></li><li><p>Reused templates with <strong>helpers</strong>.</p></li><li><p>Built <strong>dynamic manifests</strong> that adapt to environment needs.</p></li></ul><div><hr></div><p></p><h1><strong>Chapter 10: Conclusion &amp; Real-World Project Setup in Azure</strong></h1><div><hr></div><h2>&#128313; Step 1: Project Structure</h2><p>Let&#8217;s build a sample <strong>microservice app</strong> (API + DB) with Helm.</p><pre><code><code>helm-lab/
&#9474;&#9472;&#9472; api-chart/
&#9474;   &#9474;&#9472;&#9472; Chart.yaml
&#9474;   &#9474;&#9472;&#9472; values.yaml
&#9474;   &#9474;&#9472;&#9472; templates/
&#9474;   &#9474;    &#9500;&#9472;&#9472; deployment.yaml
&#9474;   &#9474;    &#9500;&#9472;&#9472; service.yaml
&#9474;   &#9474;    &#9500;&#9472;&#9472; ingress.yaml
&#9474;   &#9474;    &#9492;&#9472;&#9472; _helpers.tpl
&#9474;&#9472;&#9472; values-dev.yaml
&#9474;&#9472;&#9472; values-staging.yaml
&#9474;&#9472;&#9472; values-prod.yaml
</code></code></pre><div><hr></div><h2>&#128313; Step 2: Chart.yaml</h2><pre><code><code>apiVersion: v2
name: api-chart
description: A simple Node.js API with MySQL backend
type: application
version: 0.1.0
appVersion: &#8220;1.0.0&#8221;

dependencies:
  - name: mysql
    version: 9.4.0
    repository: &#8220;https://charts.bitnami.com/bitnami&#8221;
</code></code></pre><p>&#128073; This chart depends on <strong>MySQL</strong>.</p><div><hr></div><h2>&#128313; Step 3: values.yaml (Base)</h2><pre><code><code>replicaCount: 2
image:
  repository: bavi/node-api
  tag: &#8220;1.0.0&#8221;
service:
  type: ClusterIP
  port: 8080

ingress:
  enabled: true
  hostname: api.local

mysql:
  auth:
    rootPassword: root123
    database: apidb
</code></code></pre><div><hr></div><h2>&#128313; Step 4: Environment-Specific Values</h2><p><strong>values-dev.yaml</strong></p><pre><code><code>replicaCount: 1
image:
  tag: &#8220;dev&#8221;
mysql:
  auth:
    rootPassword: devpass
</code></code></pre><p><strong>values-staging.yaml</strong></p><pre><code><code>replicaCount: 2
image:
  tag: &#8220;staging&#8221;
mysql:
  auth:
    rootPassword: stagepass
</code></code></pre><p><strong>values-prod.yaml</strong></p><pre><code><code>replicaCount: 5
image:
  tag: &#8220;stable&#8221;
mysql:
  auth:
    rootPassword: prodpass
</code></code></pre><div><hr></div><h2>&#128313; Step 5: Deployment Template</h2><p><code>templates/deployment.yaml</code></p><pre><code><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include &#8220;api-chart.fullname&#8221; . }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ include &#8220;api-chart.name&#8221; . }}
  template:
    metadata:
      labels:
        app: {{ include &#8220;api-chart.name&#8221; . }}
    spec:
      containers:
        - name: api
          image: &#8220;{{ .Values.image.repository }}:{{ .Values.image.tag }}&#8221;
          ports:
            - containerPort: {{ .Values.service.port }}
          env:
            - name: DB_HOST
              value: &#8220;{{ .Release.Name }}-mysql&#8221;
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: {{ .Release.Name }}-mysql
                  key: mysql-root-password
</code></code></pre><div><hr></div><h2>&#128313; Step 6: Deploy into Azure AKS</h2><ol><li><p>Make sure AKS is set up (from Chapter 1).</p></li><li><p>Deploy Dev environment:</p></li></ol><pre><code><code>helm install api-dev ./api-chart -f values-dev.yaml -n dev --create-namespace
</code></code></pre><ol start="3"><li><p>Deploy Staging:</p></li></ol><pre><code><code>helm install api-staging ./api-chart -f values-staging.yaml -n staging --create-namespace
</code></code></pre><ol start="4"><li><p>Deploy Prod:</p></li></ol><pre><code><code>helm install api-prod ./api-chart -f values-prod.yaml -n prod --create-namespace
</code></code></pre><p>Check:</p><pre><code><code>helm list -A
kubectl get pods -n prod
</code></code></pre><div><hr></div><h2>&#128313; Step 7: Upgrade Workflow</h2><p>Update to new version (e.g., <code>1.0.1</code>):</p><pre><code><code>helm upgrade api-prod ./api-chart -f values-prod.yaml --set image.tag=1.0.1 -n prod
</code></code></pre><p>Rollback if issues:</p><pre><code><code>helm rollback api-prod 1 -n prod
</code></code></pre><div><hr></div><h2>&#128313; Step 8: Integrate into CI/CD (Azure DevOps or GitHub Actions)</h2><p>Example GitHub Actions snippet:</p><pre><code><code>- name: Deploy to AKS with Helm
  run: |
    helm upgrade api-prod ./api-chart \
      -f values-prod.yaml \
      --install \
      -n prod
</code></code></pre><p>&#128073; Ensures every commit can roll out to AKS.</p><div><hr></div><h2>&#9989; What You Achieved in the Series</h2><ul><li><p>Setup Azure AKS cluster for Helm.</p></li><li><p>Learned Helm basics &#8594; charts, releases, repos.</p></li><li><p>Explored chart structure.</p></li><li><p>Built &amp; customized charts with <strong>Nginx, Redis, MySQL, WordPress, Node.js API</strong>.</p></li><li><p>Managed <strong>deployments, rollbacks, multi-env values</strong>.</p></li><li><p>Used <strong>advanced templating</strong> (loops, if/else, pipelines).</p></li><li><p>Followed <strong>best practices</strong> (linting, testing, RBAC, GitOps).</p></li><li><p>Deployed a <strong>real-world project to Azure AKS</strong>.</p></li></ul><div><hr></div><h2><strong>Final Note</strong>:</h2><p>Helm is not just a tool, it&#8217;s the <strong>glue between Kubernetes and DevOps automation</strong>. Mastering Helm gives you production-ready, versioned, and repeatable deployments.</p><div><hr></div><p></p><p></p><h1>Helm Learning Exercises</h1><div><hr></div><h2><strong>Chapter 1: Setting Up the Lab Environment in Azure Cloud</strong></h2><ol><li><p>Create a new resource group in a different Azure region.</p></li><li><p>Deploy an AKS cluster with 1 node, then scale it to 3 nodes.</p></li><li><p>Create a namespace <code>helm-lab</code> and deploy a test Pod (<code>nginx</code>).</p></li><li><p>Configure <code>kubectl</code> to connect to your AKS cluster.</p></li><li><p>Verify Kubernetes API server is reachable (<code>kubectl cluster-info</code>).</p></li><li><p>Install Helm on <strong>Azure Cloud Shell</strong>.</p></li><li><p>Install Helm on your <strong>local machine</strong>.</p></li><li><p>Deploy a Helm chart (Nginx) into a new namespace <code>test</code>.</p></li><li><p>Delete the namespace and verify Helm release is removed.</p></li><li><p>Enable <strong>Azure Monitor</strong> on your AKS cluster.</p></li></ol><div><hr></div><h2><strong>Chapter 2: What Is Helm and Why Use It?</strong></h2><ol><li><p>List all Helm repositories available in your setup.</p></li><li><p>Search for the <code>mysql</code> chart in Bitnami repo.</p></li><li><p>Install two instances of <code>nginx</code> using different release names.</p></li><li><p>Override default replica count at install time with <code>--set</code>.</p></li><li><p>List Helm releases across all namespaces.</p></li><li><p>Upgrade <code>nginx</code> release with a new replica count.</p></li><li><p>Rollback <code>nginx</code> release to its first version.</p></li><li><p>Delete Helm release but keep history (<code>--keep-history</code>).</p></li><li><p>Export rendered manifests with <code>helm template</code>.</p></li><li><p>Compare Helm vs. plain YAML (install nginx both ways).</p></li></ol><div><hr></div><h2><strong>Chapter 3: Installing &amp; Configuring Helm</strong></h2><ol><li><p>Install Helm on <strong>Linux</strong>.</p></li><li><p>Install Helm on <strong>Windows (PowerShell)</strong>.</p></li><li><p>Install Helm on <strong>macOS (Homebrew)</strong>.</p></li><li><p>Add the <strong>Bitnami</strong> repo and update it.</p></li><li><p>Search for the <code>wordpress</code> chart.</p></li><li><p>Install <code>wordpress</code> in namespace <code>web</code>.</p></li><li><p>Verify Helm installation using <code>helm version</code>.</p></li><li><p>Run <code>helm repo list</code> and document repos.</p></li><li><p>Configure Helm on <strong>GitHub Actions runner</strong>.</p></li><li><p>Use <code>helm list -A</code> to check all releases.</p></li></ol><div><hr></div><h2><strong>Chapter 4: Exploring the Structure of a Helm Chart</strong></h2><ol><li><p>Run <code>helm create mychart</code> and explore folder structure.</p></li><li><p>Edit <code>Chart.yaml</code> &#8594; change appVersion to <code>&#8220;2.0.0&#8221;</code>.</p></li><li><p>Edit <code>values.yaml</code> &#8594; change service type to <code>NodePort</code>.</p></li><li><p>Modify <code>deployment.yaml</code> &#8594; change image to <code>nginx</code>.</p></li><li><p>Add a ConfigMap in <code>templates/</code>.</p></li><li><p>Add a helper template <code>_helpers.tpl</code> for app name.</p></li><li><p>Render chart using <code>helm template</code>.</p></li><li><p>Install the chart with release name <code>myapp</code>.</p></li><li><p>Upgrade release with new values.</p></li><li><p>Delete release and namespace.</p></li></ol><div><hr></div><h2><strong>Chapter 5: Creating Your First Helm Chart</strong></h2><ol><li><p>Create a new Helm chart for Redis.</p></li><li><p>Deploy Redis with 1 replica.</p></li><li><p>Upgrade Redis to 3 replicas.</p></li><li><p>Create Helm chart for MySQL with DB password.</p></li><li><p>Create Helm chart for WordPress with MySQL dependency.</p></li><li><p>Build custom chart for Node.js API.</p></li><li><p>Deploy Node.js API with <code>LoadBalancer</code>.</p></li><li><p>Rollback Node.js API deployment.</p></li><li><p>Add dependency (Redis) to Node.js chart.</p></li><li><p>Document your custom chart with <code>README.md</code>.</p></li></ol><div><hr></div><h2><strong>Chapter 6: Deploying and Managing Releases</strong></h2><ol><li><p>Install two releases of <code>nginx</code> (<code>nginx-dev</code>, <code>nginx-prod</code>).</p></li><li><p>Deploy release in different namespaces.</p></li><li><p>List all releases in <code>prod</code> namespace.</p></li><li><p>Upgrade <code>nginx-prod</code> with new image version.</p></li><li><p>Rollback <code>nginx-prod</code> to previous revision.</p></li><li><p>Delete <code>nginx-dev</code> release.</p></li><li><p>Use <code>helm history</code> to check versions.</p></li><li><p>Deploy release with custom values file.</p></li><li><p>Export manifests of release.</p></li><li><p>Automate <code>helm upgrade</code> in a shell script.</p></li></ol><div><hr></div><h2><strong>Chapter 7: Customizing Helm Charts</strong></h2><ol><li><p>Create <code>values-dev.yaml</code> and <code>values-prod.yaml</code>.</p></li><li><p>Deploy chart with <code>values-dev.yaml</code>.</p></li><li><p>Deploy chart with <code>values-prod.yaml</code>.</p></li><li><p>Add environment variables via <code>values.yaml</code>.</p></li><li><p>Create secrets using <code>b64enc</code>.</p></li><li><p>Enable HPA only in Prod with conditional.</p></li><li><p>Create ingress rule for Dev (dev.myapp.com).</p></li><li><p>Create ingress rule for Prod (myapp.com).</p></li><li><p>Add a feature flag (debug mode).</p></li><li><p>Deploy chart in both Dev &amp; Prod, compare manifests.</p></li></ol><div><hr></div><h2><strong>Chapter 8: Best Practices</strong></h2><ol><li><p>Run <code>helm lint</code> on your chart.</p></li><li><p>Validate chart with <code>kubectl apply --dry-run=client</code>.</p></li><li><p>Add Redis dependency in <code>Chart.yaml</code>.</p></li><li><p>Run <code>helm dependency update</code>.</p></li><li><p>Write a unittest for <code>replicaCount</code>.</p></li><li><p>Run Helm unittest plugin.</p></li><li><p>Configure RBAC for Helm with a service account.</p></li><li><p>Install Helm release with service account.</p></li><li><p>Integrate chart into ArgoCD.</p></li><li><p>Write a <code>README.md</code> with installation steps.</p></li></ol><div><hr></div><h2><strong>Chapter 9: Advanced Templating</strong></h2><ol><li><p>Use a loop to create multiple env vars.</p></li><li><p>Use an <code>if</code> conditional for ingress.</p></li><li><p>Use pipeline to uppercase a value.</p></li><li><p>Use pipeline to set a default DB host.</p></li><li><p>Create helper template in <code>_helpers.tpl</code>.</p></li><li><p>Reuse helper template in Deployment &amp; Service.</p></li><li><p>Loop through multiple service ports.</p></li><li><p>Conditionally enable metrics service.</p></li><li><p>Nest loop inside condition.</p></li><li><p>Render chart and verify YAML output.</p></li></ol><div><hr></div><h2><strong>Chapter 10: Real-World Project in Azure</strong></h2><ol><li><p>Create namespace <code>dev</code>, <code>staging</code>, <code>prod</code>.</p></li><li><p>Deploy API chart with <code>values-dev.yaml</code>.</p></li><li><p>Deploy API chart with <code>values-staging.yaml</code>.</p></li><li><p>Deploy API chart with <code>values-prod.yaml</code>.</p></li><li><p>Upgrade Prod API image to <code>1.0.1</code>.</p></li><li><p>Rollback Prod API to version 1.</p></li><li><p>Expose API via Azure LoadBalancer ingress.</p></li><li><p>Configure Helm in GitHub Actions CI/CD.</p></li><li><p>Deploy chart automatically via pipeline.</p></li><li><p>Document project architecture with diagrams.</p></li></ol><div><hr></div><p></p>]]></content:encoded></item><item><title><![CDATA[AI/ML Career Starter: MySQL Deep Dive in 80 Hours]]></title><description><![CDATA[Crack AI & Data Jobs: Free MySQL Deep Dive (80 Hours)]]></description><link>https://careerbytecode.substack.com/p/complete-handson-training-crack-ai-data-jobs-free-mysql-deep-dive-80-hours</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/complete-handson-training-crack-ai-data-jobs-free-mysql-deep-dive-80-hours</guid><dc:creator><![CDATA[CareerByteCode]]></dc:creator><pubDate>Thu, 25 Sep 2025 07:25:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!p669!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0a716-a144-42ac-a0d6-ae8455b98a50_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!p669!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0a716-a144-42ac-a0d6-ae8455b98a50_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!p669!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0a716-a144-42ac-a0d6-ae8455b98a50_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!p669!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0a716-a144-42ac-a0d6-ae8455b98a50_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!p669!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0a716-a144-42ac-a0d6-ae8455b98a50_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!p669!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0a716-a144-42ac-a0d6-ae8455b98a50_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!p669!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0a716-a144-42ac-a0d6-ae8455b98a50_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e3e0a716-a144-42ac-a0d6-ae8455b98a50_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:739003,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/174426748?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0a716-a144-42ac-a0d6-ae8455b98a50_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!p669!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0a716-a144-42ac-a0d6-ae8455b98a50_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!p669!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0a716-a144-42ac-a0d6-ae8455b98a50_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!p669!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0a716-a144-42ac-a0d6-ae8455b98a50_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!p669!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3e0a716-a144-42ac-a0d6-ae8455b98a50_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p></p><h1>&#128467;&#65039; 90-Day SQL Learning Plan (with Chapters)</h1><div><hr></div><h2>&#128205; Phase 1: SQL Foundations (Weeks 1&#8211;2)</h2><p><strong>Covers: Chapter 1 (Foundations) + Chapter 2 (Aggregations &amp; Grouping)</strong></p><h3><strong>Week 1 &#8594; Chapter 1: SQL Foundations</strong></h3><ul><li><p>Day 1: Install MySQL, set up practice DB (<code>employees</code>, <code>products</code>).</p></li><li><p>Day 2: <code>SELECT</code>, <code>FROM</code>, <code>WHERE</code>.</p></li><li><p>Day 3: Filtering (<code>=, &lt;, &gt;, BETWEEN, IN, LIKE</code>).</p></li><li><p>Day 4: <code>ORDER BY</code>, <code>LIMIT</code>.</p></li><li><p>Day 5: Aliases (<code>AS</code>), expressions.</p></li><li><p>Day 6: <code>INSERT</code>, <code>UPDATE</code>, <code>DELETE</code>.</p></li><li><p>Day 7: <strong>Mini Project</strong> &#8594; Build a <code>students</code> + <code>courses</code> DB, query for:</p><ul><li><p>Students above avg marks</p></li><li><p>Students in specific courses</p></li></ul></li></ul><h3><strong>Week 2 &#8594; Chapter 2: Aggregations &amp; Grouping</strong></h3><ul><li><p>Day 8: Aggregates (<code>COUNT, SUM, AVG, MIN, MAX</code>).</p></li><li><p>Day 9: <code>GROUP BY</code> single column.</p></li><li><p>Day 10: <code>GROUP BY</code> multiple columns.</p></li><li><p>Day 11: <code>HAVING</code> vs <code>WHERE</code>.</p></li><li><p>Day 12: <code>DISTINCT</code>.</p></li><li><p>Day 13: Aggregations + <code>ORDER BY</code>.</p></li><li><p>Day 14: <strong>Mini Project</strong> &#8594; Sales dataset &#8594;</p><ul><li><p>Revenue per region</p></li><li><p>Top-selling product</p></li><li><p>Average order size</p></li></ul></li></ul><div><hr></div><h2>&#128205; Phase 2: Joins &amp; Subqueries (Weeks 3&#8211;4)</h2><p><strong>Covers: Chapter 3 (Joins) + Chapter 4 (Subqueries &amp; Derived Tables)</strong></p><h3><strong>Week 3 &#8594; Chapter 3: Joins</strong></h3><ul><li><p>Day 15: INNER JOIN.</p></li><li><p>Day 16: LEFT JOIN &amp; RIGHT JOIN.</p></li><li><p>Day 17: FULL OUTER JOIN (simulate).</p></li><li><p>Day 18: SELF JOIN (hierarchies).</p></li><li><p>Day 19: CROSS JOIN (combinations).</p></li><li><p>Day 20: Multi-table joins.</p></li><li><p>Day 21: <strong>Mini Project</strong> &#8594; E-commerce DB (<code>customers</code>, <code>orders</code>, <code>payments</code>) &#8594;</p><ul><li><p>Show customers with orders</p></li><li><p>Find customers with no orders</p></li><li><p>Compute spend per customer</p></li></ul></li></ul><h3><strong>Week 4 &#8594; Chapter 4: Subqueries &amp; Derived Tables</strong></h3><ul><li><p>Day 22: Subquery in <code>WHERE</code>.</p></li><li><p>Day 23: Subquery in <code>SELECT</code>.</p></li><li><p>Day 24: Derived tables in <code>FROM</code>.</p></li><li><p>Day 25: Correlated subqueries.</p></li><li><p>Day 26: <code>EXISTS</code> vs <code>IN</code>.</p></li><li><p>Day 27: CTE (<code>WITH</code>).</p></li><li><p>Day 28: <strong>Mini Project</strong> &#8594; HR dataset &#8594;</p><ul><li><p>Employees above dept avg salary</p></li><li><p>Departments with no employees</p></li><li><p>Feature table: salary vs dept avg</p></li></ul></li></ul><div><hr></div><h2>&#128205; Phase 3: Window Functions &amp; Data Manipulation (Weeks 5&#8211;6)</h2><p><strong>Covers: Chapter 5 (Window Functions) + Chapter 6 (Data Manipulation)</strong></p><h3><strong>Week 5 &#8594; Chapter 5: Advanced Filtering &amp; Window Functions</strong></h3><ul><li><p>Day 29: <code>CASE WHEN</code>.</p></li><li><p>Day 30: Handle NULLs (<code>COALESCE</code>, <code>NULLIF</code>, <code>IFNULL</code>).</p></li><li><p>Day 31: <code>ROW_NUMBER</code>.</p></li><li><p>Day 32: <code>RANK</code>, <code>DENSE_RANK</code>.</p></li><li><p>Day 33: <code>SUM() OVER</code>, <code>AVG() OVER</code>.</p></li><li><p>Day 34: <code>LAG</code>, <code>LEAD</code>.</p></li><li><p>Day 35: <strong>Mini Project</strong> &#8594; Transactions dataset &#8594;</p><ul><li><p>Rank customers by region spend</p></li><li><p>Cumulative spend per customer</p></li><li><p>Rolling daily average</p></li></ul></li></ul><h3><strong>Week 6 &#8594; Chapter 6: Data Manipulation</strong></h3><ul><li><p>Day 36: <code>INSERT</code> single/multiple rows.</p></li><li><p>Day 37: <code>UPDATE</code> with WHERE.</p></li><li><p>Day 38: <code>DELETE</code> safely.</p></li><li><p>Day 39: Bulk insert (<code>LOAD DATA</code>).</p></li><li><p>Day 40: UPSERT (<code>ON DUPLICATE KEY UPDATE</code>).</p></li><li><p>Day 41: Transactions (<code>START TRANSACTION, COMMIT, ROLLBACK</code>).</p></li><li><p>Day 42: <strong>Mini Project</strong> &#8594; Banking DB &#8594;</p><ul><li><p>Simulate deposits/withdrawals</p></li><li><p>Update balances</p></li><li><p>Handle rollback</p></li></ul></li></ul><div><hr></div><h2>&#128205; Phase 4: Set Operations &amp; Cleaning (Weeks 7&#8211;8)</h2><p><strong>Covers: Chapter 7 (Set Operations) + Chapter 8 (Data Cleaning &amp; Transformation)</strong></p><h3><strong>Week 7 &#8594; Chapter 7: Set Operations</strong></h3><ul><li><p>Day 43: <code>UNION</code>.</p></li><li><p>Day 44: <code>UNION ALL</code>.</p></li><li><p>Day 45: INTERSECT (simulate).</p></li><li><p>Day 46: EXCEPT (simulate).</p></li><li><p>Day 47: Combine datasets with UNION.</p></li><li><p>Day 48: Deduplication with set ops.</p></li><li><p>Day 49: <strong>Mini Project</strong> &#8594; Customer retention &#8594;</p><ul><li><p>Customers in Jan but not Feb</p></li><li><p>Customers in both months</p></li><li><p>Total unique customers in Q1</p></li></ul></li></ul><h3><strong>Week 8 &#8594; Chapter 8: Data Cleaning &amp; Transformation</strong></h3><ul><li><p>Day 50: String cleaning (<code>TRIM, UPPER, LOWER</code>).</p></li><li><p>Day 51: SUBSTRING, CONCAT.</p></li><li><p>Day 52: Pattern match (<code>LIKE</code>, <code>REGEXP</code>).</p></li><li><p>Day 53: Date ops (<code>DATEDIFF, DATE_ADD, EXTRACT</code>).</p></li><li><p>Day 54: Type conversion (<code>CAST, CONVERT</code>).</p></li><li><p>Day 55: Pivot (CASE).</p></li><li><p>Day 56: Unpivot (UNION).</p></li><li><p>Day 57: <strong>Mini Project</strong> &#8594; Orders dataset &#8594;</p><ul><li><p>Clean names/emails</p></li><li><p>Calculate delivery delays</p></li><li><p>Pivot sales by region</p></li></ul></li></ul><div><hr></div><h2>&#128205; Phase 5: Optimization &amp; AI-Specific SQL (Weeks 9&#8211;12)</h2><p><strong>Covers: Chapter 9 (Performance &amp; Optimization) + Chapter 10 (AI/Data-Job SQL Topics)</strong></p><h3><strong>Week 9 &#8594; Chapter 9: Performance &amp; Optimization</strong></h3><ul><li><p>Day 58: Index basics.</p></li><li><p>Day 59: Composite indexes.</p></li><li><p>Day 60: <code>EXPLAIN</code>.</p></li><li><p>Day 61: Avoid <code>SELECT *</code>.</p></li><li><p>Day 62: Indexing join columns.</p></li><li><p>Day 63: Join vs Subquery performance.</p></li><li><p>Day 64: <strong>Mini Project</strong> &#8594; Optimize sales dataset queries with indexes.</p></li></ul><h3><strong>Weeks 10&#8211;11 &#8594; Chapter 10: AI/Data SQL Applications</strong></h3><ul><li><p>Day 65: Feature engineering (<code>total_spend</code>, <code>txn_count</code>).</p></li><li><p>Day 66: Time-series (lag, lead, cumulative).</p></li><li><p>Day 67: RFM metrics.</p></li><li><p>Day 68: Churn detection (inactive customers).</p></li><li><p>Day 69: Data quality checks (NULLs, duplicates, anomalies).</p></li><li><p>Day 70: ETL staging &#8594; clean tables.</p></li><li><p>Day 71&#8211;77: <strong>Project</strong> &#8594; Build churn dataset &#8594;</p><ul><li><p>Last transaction date</p></li><li><p>Avg spend</p></li><li><p>Cumulative revenue</p></li><li><p>Churn flag (inactive &gt;60 days)</p></li></ul></li></ul><h3><strong>Week 12 &#8594; Chapter 10: Python Integration</strong></h3><ul><li><p>Day 78: Connect MySQL with Python (<code>mysql.connector</code>).</p></li><li><p>Day 79: <code>pandas.read_sql</code>.</p></li><li><p>Day 80: SQL queries inside Python ETL.</p></li><li><p>Day 81&#8211;84: <strong>Mini Project</strong> &#8594; SQL &#8594; pandas &#8594; ML pipeline.</p></li></ul><div><hr></div><h2>&#127919; Final Capstone Project (Days 85&#8211;90)</h2><p><strong>Applies Chapters 1&#8211;10 together</strong></p><p><strong>Goal:</strong> Build a <strong>SQL-powered Feature Store</strong> for ML.<br>Steps:</p><ol><li><p>Create sample e-commerce DB (<code>customers</code>, <code>orders</code>, <code>transactions</code>).</p></li><li><p>Clean text &amp; missing values (Ch. 8).</p></li><li><p>Engineer features (Ch. 2, 5, 10):</p><ul><li><p>Total spend</p></li><li><p>Avg transaction value</p></li><li><p>Recency</p></li><li><p>Cumulative revenue</p></li><li><p>Churn flag</p></li></ul></li><li><p>Store results in <code>customer_features</code>.</p></li><li><p>Use Python (<code>pandas.read_sql</code>) to train ML model (predict churn).</p></li></ol><div><hr></div><p>&#9989; With this 90-day plan (mapped to <strong>Chapters 1&#8211;10</strong>), you&#8217;ll:</p><ul><li><p>Learn SQL step by step.</p></li><li><p>Build <strong>real-world projects</strong>.</p></li><li><p>Be ready for <strong>AI/Data/ML jobs</strong>.</p></li></ul><div><hr></div><p></p><h1>Chapter 1 &#8212; MySQL Foundations (Layman, detailed + runnable examples)</h1><p>This chapter introduces the basics of SQL &#8212; tables, rows, columns, primary/foreign keys.<br>You&#8217;ll learn how to retrieve data with <code>SELECT</code>, filter using <code>WHERE</code>, sort with <code>ORDER BY</code>, and limit results.<br>It also covers creating, inserting, updating, and deleting records.<br>These are the building blocks for everything else in SQL.</p><div><hr></div><h2>Quick friendly overview (layman)</h2><p>Think of a <strong>database</strong> like a giant spreadsheet cabinet. Each <strong>table</strong> is one spreadsheet (sheet) inside the cabinet. A <strong>row</strong> is one line in the sheet (one record), and each <strong>column</strong> is a field (like &#8220;Name&#8221;, &#8220;Date&#8221;, &#8220;Price&#8221;).</p><p><strong>SQL</strong> (Structured Query Language) is the language we use to talk to the cabinet: read sheets, add new rows, change things, or create new sheets.</p><p>Important categories of SQL commands &#8212; imagine kitchen tasks:</p><ul><li><p><strong>DDL (Data Definition Language)</strong> &#8212; building the kitchen: <code>CREATE TABLE</code>, <code>ALTER TABLE</code>, <code>DROP TABLE</code>.</p></li><li><p><strong>DML (Data Manipulation Language)</strong> &#8212; cooking: <code>INSERT</code>, <code>UPDATE</code>, <code>DELETE</code>.</p></li><li><p><strong>DQL (Data Query Language)</strong> &#8212; tasting: <code>SELECT</code> (reading data).</p></li><li><p><strong>DCL (Data Control Language)</strong> &#8212; who can use the kitchen: <code>GRANT</code>, <code>REVOKE</code>. (Often admin-only.)</p></li><li><p><strong>TCL (Transaction Control Language)</strong> &#8212; commit or undo steps: <code>START TRANSACTION</code>, <code>COMMIT</code>, <code>ROLLBACK</code>.</p></li></ul><p>We&#8217;ll focus on the parts you need for AI / Data work: reading (SELECT), filtering, simple DDL/DML so you can create sample data to practise.</p><div><hr></div><h2>1. Key concepts in plain words</h2><h3>Tables, rows, columns</h3><ul><li><p><strong>Table</strong> = a named collection of rows (like a spreadsheet).</p></li><li><p><strong>Row</strong> = one record (one person, one sale).</p></li><li><p><strong>Column</strong> = an attribute (name, price, date).</p></li><li><p><strong>Primary key (PK)</strong> = a column (or set) that uniquely identifies each row (like student ID).</p></li><li><p><strong>Foreign key (FK)</strong> = a column that points to a primary key in another table (a link between tables).</p></li></ul><h3>SELECT / FROM / WHERE (basic idea)</h3><ul><li><p><strong>SELECT</strong> = which columns you want to see.</p></li><li><p><strong>FROM</strong> = which table you want to read from.</p></li><li><p><strong>WHERE</strong> = rules to pick only rows you care about (filters).</p></li></ul><h3>Filtering operators (layman)</h3><ul><li><p><code>=</code> equals, <code>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code>, <code>&gt;=</code> compare numbers or dates.</p></li><li><p><code>&lt;&gt;</code> means not equal.</p></li><li><p><code>BETWEEN a AND b</code> means between two values (inclusive).</p></li><li><p><code>IN (a, b, c)</code> means the column value is one of these.</p></li><li><p><code>LIKE &#8216;foo%&#8217;</code> pattern matching (starts with foo).</p></li><li><p><code>IS NULL</code> checks missing values.</p></li></ul><h3>ORDER BY and LIMIT</h3><ul><li><p><code>ORDER BY</code> sorts results (e.g., newest first).</p></li><li><p><code>LIMIT</code> returns only the top N results (useful for samples, quick checks).</p></li></ul><h3>Aliases</h3><ul><li><p><code>AS</code> gives a temporary name to a column or table in the result (handy for readable outputs).</p></li></ul><div><hr></div><h2>2. Setup note (how I wrote the examples)</h2><p>Every example below is a self-contained SQL block.<br><strong>Each block starts with </strong><code>DROP TABLE IF EXISTS</code> so you can copy-paste any single example into a MySQL client and it will run cleanly. If you run many examples in the same session, the <code>DROP</code> ensures there are no conflicts.</p><div><hr></div><h2>Example 1 &#8212; Basic SELECT: show all columns, select some columns</h2><p><strong>What it teaches (layman):</strong> how to list rows and pick columns &#8212; the most common step in data work.</p><p>Run this whole block in MySQL:</p><pre><code><code>-- Example 1: Basic SELECT
DROP TABLE IF EXISTS employees;
CREATE TABLE employees (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100),
  role VARCHAR(60),
  salary INT,
  hire_date DATE,
  department VARCHAR(60)
);

INSERT INTO employees (name, role, salary, hire_date, department) VALUES
(&#8217;Alice Johnson&#8217;,&#8217;Data Analyst&#8217;,55000,&#8217;2020-03-15&#8217;,&#8217;Analytics&#8217;),
(&#8217;Bob Smith&#8217;,&#8217;ML Engineer&#8217;,90000,&#8217;2019-07-01&#8217;,&#8217;AI&#8217;),
(&#8217;Carla Gomez&#8217;,&#8217;Data Scientist&#8217;,85000,&#8217;2021-11-20&#8217;,&#8217;AI&#8217;),
(&#8217;Dan Lee&#8217;,&#8217;Intern&#8217;,15000,&#8217;2024-06-01&#8217;,&#8217;Analytics&#8217;),
(&#8217;Eve Miller&#8217;,&#8217;Software Engineer&#8217;,75000,&#8217;2018-01-10&#8217;,&#8217;Engineering&#8217;),
(&#8217;Frank Wu&#8217;,&#8217;Data Engineer&#8217;,72000,&#8217;2022-02-28&#8217;,&#8217;Data Platform&#8217;);

-- 1a) show everything
SELECT * FROM employees;

-- 1b) show only name and role
SELECT name, role FROM employees;

-- 1c) show only rows where department = &#8216;AI&#8217;
SELECT * FROM employees WHERE department = &#8216;AI&#8217;;
</code></code></pre><p><strong>Plain explanation:</strong></p><ul><li><p><code>SELECT * FROM employees;</code> returns every column for every employee (the whole sheet).</p></li><li><p><code>SELECT name, role</code> picks only two columns (like hiding the others).</p></li><li><p><code>WHERE department = &#8216;AI&#8217;</code> filters to show only employees whose department is AI.</p></li></ul><div><hr></div><h2>Example 2 &#8212; Filtering operators: =, &lt;, &gt;, &lt;&gt;, BETWEEN, IN, LIKE, IS NULL</h2><p><strong>What it teaches (layman):</strong> how to ask specific questions: &#8220;show me people who earn more than X&#8221; or &#8220;show names that start with A&#8221;.</p><p>Run this block:</p><pre><code><code>-- Example 2: Filtering operators
DROP TABLE IF EXISTS products;
CREATE TABLE products (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(120),
  category VARCHAR(60),
  price DECIMAL(8,2),
  stock INT,
  added_on DATE,
  notes VARCHAR(200)
);

INSERT INTO products (name, category, price, stock, added_on, notes) VALUES
(&#8217;USB Cable&#8217;,&#8217;Accessories&#8217;,5.99,250,&#8217;2024-01-10&#8217;, NULL),
(&#8217;Gaming Mouse&#8217;,&#8217;Peripherals&#8217;,49.99,40,&#8217;2023-11-05&#8217;,&#8217;Limited edition&#8217;),
(&#8217;Webcam HD&#8217;,&#8217;Peripherals&#8217;,79.99,0,&#8217;2022-09-12&#8217;, &#8216;discontinued&#8217;),
(&#8217;Laptop Stand&#8217;,&#8217;Accessories&#8217;,29.99,120,&#8217;2024-05-20&#8217;, NULL),
(&#8217;Office Chair&#8217;,&#8217;Furniture&#8217;,199.99,10,&#8217;2021-04-15&#8217;, NULL),
(&#8217;Mechanical Keyboard&#8217;,&#8217;Peripherals&#8217;,129.50,8,&#8217;2023-12-01&#8217;, NULL);

-- Examples of filters:

-- equals
SELECT * FROM products WHERE category = &#8216;Peripherals&#8217;;

-- greater than / less than
SELECT name, price FROM products WHERE price &gt; 50;

-- not equal
SELECT name, price FROM products WHERE price &lt;&gt; 79.99;

-- BETWEEN (inclusive)
SELECT name, price FROM products WHERE price BETWEEN 30 AND 150;

-- IN (one of)
SELECT name, category FROM products WHERE category IN (&#8217;Accessories&#8217;, &#8216;Furniture&#8217;);

-- LIKE (pattern) - starts with &#8216;Web&#8217;
SELECT * FROM products WHERE name LIKE &#8216;Web%&#8217;;

-- IS NULL (missing note)
SELECT * FROM products WHERE notes IS NULL;
</code></code></pre><p><strong>Plain explanation:</strong></p><ul><li><p><code>price &gt; 50</code> shows only expensive items.</p></li><li><p><code>&lt;&gt;</code> means &#8220;not equal&#8221;.</p></li><li><p><code>BETWEEN 30 AND 150</code> returns items priced between 30 and 150.</p></li><li><p><code>IN (&#8217;Accessories&#8217;, &#8216;Furniture&#8217;)</code> is like asking &#8220;is category one of this list?&#8221;</p></li><li><p><code>LIKE &#8216;Web%&#8217;</code> matches names that start with &#8220;Web&#8221;.</p></li><li><p><code>IS NULL</code> checks for missing values (no note).</p></li></ul><div><hr></div><h2>Example 3 &#8212; ORDER BY and LIMIT (show top/bottom results)</h2><p><strong>What it teaches (layman):</strong> how to sort results and take the first N rows &#8212; e.g., top earners, latest dates.</p><p>Run this block:</p><pre><code><code>-- Example 3: ORDER BY and LIMIT
DROP TABLE IF EXISTS sales;
CREATE TABLE sales (
  id INT AUTO_INCREMENT PRIMARY KEY,
  product VARCHAR(120),
  amount DECIMAL(10,2),
  sale_date DATE,
  region VARCHAR(60)
);

INSERT INTO sales (product, amount, sale_date, region) VALUES
(&#8217;USB Cable&#8217;, 5.99, &#8216;2024-09-01&#8217;, &#8216;Europe&#8217;),
(&#8217;Office Chair&#8217;, 199.99, &#8216;2024-08-20&#8217;, &#8216;US&#8217;),
(&#8217;Mechanical Keyboard&#8217;, 129.50, &#8216;2024-09-10&#8217;, &#8216;Asia&#8217;),
(&#8217;Laptop Stand&#8217;, 29.99, &#8216;2024-07-31&#8217;, &#8216;Europe&#8217;),
(&#8217;Gaming Mouse&#8217;, 49.99, &#8216;2024-09-12&#8217;, &#8216;US&#8217;),
(&#8217;Webcam HD&#8217;, 79.99, &#8216;2024-08-25&#8217;, &#8216;APAC&#8217;);

-- Show newest sales first
SELECT * FROM sales ORDER BY sale_date DESC;

-- Show top 3 largest sales amounts
SELECT * FROM sales ORDER BY amount DESC LIMIT 3;

-- Show cheapest 2 sales
SELECT * FROM sales ORDER BY amount ASC LIMIT 2;
</code></code></pre><p><strong>Plain explanation:</strong></p><ul><li><p><code>ORDER BY sale_date DESC</code> sorts newest first (<code>DESC</code> = descending).</p></li><li><p><code>LIMIT 3</code> returns only the top 3 rows after sorting.</p></li><li><p>Combine them to get &#8220;top N&#8221; or &#8220;bottom N&#8221;.</p></li></ul><div><hr></div><h2>Example 4 &#8212; Aliases (AS) and simple expressions</h2><p><strong>What it teaches (layman):</strong> make query columns readable, and compute new values on the fly (e.g., add tax or bonuses).</p><p>Run this block:</p><pre><code><code>-- Example 4: Aliases and expressions
DROP TABLE IF EXISTS employees2;
CREATE TABLE employees2 (
  id INT AUTO_INCREMENT PRIMARY KEY,
  first_name VARCHAR(50),
  last_name VARCHAR(50),
  salary INT
);

INSERT INTO employees2 (first_name, last_name, salary) VALUES
(&#8217;Alice&#8217;,&#8217;Johnson&#8217;,55000),
(&#8217;Bob&#8217;,&#8217;Smith&#8217;,90000),
(&#8217;Carla&#8217;,&#8217;Gomez&#8217;,85000),
(&#8217;Eve&#8217;,&#8217;Miller&#8217;,75000);

-- Full name with alias, salary with a 10% bonus calculation
SELECT 
  id,
  CONCAT(first_name, &#8216; &#8216;, last_name) AS full_name,
  salary AS base_salary,
  salary * 1.10 AS salary_with_10pct_bonus
FROM employees2;

-- Using alias in ORDER BY
SELECT CONCAT(first_name,&#8217; &#8216;,last_name) AS full_name, salary
FROM employees2
ORDER BY salary DESC;
</code></code></pre><p><strong>Plain explanation:</strong></p><ul><li><p><code>AS full_name</code> gives the computed column a friendly name in output.</p></li><li><p><code>salary * 1.10</code> calculates a new value; we can show it with an alias.</p></li><li><p>Aliases make output easier to read (especially in reports).</p></li></ul><div><hr></div><h2>Example 5 &#8212; Combining conditions (AND / OR / NOT), and <code>LIMIT</code> practical use</h2><p><strong>What it teaches (layman):</strong> combine multiple rules: &#8220;find all ML Engineers in AI earning &gt; 80k&#8221; or &#8220;employees not in Engineering&#8221;.</p><p>Run this block:</p><pre><code><code>-- Example 5: Logical operators AND / OR / NOT
DROP TABLE IF EXISTS employees3;
CREATE TABLE employees3 (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100),
  role VARCHAR(60),
  salary INT,
  department VARCHAR(60)
);

INSERT INTO employees3 (name, role, salary, department) VALUES
(&#8217;Alice Johnson&#8217;,&#8217;Data Analyst&#8217;,55000,&#8217;Analytics&#8217;),
(&#8217;Bob Smith&#8217;,&#8217;ML Engineer&#8217;,90000,&#8217;AI&#8217;),
(&#8217;Carla Gomez&#8217;,&#8217;Data Scientist&#8217;,85000,&#8217;AI&#8217;),
(&#8217;Eve Miller&#8217;,&#8217;Software Engineer&#8217;,75000,&#8217;Engineering&#8217;),
(&#8217;Gina Park&#8217;,&#8217;ML Engineer&#8217;,82000,&#8217;AI&#8217;),
(&#8217;Harry Fox&#8217;,&#8217;Support Engineer&#8217;,45000,&#8217;Customer Success&#8217;);

-- ML Engineers in AI earning &gt; 80k
SELECT * FROM employees3
WHERE role = &#8216;ML Engineer&#8217; AND department = &#8216;AI&#8217; AND salary &gt; 80000;

-- Everyone who is NOT in Engineering
SELECT * FROM employees3 WHERE NOT (department = &#8216;Engineering&#8217;);

-- ML Engineers OR Data Scientists
SELECT * FROM employees3
WHERE role = &#8216;ML Engineer&#8217; OR role = &#8216;Data Scientist&#8217;;

-- Combine and limit (top 2 high-paid people)
SELECT * FROM employees3
ORDER BY salary DESC
LIMIT 2;
</code></code></pre><p><strong>Plain explanation:</strong></p><ul><li><p><code>AND</code> narrows down (all conditions must be true).</p></li><li><p><code>OR</code> widens (any condition true).</p></li><li><p><code>NOT</code> reverses a condition.</p></li><li><p>Use parentheses if logic gets complicated.</p></li></ul><div><hr></div><h2>Example 6 &#8212; DDL &amp; DML basics: CREATE TABLE, INSERT, UPDATE, DELETE, and a SIMPLE TRANSACTION (TCL)</h2><p><strong>What it teaches (layman):</strong> how to create tables, change data, and how to use transactions to make changes safe (commit or undo).</p><p>Run this block:</p><pre><code><code>-- Example 6: DDL / DML and a simple transaction example
DROP TABLE IF EXISTS customers;
CREATE TABLE customers (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100),
  email VARCHAR(120),
  wallet_balance DECIMAL(10,2)
);

-- Insert
INSERT INTO customers (name, email, wallet_balance) VALUES
(&#8217;Nina Brown&#8217;, &#8216;nina@example.com&#8217;, 150.00),
(&#8217;Omar Khan&#8217;, &#8216;omar@example.com&#8217;, 300.00),
(&#8217;Priya Singh&#8217;, &#8216;priya@example.com&#8217;, 20.00);

-- Update (customer spent 30)
UPDATE customers SET wallet_balance = wallet_balance - 30 WHERE name = &#8216;Nina Brown&#8217;;

-- Delete (remove a customer)
DELETE FROM customers WHERE name = &#8216;Priya Singh&#8217;;

-- Inspect final table
SELECT * FROM customers;

-- Simple transaction: move 50 from Omar to Nina (two-step change)
START TRANSACTION;
  UPDATE customers SET wallet_balance = wallet_balance - 50 WHERE name = &#8216;Omar Khan&#8217;;
  UPDATE customers SET wallet_balance = wallet_balance + 50 WHERE name = &#8216;Nina Brown&#8217;;
-- If both updates look good, commit:
COMMIT;
-- If something went wrong, we could instead run: ROLLBACK;
</code></code></pre><p><strong>Plain explanation:</strong></p><ul><li><p><code>CREATE TABLE</code>: makes the sheet with columns.</p></li><li><p><code>INSERT</code>: adds rows.</p></li><li><p><code>UPDATE</code>: changes existing rows (be careful with WHERE &#8212; missing WHERE updates all rows).</p></li><li><p><code>DELETE</code>: removes rows (again watch the WHERE).</p></li><li><p><code>START TRANSACTION</code> + <code>COMMIT</code> ensures a group of changes happen together; <code>ROLLBACK</code> undoes them.</p></li></ul><blockquote><p><strong>Safety tip:</strong> Always run <code>SELECT</code> to preview rows your <code>UPDATE</code> or <code>DELETE</code> will affect before executing them.</p></blockquote><div><hr></div><h2>Mini cheat-sheet (commands you&#8217;ll use most)</h2><ul><li><p><code>SELECT columns FROM table WHERE condition;</code></p></li><li><p><code>SELECT * FROM table;</code></p></li><li><p><code>INSERT INTO table (c1,c2) VALUES (v1,v2);</code></p></li><li><p><code>UPDATE table SET column = value WHERE condition;</code></p></li><li><p><code>DELETE FROM table WHERE condition;</code></p></li><li><p><code>CREATE TABLE ...;</code> / <code>DROP TABLE IF EXISTS table;</code></p></li><li><p><code>ORDER BY column [ASC|DESC] LIMIT n;</code></p></li><li><p><code>JOIN</code> (we&#8217;ll cover joins in the next chapter)</p></li><li><p><code>START TRANSACTION; ... COMMIT;</code> / <code>ROLLBACK;</code></p></li></ul><div><hr></div><h2>10 Exercises (Chapter 1 &#8212; Foundations)</h2><blockquote><p>Run the example creation blocks above first so the example tables (<code>employees</code>, <code>products</code>, <code>sales</code>, <code>employees2</code>, <code>employees3</code>, <code>customers</code>) exist. Each exercise expects those sample tables. If you prefer, re-run the example blocks (each is self-contained).</p></blockquote><ol><li><p><strong>List names and roles</strong> &#8212; Write a query to show only <code>name</code> and <code>role</code> from <code>employees</code> (Example 1).</p></li><li><p><strong>High earners</strong> &#8212; Show all columns from <code>employees</code> where <code>salary &gt;= 80000</code>.</p></li><li><p><strong>Pattern search</strong> &#8212; From <code>products</code>, find product rows where <code>name</code> contains the substring <code>Keyboard</code> (use <code>LIKE</code>).</p></li><li><p><strong>Price range</strong> &#8212; From <code>products</code> select <code>name</code> and <code>price</code> for products priced between 30 and 130.</p></li><li><p><strong>Top sales</strong> &#8212; From <code>sales</code>, show the top 2 sales by <code>amount</code>.</p></li><li><p><strong>Not in department</strong> &#8212; From <code>employees3</code>, show people who are <strong>not</strong> in <code>AI</code> department.</p></li><li><p><strong>Alias and expression</strong> &#8212; From <code>employees2</code> create a column <code>full_name</code> by concatenating first and last name and compute <code>salary_with_tax</code> assuming tax is 20% (i.e., salary * 0.8). Show <code>full_name</code> and <code>salary_with_tax</code>.</p></li><li><p><strong>Update safety check</strong> &#8212; Write an <code>UPDATE</code> that would reduce <code>wallet_balance</code> by 100 for <code>Omar Khan</code>, but first write a <code>SELECT</code> that confirms <code>Omar Khan</code> has at least 100 before running the <code>UPDATE</code>.</p></li><li><p><strong>Delete cautious</strong> &#8212; Write a <code>DELETE</code> to remove products that are <code>price &lt; 10</code> and <code>stock = 0</code>. But first write the <code>SELECT</code> to preview what would be deleted.</p></li><li><p><strong>Combined filter</strong> &#8212; From <code>employees3</code>, find all <code>ML Engineer</code> or <code>Data Scientist</code> who earn more than 80k, order by salary descending, and show only the top 3 results.</p></li></ol><div><hr></div><h2>Small checklist for learners (practical tips)</h2><ul><li><p>Always run <code>SELECT</code> with the same <code>WHERE</code> conditions before <code>UPDATE</code>/<code>DELETE</code>.</p></li><li><p>Use <code>LIMIT</code> when experimenting to avoid huge results.</p></li><li><p>Use <code>DROP TABLE IF EXISTS</code> in practice scripts when you want a clean run.</p></li><li><p>Prefer <code>AUTO_INCREMENT</code> keys for small practice tables.</p></li><li><p>Use <code>START TRANSACTION</code> + <code>ROLLBACK</code> while testing multi-step changes.</p></li></ul><div><hr></div><p></p><div><hr></div><h1>Chapter 2 &#8212; Aggregations &amp; Grouping (MySQL for AI/Data/ML)</h1><p>Here you&#8217;ll learn how to summarize data using functions like <code>COUNT</code>, <code>SUM</code>, <code>AVG</code>, <code>MIN</code>, and <code>MAX</code>.<br><code>GROUP BY</code> lets you create summaries per category, while <code>HAVING</code> filters groups after aggregation.<br><code>DISTINCT</code> helps find unique values in a column.<br>This is crucial for EDA (Exploratory Data Analysis) and feature engineering in ML.</p><div><hr></div><h2>1. Layman Explanation</h2><p>Imagine you have a <strong>list of sales</strong> in your shop. You want to know:</p><ul><li><p>How many sales happened? &#8594; <code>COUNT()</code></p></li><li><p>What was the total money earned? &#8594; <code>SUM()</code></p></li><li><p>What&#8217;s the average bill amount? &#8594; <code>AVG()</code></p></li><li><p>What&#8217;s the cheapest and most expensive sale? &#8594; <code>MIN(), MAX()</code></p></li></ul><p>These are called <strong>aggregate functions</strong> because they &#8220;squash&#8221; many rows into a single number.</p><h3>GROUP BY (super important!)</h3><ul><li><p><code>GROUP BY</code> tells SQL: &#8220;Instead of one big total, give me totals per category.&#8221;</p></li><li><p>Example: &#8220;How much revenue per region?&#8221; or &#8220;Average salary per department?&#8221;</p></li><li><p>Without <code>GROUP BY</code>, aggregate applies to the whole table.</p></li><li><p>With <code>GROUP BY</code>, aggregate applies per group.</p></li></ul><h3>HAVING vs WHERE</h3><ul><li><p><code>WHERE</code> filters <strong>before</strong> grouping (on individual rows).</p></li><li><p><code>HAVING</code> filters <strong>after</strong> grouping (on group results).</p></li><li><p>Example:</p><ul><li><p><code>WHERE salary &gt; 50000</code> &#8594; only employees above 50k are considered in groups.</p></li><li><p><code>HAVING AVG(salary) &gt; 70000</code> &#8594; only departments whose average salary &gt; 70k are kept.</p></li></ul></li></ul><h3>DISTINCT</h3><ul><li><p>Removes duplicates before showing results.</p></li><li><p>Example: &#8220;How many unique departments exist?&#8221; &#8594; <code>SELECT COUNT(DISTINCT department) ...</code></p></li></ul><div><hr></div><h2>2. Examples (fully runnable SQL blocks)</h2><div><hr></div><h3>Example 1 &#8212; Basic aggregates without grouping</h3><pre><code><code>-- Example 1: Aggregates on whole table
DROP TABLE IF EXISTS sales2;
CREATE TABLE sales2 (
  id INT AUTO_INCREMENT PRIMARY KEY,
  product VARCHAR(100),
  region VARCHAR(50),
  amount DECIMAL(10,2),
  sale_date DATE
);

INSERT INTO sales2 (product, region, amount, sale_date) VALUES
(&#8217;USB Cable&#8217;,&#8217;Europe&#8217;,5.99,&#8217;2024-09-01&#8217;),
(&#8217;Office Chair&#8217;,&#8217;US&#8217;,199.99,&#8217;2024-08-20&#8217;),
(&#8217;Mechanical Keyboard&#8217;,&#8217;Asia&#8217;,129.50,&#8217;2024-09-10&#8217;),
(&#8217;Laptop Stand&#8217;,&#8217;Europe&#8217;,29.99,&#8217;2024-07-31&#8217;),
(&#8217;Gaming Mouse&#8217;,&#8217;US&#8217;,49.99,&#8217;2024-09-12&#8217;),
(&#8217;Webcam HD&#8217;,&#8217;APAC&#8217;,79.99,&#8217;2024-08-25&#8217;),
(&#8217;Laptop Stand&#8217;,&#8217;Europe&#8217;,29.99,&#8217;2024-09-05&#8217;);

-- Total revenue
SELECT SUM(amount) AS total_revenue FROM sales2;

-- Average sale value
SELECT AVG(amount) AS average_sale FROM sales2;

-- Highest and lowest sale amounts
SELECT MIN(amount) AS cheapest, MAX(amount) AS costliest FROM sales2;

-- Count rows (sales)
SELECT COUNT(*) AS total_sales FROM sales2;
</code></code></pre><div><hr></div><h3>Example 2 &#8212; GROUP BY one column</h3><pre><code><code>-- Example 2: Grouping by region
SELECT region, SUM(amount) AS region_revenue
FROM sales2
GROUP BY region;

-- Average sale per region
SELECT region, AVG(amount) AS avg_sale
FROM sales2
GROUP BY region;
</code></code></pre><p><strong>Explanation:</strong><br>Each region is grouped separately. <code>SUM(amount)</code> is calculated per region instead of for the whole table.</p><div><hr></div><h3>Example 3 &#8212; GROUP BY multiple columns</h3><pre><code><code>-- Example 3: Group by region and product
SELECT region, product, COUNT(*) AS sales_count, SUM(amount) AS total_revenue
FROM sales2
GROUP BY region, product
ORDER BY region, product;
</code></code></pre><p><strong>Explanation:</strong><br>We grouped by both <code>region</code> and <code>product</code>, so we get one row for each region-product combination.</p><div><hr></div><h3>Example 4 &#8212; HAVING vs WHERE</h3><pre><code><code>-- Example 4: Difference between WHERE and HAVING

-- WHERE: only sales above 30 are considered before grouping
SELECT region, SUM(amount) AS region_revenue
FROM sales2
WHERE amount &gt; 30
GROUP BY region;

-- HAVING: first group, then filter regions with total revenue &gt; 100
SELECT region, SUM(amount) AS region_revenue
FROM sales2
GROUP BY region
HAVING SUM(amount) &gt; 100;
</code></code></pre><div><hr></div><h3>Example 5 &#8212; DISTINCT values</h3><pre><code><code>-- Example 5: DISTINCT examples

-- Unique regions
SELECT DISTINCT region FROM sales2;

-- How many unique products sold?
SELECT COUNT(DISTINCT product) AS unique_products FROM sales2;
</code></code></pre><div><hr></div><h3>Example 6 &#8212; Combine aggregates with ORDER BY and LIMIT</h3><pre><code><code>-- Example 6: Top performing region by revenue
SELECT region, SUM(amount) AS total_revenue
FROM sales2
GROUP BY region
ORDER BY total_revenue DESC
LIMIT 1;
</code></code></pre><div><hr></div><h2>3. Exercises (10 problems)</h2><ol><li><p>Show the <strong>total number of sales</strong> in <code>sales2</code>.</p></li><li><p>Show the <strong>average sale amount</strong> in <code>sales2</code>.</p></li><li><p>Show the <strong>total revenue per product</strong> (GROUP BY product).</p></li><li><p>Show the <strong>total revenue per region</strong>, ordered from highest to lowest.</p></li><li><p>Show the <strong>number of sales per region</strong>.</p></li><li><p>Show <strong>region + total revenue</strong> but only keep regions where revenue &gt; 150 (use <code>HAVING</code>).</p></li><li><p>Find the <strong>cheapest sale amount and costliest sale amount</strong> in <code>sales2</code>.</p></li><li><p>Find how many <strong>unique regions</strong> exist.</p></li><li><p>Find the <strong>average sale per region</strong> but only show regions whose average sale &gt; 50.</p></li><li><p>Which product has the <strong>highest total revenue</strong>? (GROUP BY product, order by SUM, limit 1).</p></li></ol><div><hr></div><p></p><p></p><div><hr></div><h1>Chapter 3 &#8212; Joins (Core for AI/Data/ML)</h1><p>Joins allow you to combine data from multiple tables.<br>You&#8217;ll learn INNER, LEFT, RIGHT, FULL OUTER, SELF, CROSS, and multi-table joins.<br>These are essential for feature engineering, as real-world datasets are often split across tables.<br>Understanding joins is the backbone of relational database work in AI/Data jobs.</p><div><hr></div><h2>1. Layman Explanation</h2><p>Think of <strong>Joins</strong> like putting two spreadsheets side by side and connecting rows based on a common column.</p><ul><li><p><strong>INNER JOIN</strong> &#8594; Only rows that match in both tables (like &#8220;friends you both know&#8221;).</p></li><li><p><strong>LEFT JOIN</strong> &#8594; All rows from the <strong>left table</strong>, even if no match in right (like &#8220;all my friends, and if you know them too, show it; else leave blank&#8221;).</p></li><li><p><strong>RIGHT JOIN</strong> &#8594; Opposite of LEFT JOIN (all rows from right, plus matches from left).</p></li><li><p><strong>FULL OUTER JOIN</strong> (MySQL doesn&#8217;t support directly; can simulate with <code>UNION</code>) &#8594; All rows from both sides, matched where possible.</p></li><li><p><strong>SELF JOIN</strong> &#8594; Joining a table with itself (like comparing people in the same table).</p></li><li><p><strong>CROSS JOIN</strong> &#8594; All combinations of rows (Cartesian product).</p></li><li><p><strong>Multi-table join</strong> &#8594; More than 2 tables.</p></li></ul><p>&#128073; For AI/Data, joins are used to:</p><ul><li><p>Merge <strong>customer info</strong> with <strong>transaction data</strong>.</p></li><li><p>Attach <strong>product categories</strong> to sales.</p></li><li><p>Combine <strong>log tables</strong> with <strong>user profiles</strong>.</p></li></ul><div><hr></div><h2>2. Examples (fully runnable SQL blocks)</h2><div><hr></div><h3>Example 1 &#8212; INNER JOIN</h3><pre><code><code>-- Example 1: INNER JOIN
DROP TABLE IF EXISTS customers2;
CREATE TABLE customers2 (
  id INT PRIMARY KEY,
  name VARCHAR(100),
  city VARCHAR(50)
);

DROP TABLE IF EXISTS orders;
CREATE TABLE orders (
  id INT PRIMARY KEY,
  customer_id INT,
  product VARCHAR(100),
  amount DECIMAL(10,2)
);

INSERT INTO customers2 VALUES
(1, &#8216;Alice&#8217;, &#8216;Paris&#8217;),
(2, &#8216;Bob&#8217;, &#8216;London&#8217;),
(3, &#8216;Carla&#8217;, &#8216;New York&#8217;);

INSERT INTO orders VALUES
(101, 1, &#8216;Laptop&#8217;, 999.99),
(102, 2, &#8216;Mouse&#8217;, 25.50),
(103, 1, &#8216;Keyboard&#8217;, 75.00),
(104, 4, &#8216;Webcam&#8217;, 50.00); -- Note: customer_id 4 doesn&#8217;t exist in customers2

-- Show customers with their orders (only matching ones)
SELECT c.name, c.city, o.product, o.amount
FROM customers2 c
INNER JOIN orders o ON c.id = o.customer_id;
</code></code></pre><p>&#128073; Only customers <strong>with orders</strong> appear (Alice and Bob). Carla appears in <code>customers2</code> but she didn&#8217;t order &#8594; not shown. Order <code>104</code> doesn&#8217;t match any customer &#8594; not shown.</p><div><hr></div><h3>Example 2 &#8212; LEFT JOIN</h3><pre><code><code>-- Example 2: LEFT JOIN
SELECT c.name, c.city, o.product, o.amount
FROM customers2 c
LEFT JOIN orders o ON c.id = o.customer_id;
</code></code></pre><p>&#128073; Shows <strong>all customers</strong>, even if they didn&#8217;t order. Orders missing appear as <code>NULL</code>.</p><div><hr></div><h3>Example 3 &#8212; RIGHT JOIN</h3><pre><code><code>-- Example 3: RIGHT JOIN
SELECT c.name, c.city, o.product, o.amount
FROM customers2 c
RIGHT JOIN orders o ON c.id = o.customer_id;
</code></code></pre><p>&#128073; Shows <strong>all orders</strong>, even if no customer exists. Order <code>104</code> (customer_id 4) is included, with <code>NULL</code> customer info.</p><div><hr></div><h3>Example 4 &#8212; FULL OUTER JOIN simulation</h3><p>MySQL doesn&#8217;t support it directly, but you can simulate:</p><pre><code><code>-- Example 4: FULL OUTER JOIN simulation with UNION
SELECT c.name, c.city, o.product, o.amount
FROM customers2 c
LEFT JOIN orders o ON c.id = o.customer_id

UNION

SELECT c.name, c.city, o.product, o.amount
FROM customers2 c
RIGHT JOIN orders o ON c.id = o.customer_id;
</code></code></pre><p>&#128073; This returns all customers and all orders, whether matched or not.</p><div><hr></div><h3>Example 5 &#8212; SELF JOIN</h3><pre><code><code>-- Example 5: SELF JOIN
DROP TABLE IF EXISTS employees4;
CREATE TABLE employees4 (
  id INT PRIMARY KEY,
  name VARCHAR(100),
  manager_id INT
);

INSERT INTO employees4 VALUES
(1, &#8216;Alice&#8217;, NULL),
(2, &#8216;Bob&#8217;, 1),
(3, &#8216;Carla&#8217;, 1),
(4, &#8216;Dan&#8217;, 2);

-- Show each employee with their manager&#8217;s name
SELECT e.name AS employee, m.name AS manager
FROM employees4 e
LEFT JOIN employees4 m ON e.manager_id = m.id;
</code></code></pre><p>&#128073; Useful for <strong>hierarchies</strong> (e.g., org charts).</p><div><hr></div><h3>Example 6 &#8212; CROSS JOIN</h3><pre><code><code>-- Example 6: CROSS JOIN
DROP TABLE IF EXISTS colors;
CREATE TABLE colors (color VARCHAR(50));
INSERT INTO colors VALUES (&#8217;Red&#8217;), (&#8217;Blue&#8217;);

DROP TABLE IF EXISTS sizes;
CREATE TABLE sizes (size VARCHAR(50));
INSERT INTO sizes VALUES (&#8217;Small&#8217;), (&#8217;Large&#8217;);

-- All combinations
SELECT * FROM colors CROSS JOIN sizes;
</code></code></pre><p>&#128073; Gives 4 combinations: Red-Small, Red-Large, Blue-Small, Blue-Large.</p><div><hr></div><h3>Example 7 &#8212; Multi-table JOIN</h3><pre><code><code>-- Example 7: Multi-table join (customers + orders + payments)
DROP TABLE IF EXISTS payments;
CREATE TABLE payments (
  id INT PRIMARY KEY,
  order_id INT,
  payment_method VARCHAR(50),
  status VARCHAR(50)
);

INSERT INTO payments VALUES
(201, 101, &#8216;Credit Card&#8217;, &#8216;Completed&#8217;),
(202, 102, &#8216;PayPal&#8217;, &#8216;Completed&#8217;),
(203, 103, &#8216;Credit Card&#8217;, &#8216;Pending&#8217;);

-- Join all 3 tables
SELECT c.name, o.product, o.amount, p.payment_method, p.status
FROM customers2 c
INNER JOIN orders o ON c.id = o.customer_id
INNER JOIN payments p ON o.id = p.order_id;
</code></code></pre><p>&#128073; Combines customer, order, and payment info into one result.</p><div><hr></div><h2>3. Exercises (10 problems)</h2><ol><li><p>Using <code>customers2</code> and <code>orders</code>, show all customers with their orders (use <code>LEFT JOIN</code>).</p></li><li><p>Show all orders including those without matching customers (use <code>RIGHT JOIN</code>).</p></li><li><p>List all customers who have <strong>not placed any order</strong> (hint: <code>LEFT JOIN</code> + <code>WHERE o.id IS NULL</code>).</p></li><li><p>List all orders that don&#8217;t have a valid customer (hint: <code>RIGHT JOIN</code> + <code>WHERE c.id IS NULL</code>).</p></li><li><p>Show total spending per customer (use <code>INNER JOIN</code> + <code>GROUP BY</code>).</p></li><li><p>Use <code>SELF JOIN</code> on <code>employees4</code> to list all employees and their managers.</p></li><li><p>From <code>employees4</code>, find employees who <strong>don&#8217;t have a manager</strong>.</p></li><li><p>Generate all color-size combinations with <code>CROSS JOIN</code>.</p></li><li><p>From <code>customers2</code>, <code>orders</code>, and <code>payments</code>, list each customer&#8217;s orders with payment status.</p></li><li><p>Which customer spent the most money in total? (join + <code>SUM(amount)</code> + <code>ORDER BY</code>).</p></li></ol><div><hr></div><p></p><div><hr></div><h1>Chapter 4 &#8212; Subqueries &amp; Derived Tables (MySQL for AI/Data/ML)</h1><p>Subqueries let you nest queries inside others, enabling more complex logic.<br>You&#8217;ll use them in <code>WHERE</code>, <code>SELECT</code>, and <code>FROM</code>, plus explore correlated subqueries.<br><code>EXISTS</code> vs <code>IN</code> helps check presence, while CTEs (<code>WITH</code>) make queries readable.<br>This chapter is about breaking down complex problems into step-by-step SQL logic.</p><div><hr></div><h2>1. Layman Explanation</h2><p>Think of a <strong>subquery</strong> as a &#8220;query inside another query.&#8221;<br>It&#8217;s like answering: <em>&#8220;Before I decide who is above average salary, I first need to calculate the average.&#8221;</em></p><p>There are different kinds of subqueries:</p><ul><li><p><strong>Simple subqueries</strong> &#8594; put a query inside <code>WHERE</code>, <code>SELECT</code>, or <code>FROM</code>.</p></li><li><p><strong>Correlated subqueries</strong> &#8594; the inner query depends on each row of the outer query.</p></li><li><p><strong>EXISTS</strong> vs <strong>IN</strong> &#8594; ways to check if something exists in another set.</p></li><li><p><strong>Derived tables</strong> &#8594; subquery inside <code>FROM</code> (like a temporary table).</p></li><li><p><strong>CTEs (Common Table Expressions)</strong> &#8594; similar to derived tables, but with <code>WITH</code> (more readable).</p></li></ul><p>&#128073; In AI/Data:</p><ul><li><p>Subqueries are used to create <strong>temporary features</strong> (like &#8220;is salary above dept average?&#8221;).</p></li><li><p>Derived tables and CTEs are used in <strong>ETL pipelines</strong>.</p></li></ul><div><hr></div><h2>2. Examples (fully runnable SQL blocks)</h2><div><hr></div><h3>Example 1 &#8212; Subquery in WHERE (find above-average salary)</h3><pre><code><code>-- Example 1: Subquery in WHERE
DROP TABLE IF EXISTS employees5;
CREATE TABLE employees5 (
  id INT PRIMARY KEY,
  name VARCHAR(100),
  department VARCHAR(50),
  salary INT
);

INSERT INTO employees5 VALUES
(1, &#8216;Alice&#8217;, &#8216;AI&#8217;, 90000),
(2, &#8216;Bob&#8217;, &#8216;AI&#8217;, 75000),
(3, &#8216;Carla&#8217;, &#8216;Analytics&#8217;, 60000),
(4, &#8216;Dan&#8217;, &#8216;Analytics&#8217;, 65000),
(5, &#8216;Eve&#8217;, &#8216;Engineering&#8217;, 80000);

-- Find employees earning above average salary (whole company)
SELECT name, salary
FROM employees5
WHERE salary &gt; (SELECT AVG(salary) FROM employees5);
</code></code></pre><p>&#128073; Inner query <code>(SELECT AVG(salary) ...)</code> gives a number.<br>Outer query uses it to filter rows.</p><div><hr></div><h3>Example 2 &#8212; Subquery in SELECT (compare against overall average)</h3><pre><code><code>-- Example 2: Subquery in SELECT
SELECT name, salary,
       (SELECT AVG(salary) FROM employees5) AS company_avg
FROM employees5;
</code></code></pre><p>&#128073; Each row shows salary along with the company average.<br>Useful in feature engineering: create &#8220;relative to average&#8221; features.</p><div><hr></div><h3>Example 3 &#8212; Subquery in FROM (derived table)</h3><pre><code><code>-- Example 3: Subquery in FROM
SELECT dept_summary.department, dept_summary.avg_salary
FROM (
    SELECT department, AVG(salary) AS avg_salary
    FROM employees5
    GROUP BY department
) AS dept_summary
WHERE dept_summary.avg_salary &gt; 70000;
</code></code></pre><p>&#128073; Inner query creates a <strong>temporary table</strong> of average salary per department.<br>Outer query filters only departments with avg &gt; 70k.</p><div><hr></div><h3>Example 4 &#8212; Correlated subquery</h3><pre><code><code>-- Example 4: Correlated subquery
-- Find employees whose salary is above their own department&#8217;s average
SELECT e1.name, e1.department, e1.salary
FROM employees5 e1
WHERE e1.salary &gt; (
    SELECT AVG(e2.salary)
    FROM employees5 e2
    WHERE e2.department = e1.department
);
</code></code></pre><p>&#128073; Here, the inner query depends on <code>e1.department</code>.<br>For each employee, SQL calculates their dept average, then checks if they&#8217;re above it.</p><div><hr></div><h3>Example 5 &#8212; EXISTS vs IN</h3><pre><code><code>-- Example 5: EXISTS vs IN
DROP TABLE IF EXISTS departments;
CREATE TABLE departments (
  id INT PRIMARY KEY,
  name VARCHAR(50)
);

INSERT INTO departments VALUES
(1, &#8216;AI&#8217;),
(2, &#8216;Analytics&#8217;),
(3, &#8216;Engineering&#8217;),
(4, &#8216;HR&#8217;);

-- Show departments that actually have employees (using IN)
SELECT name
FROM departments
WHERE name IN (SELECT DISTINCT department FROM employees5);

-- Same result with EXISTS
SELECT d.name
FROM departments d
WHERE EXISTS (
    SELECT 1 FROM employees5 e WHERE e.department = d.name
);
</code></code></pre><p>&#128073; Both queries return only departments with employees.</p><ul><li><p><code>IN</code> checks values.</p></li><li><p><code>EXISTS</code> just checks if at least one row exists.</p></li></ul><div><hr></div><h3>Example 6 &#8212; CTE with WITH</h3><pre><code><code>-- Example 6: CTE (Common Table Expression)
WITH dept_avg AS (
    SELECT department, AVG(salary) AS avg_salary
    FROM employees5
    GROUP BY department
)
SELECT e.name, e.department, e.salary, d.avg_salary
FROM employees5 e
JOIN dept_avg d ON e.department = d.department;
</code></code></pre><p>&#128073; More readable than nesting subqueries inside <code>FROM</code>.<br>Very useful in big AI pipelines.</p><div><hr></div><h2>3. Exercises (10 problems)</h2><ol><li><p>From <code>employees5</code>, find employees who earn <strong>below the overall average salary</strong>.</p></li><li><p>Show each employee&#8217;s name, salary, and the <strong>overall max salary</strong> (use subquery in <code>SELECT</code>).</p></li><li><p>Show each department&#8217;s average salary using a <strong>derived table</strong> (<code>FROM</code> subquery).</p></li><li><p>Find employees earning <strong>above their department&#8217;s average salary</strong> (use correlated subquery).</p></li><li><p>List all departments that <strong>do not</strong> have any employees (use <code>NOT EXISTS</code>).</p></li><li><p>Use a <strong>CTE</strong> to find departments with average salary above 70k.</p></li><li><p>Show employees who earn <strong>less than the maximum salary</strong> in their department.</p></li><li><p>Use <code>IN</code> to list employees working in <code>departments</code> that exist in <code>employees5</code>.</p></li><li><p>Create a derived table that shows department + employee count, then filter only departments with more than 1 employee.</p></li><li><p>Using CTE, create a column that shows <strong>difference between employee salary and department average</strong>.</p></li></ol><div><hr></div><p></p><div><hr></div><h1>Chapter 5 &#8212; Advanced Filtering &amp; Window Functions</h1><p>This chapter introduces <code>CASE WHEN</code>, NULL handling, and ranking functions (<code>ROW_NUMBER</code>, <code>RANK</code>, <code>DENSE_RANK</code>).<br>Window functions like <code>SUM() OVER</code>, <code>AVG() OVER</code>, <code>LAG</code>, and <code>LEAD</code> enable rolling sums, rankings, and time-series analysis.<br>They allow you to calculate aggregates without losing row-level detail.<br>These are especially powerful for AI/ML features like recency, moving averages, and trends.</p><div><hr></div><h2>1. Layman Explanation</h2><p>So far, we&#8217;ve only worked with <strong>groups</strong> where aggregation squashes rows into one result per group.<br>But sometimes we want <strong>aggregates without losing rows</strong> &#8212; e.g.:</p><ul><li><p>For each employee, show <strong>their salary and the average salary of their department</strong>.</p></li><li><p>For each sale, show the <strong>cumulative revenue up to that day</strong>.</p></li><li><p>For each transaction, show <strong>previous transaction amount</strong>.</p></li></ul><p>&#128073; That&#8217;s where <strong>Window Functions</strong> come in. They work like saying:<br><em>&#8220;Look at a sliding window of rows and calculate something for each row, but don&#8217;t collapse the whole dataset.&#8221;</em></p><div><hr></div><h2>2. Key Functions</h2><ul><li><p><strong>CASE WHEN</strong> &#8594; if/else logic in SQL.</p></li><li><p><strong>NULL handling</strong> &#8594; <code>COALESCE</code>, <code>NULLIF</code>, <code>IFNULL</code>.</p></li><li><p><strong>ROW_NUMBER()</strong> &#8594; unique rank within a partition.</p></li><li><p><strong>RANK()</strong> &#8594; ranking with gaps if ties.</p></li><li><p><strong>DENSE_RANK()</strong> &#8594; ranking without gaps.</p></li><li><p><strong>SUM() OVER()</strong> &#8594; running total.</p></li><li><p><strong>AVG() OVER()</strong> &#8594; moving average.</p></li><li><p><strong>LAG(), LEAD()</strong> &#8594; previous/next row&#8217;s value.</p></li><li><p><strong>Cumulative</strong> functions &#8594; build rolling features for ML.</p></li></ul><div><hr></div><h2>3. Examples (fully runnable SQL)</h2><div><hr></div><h3>Example 1 &#8212; CASE WHEN (conditional column)</h3><pre><code><code>-- Example 1: CASE WHEN
DROP TABLE IF EXISTS employees6;
CREATE TABLE employees6 (
  id INT PRIMARY KEY,
  name VARCHAR(100),
  department VARCHAR(50),
  salary INT
);

INSERT INTO employees6 VALUES
(1, &#8216;Alice&#8217;, &#8216;AI&#8217;, 95000),
(2, &#8216;Bob&#8217;, &#8216;AI&#8217;, 75000),
(3, &#8216;Carla&#8217;, &#8216;Analytics&#8217;, 60000),
(4, &#8216;Dan&#8217;, &#8216;Analytics&#8217;, 45000),
(5, &#8216;Eve&#8217;, &#8216;Engineering&#8217;, 85000);

-- Classify employees by salary
SELECT name, department, salary,
       CASE 
         WHEN salary &gt;= 90000 THEN &#8216;High Earner&#8217;
         WHEN salary BETWEEN 60000 AND 89999 THEN &#8216;Mid Earner&#8217;
         ELSE &#8216;Low Earner&#8217;
       END AS salary_band
FROM employees6;
</code></code></pre><p>&#128073; Like &#8220;if-else&#8221; in Python.</p><div><hr></div><h3>Example 2 &#8212; Handling NULL values</h3><pre><code><code>-- Example 2: COALESCE and NULL handling
DROP TABLE IF EXISTS students;
CREATE TABLE students (
  id INT PRIMARY KEY,
  name VARCHAR(100),
  score INT
);

INSERT INTO students VALUES
(1, &#8216;Alice&#8217;, 90),
(2, &#8216;Bob&#8217;, NULL),
(3, &#8216;Carla&#8217;, 75),
(4, &#8216;Dan&#8217;, NULL);

-- Replace NULL scores with 0
SELECT name, COALESCE(score, 0) AS cleaned_score
FROM students;

-- NULLIF example: returns NULL if both values equal
SELECT NULLIF(100, 100) AS result1, NULLIF(100, 200) AS result2;

-- IFNULL (MySQL-specific)
SELECT name, IFNULL(score, 50) AS filled_score FROM students;
</code></code></pre><div><hr></div><h3>Example 3 &#8212; ROW_NUMBER(), RANK(), DENSE_RANK()</h3><pre><code><code>-- Example 3: Ranking functions
DROP TABLE IF EXISTS sales3;
CREATE TABLE sales3 (
  id INT PRIMARY KEY,
  seller VARCHAR(50),
  region VARCHAR(50),
  amount INT
);

INSERT INTO sales3 VALUES
(1, &#8216;Alice&#8217;,&#8217;Europe&#8217;,500),
(2, &#8216;Bob&#8217;,&#8217;Europe&#8217;,700),
(3, &#8216;Carla&#8217;,&#8217;Europe&#8217;,700),
(4, &#8216;Dan&#8217;,&#8217;US&#8217;,400),
(5, &#8216;Eve&#8217;,&#8217;US&#8217;,900);

-- Row numbers (unique sequence per region)
SELECT seller, region, amount,
       ROW_NUMBER() OVER (PARTITION BY region ORDER BY amount DESC) AS row_num,
       RANK() OVER (PARTITION BY region ORDER BY amount DESC) AS rank_num,
       DENSE_RANK() OVER (PARTITION BY region ORDER BY amount DESC) AS dense_rank_num
FROM sales3;
</code></code></pre><p>&#128073; Differences:</p><ul><li><p><strong>ROW_NUMBER</strong>: unique (1,2,3...).</p></li><li><p><strong>RANK</strong>: ties &#8594; skips numbers (1,2,2,4).</p></li><li><p><strong>DENSE_RANK</strong>: ties &#8594; no gaps (1,2,2,3).</p></li></ul><div><hr></div><h3>Example 4 &#8212; SUM() OVER(), AVG() OVER() (running totals)</h3><pre><code><code>-- Example 4: Running totals
DROP TABLE IF EXISTS orders2;
CREATE TABLE orders2 (
  id INT PRIMARY KEY,
  order_date DATE,
  amount INT
);

INSERT INTO orders2 VALUES
(1, &#8216;2024-09-01&#8217;, 100),
(2, &#8216;2024-09-02&#8217;, 150),
(3, &#8216;2024-09-03&#8217;, 200),
(4, &#8216;2024-09-04&#8217;, 50);

-- Cumulative revenue
SELECT order_date, amount,
       SUM(amount) OVER (ORDER BY order_date) AS cumulative_revenue,
       AVG(amount) OVER (ORDER BY order_date ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS moving_avg
FROM orders2;
</code></code></pre><p>&#128073; Use cases: time series, cumulative features.</p><div><hr></div><h3>Example 5 &#8212; LAG() and LEAD()</h3><pre><code><code>-- Example 5: Lag and Lead
SELECT order_date, amount,
       LAG(amount) OVER (ORDER BY order_date) AS previous_day,
       LEAD(amount) OVER (ORDER BY order_date) AS next_day
FROM orders2;
</code></code></pre><p>&#128073; Useful for <strong>time series prediction</strong> (e.g., yesterday&#8217;s value as a feature).</p><div><hr></div><h2>4. Exercises (10 problems)</h2><ol><li><p>Use <code>CASE WHEN</code> on <code>employees6</code> to classify employees as <strong>Senior (&gt;=90000), Mid (60000&#8211;89999), Junior (&lt;60000)</strong>.</p></li><li><p>In <code>students</code>, replace NULL scores with <code>70</code> using <code>IFNULL</code>.</p></li><li><p>In <code>students</code>, create a new column showing <code>score</code> but if NULL then &#8220;Missing&#8221;. (Hint: <code>CASE WHEN</code>).</p></li><li><p>From <code>sales3</code>, list the <strong>top seller per region</strong> using <code>ROW_NUMBER</code>.</p></li><li><p>From <code>sales3</code>, find sellers who are <strong>tied for first place</strong> (using <code>RANK=1</code>).</p></li><li><p>From <code>orders2</code>, compute <strong>cumulative revenue</strong> by date.</p></li><li><p>From <code>orders2</code>, compute a <strong>3-day moving average</strong> (hint: use <code>ROWS BETWEEN 2 PRECEDING AND CURRENT ROW</code>).</p></li><li><p>From <code>orders2</code>, show each day&#8217;s order and the <strong>previous day&#8217;s order amount</strong> (use <code>LAG</code>).</p></li><li><p>From <code>orders2</code>, show each day&#8217;s order and the <strong>next day&#8217;s order amount</strong> (use <code>LEAD</code>).</p></li><li><p>Combine <code>LAG</code> and <code>LEAD</code> &#8594; show each order with both previous and next day&#8217;s order values.</p></li></ol><div><hr></div><p></p><div><hr></div><h1>Chapter 6 &#8212; Data Manipulation (INSERT, UPDATE, DELETE, MERGE/UPSERT)</h1><p>You&#8217;ll learn how to insert new records, update existing ones, and delete unnecessary rows.<br>Bulk inserts (<code>LOAD DATA</code>) and UPSERT (<code>ON DUPLICATE KEY UPDATE</code>) are introduced for ETL pipelines.<br>Transactions (<code>COMMIT</code>, <code>ROLLBACK</code>) help ensure data integrity.<br>This chapter equips you to manage and clean raw datasets before analysis or modeling.</p><div><hr></div><h2>1. Layman Explanation</h2><p>So far, we&#8217;ve been mostly <strong>reading</strong> data (<code>SELECT</code>).<br>But in real-world projects, you&#8217;ll often need to <strong>change data</strong>:</p><ul><li><p><strong>INSERT</strong> &#8594; add new rows (like writing a new entry into a notebook).</p></li><li><p><strong>UPDATE</strong> &#8594; change existing rows (like correcting a spelling mistake).</p></li><li><p><strong>DELETE</strong> &#8594; remove rows (like tearing a page out).</p></li><li><p><strong>MERGE / UPSERT</strong> &#8594; insert if not exists, update if exists (like &#8220;if student not in class, add them; if already there, update marks&#8221;).</p></li></ul><p>&#128073; For AI/Data/ML:</p><ul><li><p>You&#8217;ll use these to <strong>clean raw datasets</strong>, <strong>fix missing values</strong>, and <strong>load processed data into staging tables</strong>.</p></li></ul><div><hr></div><h2>2. Examples (fully runnable SQL blocks)</h2><div><hr></div><h3>Example 1 &#8212; INSERT (single and multiple rows)</h3><pre><code><code>-- Example 1: INSERT
DROP TABLE IF EXISTS customers3;
CREATE TABLE customers3 (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100),
  email VARCHAR(120),
  balance DECIMAL(10,2)
);

-- Insert one row
INSERT INTO customers3 (name, email, balance)
VALUES (&#8217;Alice&#8217;, &#8216;alice@example.com&#8217;, 100.00);

-- Insert multiple rows at once
INSERT INTO customers3 (name, email, balance) VALUES
(&#8217;Bob&#8217;, &#8216;bob@example.com&#8217;, 250.50),
(&#8217;Carla&#8217;, &#8216;carla@example.com&#8217;, 75.00),
(&#8217;Dan&#8217;, &#8216;dan@example.com&#8217;, 300.00);

-- See results
SELECT * FROM customers3;
</code></code></pre><div><hr></div><h3>Example 2 &#8212; UPDATE</h3><pre><code><code>-- Example 2: UPDATE
-- Add 50 to Carla&#8217;s balance
UPDATE customers3
SET balance = balance + 50
WHERE name = &#8216;Carla&#8217;;

-- Correct Dan&#8217;s email
UPDATE customers3
SET email = &#8216;dan123@example.com&#8217;
WHERE name = &#8216;Dan&#8217;;

-- See updated table
SELECT * FROM customers3;
</code></code></pre><p>&#128073; Always double-check with a <code>SELECT</code> before running <code>UPDATE</code>, or you might change <strong>all rows</strong> accidentally.</p><div><hr></div><h3>Example 3 &#8212; DELETE</h3><pre><code><code>-- Example 3: DELETE
-- Remove Alice from customers
DELETE FROM customers3
WHERE name = &#8216;Alice&#8217;;

-- Check table after delete
SELECT * FROM customers3;
</code></code></pre><p>&#128073; Again, be careful. Forgetting <code>WHERE</code> deletes <strong>everything</strong>.</p><div><hr></div><h3>Example 4 &#8212; Bulk Insert (loading data fast)</h3><pre><code><code>-- Example 4: Bulk Insert
DROP TABLE IF EXISTS products2;
CREATE TABLE products2 (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100),
  category VARCHAR(50),
  price DECIMAL(10,2)
);

-- Multiple insert
INSERT INTO products2 (name, category, price) VALUES
(&#8217;Keyboard&#8217;, &#8216;Peripherals&#8217;, 75.00),
(&#8217;Mouse&#8217;, &#8216;Peripherals&#8217;, 25.00),
(&#8217;Monitor&#8217;, &#8216;Display&#8217;, 200.00),
(&#8217;Chair&#8217;, &#8216;Furniture&#8217;, 150.00);

SELECT * FROM products2;
</code></code></pre><p>&#128073; In real ETL pipelines, bulk inserts are used to <strong>load thousands/millions of rows</strong> quickly (in MySQL &#8594; <code>LOAD DATA INFILE</code> is used for CSVs).</p><div><hr></div><h3>Example 5 &#8212; MERGE / UPSERT (Insert or Update)</h3><pre><code><code>-- Example 5: UPSERT (MySQL specific: ON DUPLICATE KEY UPDATE)
DROP TABLE IF EXISTS inventory;
CREATE TABLE inventory (
  product_id INT PRIMARY KEY,
  product_name VARCHAR(100),
  stock INT
);

-- Insert initial data
INSERT INTO inventory VALUES
(1, &#8216;Laptop&#8217;, 10),
(2, &#8216;Mouse&#8217;, 50);

-- Try inserting a new product (will insert)
INSERT INTO inventory (product_id, product_name, stock)
VALUES (3, &#8216;Keyboard&#8217;, 20)
ON DUPLICATE KEY UPDATE stock = stock + VALUES(stock);

-- Try inserting an existing product (will update stock instead of error)
INSERT INTO inventory (product_id, product_name, stock)
VALUES (2, &#8216;Mouse&#8217;, 30)
ON DUPLICATE KEY UPDATE stock = stock + VALUES(stock);

-- Check results
SELECT * FROM inventory;
</code></code></pre><p>&#128073; Very useful for <strong>data pipelines</strong> when you don&#8217;t know if data already exists.</p><div><hr></div><h3>Example 6 &#8212; Using Transactions (safety)</h3><pre><code><code>-- Example 6: Transactions
START TRANSACTION;

UPDATE customers3 SET balance = balance - 100 WHERE name = &#8216;Bob&#8217;;
UPDATE customers3 SET balance = balance + 100 WHERE name = &#8216;Carla&#8217;;

-- If both look good:
COMMIT;

-- If mistake:
-- ROLLBACK;
</code></code></pre><p>&#128073; Helps maintain <strong>consistency</strong>. In AI workflows, you don&#8217;t want partial updates that break your dataset.</p><div><hr></div><h2>3. Exercises (10 problems)</h2><ol><li><p>Insert a new customer <strong>Eva</strong> with email <code>eva@example.com</code> and balance <code>400</code>.</p></li><li><p>Insert 2 new customers at once:</p><ul><li><p>Frank, <code>frank@example.com</code>, 150</p></li><li><p>Grace, <code>grace@example.com</code>, 250</p></li></ul></li><li><p>Increase <strong>Bob&#8217;s balance by 200</strong>.</p></li><li><p>Decrease <strong>Dan&#8217;s balance by 50</strong>.</p></li><li><p>Delete customer <strong>Eva</strong>.</p></li><li><p>Add 3 new products in <code>products2</code>:</p><ul><li><p>Table (Furniture, 100)</p></li><li><p>Headphones (Peripherals, 60)</p></li><li><p>Camera (Electronics, 500)</p></li></ul></li><li><p>Insert product <code>Mouse</code> into <code>inventory</code> with stock 10 &#8594; it should <strong>update</strong> instead of duplicate.</p></li><li><p>Insert product <code>Monitor</code> into <code>inventory</code> with stock 5 &#8594; it should <strong>add new row</strong>.</p></li><li><p>Use a transaction to move <strong>100 from Carla to Bob</strong>.</p></li><li><p>Use <code>UPDATE</code> to set all customers with balance <code>&lt; 100</code> to <strong>balance = 100</strong> (cleaning).</p></li></ol><div><hr></div><p></p><div><hr></div><h1>Chapter 7 &#8212; Set Operations (UNION, INTERSECT, EXCEPT)</h1><p>Set operations let you combine results from multiple queries.<br><code>UNION</code> merges datasets, <code>UNION ALL</code> keeps duplicates, while <code>INTERSECT</code> and <code>EXCEPT</code> (simulated in MySQL) find overlaps and differences.<br>These operations are useful for comparing periods (e.g., customers this month vs last month).<br>They are often used in retention analysis and anomaly detection.</p><div><hr></div><h2>1. Layman Explanation</h2><p>Think of <strong>set operations</strong> like working with two lists in school math:</p><ul><li><p><strong>UNION</strong> &#8594; A &#8746; B &#8594; combine both sets, remove duplicates.</p></li><li><p><strong>UNION ALL</strong> &#8594; A &#8746; B (with duplicates kept).</p></li><li><p><strong>INTERSECT</strong> &#8594; A &#8745; B &#8594; keep only rows common to both sets.</p></li><li><p><strong>EXCEPT (MINUS)</strong> &#8594; A &#8211; B &#8594; rows in first table but not in second.</p></li></ul><p>&#128073; In AI/Data:</p><ul><li><p><strong>UNION</strong> is like stacking monthly data (Jan + Feb).</p></li><li><p><strong>INTERSECT</strong> helps find common records (customers who are in both campaigns).</p></li><li><p><strong>EXCEPT</strong> helps find anomalies (customers who bought last month but not this month).</p></li></ul><p>&#9888;&#65039; MySQL only directly supports <code>UNION</code> and <code>UNION ALL</code>.<br>For <code>INTERSECT</code> and <code>EXCEPT</code>, we simulate them with <code>JOIN</code> or subqueries.</p><div><hr></div><h2>2. Examples (fully runnable SQL)</h2><div><hr></div><h3>Example 1 &#8212; UNION vs UNION ALL</h3><pre><code><code>-- Example 1: UNION vs UNION ALL
DROP TABLE IF EXISTS sales_jan;
CREATE TABLE sales_jan (
  id INT PRIMARY KEY,
  product VARCHAR(50)
);

DROP TABLE IF EXISTS sales_feb;
CREATE TABLE sales_feb (
  id INT PRIMARY KEY,
  product VARCHAR(50)
);

INSERT INTO sales_jan VALUES
(1,&#8217;Laptop&#8217;), (2,&#8217;Mouse&#8217;), (3,&#8217;Keyboard&#8217;);

INSERT INTO sales_feb VALUES
(4,&#8217;Mouse&#8217;), (5,&#8217;Monitor&#8217;), (6,&#8217;Laptop&#8217;);

-- UNION (duplicates removed)
SELECT product FROM sales_jan
UNION
SELECT product FROM sales_feb;

-- UNION ALL (duplicates kept)
SELECT product FROM sales_jan
UNION ALL
SELECT product FROM sales_feb;
</code></code></pre><p>&#128073; <code>UNION</code> &#8594; {Laptop, Mouse, Keyboard, Monitor}<br>&#128073; <code>UNION ALL</code> &#8594; keeps duplicates (Laptop twice, Mouse twice).</p><div><hr></div><h3>Example 2 &#8212; INTERSECT simulation</h3><pre><code><code>-- Example 2: INTERSECT simulation (common products in both months)
SELECT product FROM sales_jan
WHERE product IN (SELECT product FROM sales_feb);
</code></code></pre><p>&#128073; Only shows <code>Laptop</code> and <code>Mouse</code> (common in both).</p><div><hr></div><h3>Example 3 &#8212; EXCEPT simulation</h3><pre><code><code>-- Example 3: EXCEPT simulation (products in Jan but not in Feb)
SELECT product FROM sales_jan
WHERE product NOT IN (SELECT product FROM sales_feb);
</code></code></pre><p>&#128073; Only <code>Keyboard</code> (exists in Jan but not in Feb).</p><div><hr></div><h3>Example 4 &#8212; EXCEPT (other direction)</h3><pre><code><code>-- Example 4: Products in Feb but not in Jan
SELECT product FROM sales_feb
WHERE product NOT IN (SELECT product FROM sales_jan);
</code></code></pre><p>&#128073; Result: <code>Monitor</code>.</p><div><hr></div><h3>Example 5 &#8212; Combining UNION with other queries</h3><pre><code><code>-- Example 5: Customers active in Jan or Feb
DROP TABLE IF EXISTS customers_jan;
CREATE TABLE customers_jan (name VARCHAR(50));
INSERT INTO customers_jan VALUES (&#8217;Alice&#8217;), (&#8217;Bob&#8217;), (&#8217;Carla&#8217;);

DROP TABLE IF EXISTS customers_feb;
CREATE TABLE customers_feb (name VARCHAR(50));
INSERT INTO customers_feb VALUES (&#8217;Bob&#8217;), (&#8217;Carla&#8217;), (&#8217;Dan&#8217;);

-- All unique customers across Jan+Feb
SELECT name FROM customers_jan
UNION
SELECT name FROM customers_feb;

-- Customers who appeared in both Jan and Feb
SELECT name FROM customers_jan
WHERE name IN (SELECT name FROM customers_feb);

-- Customers only in Jan (not in Feb)
SELECT name FROM customers_jan
WHERE name NOT IN (SELECT name FROM customers_feb);
</code></code></pre><div><hr></div><h2>3. Exercises (10 problems)</h2><ol><li><p>Using <code>sales_jan</code> and <code>sales_feb</code>, get a list of <strong>all unique products</strong> sold (use <code>UNION</code>).</p></li><li><p>Using the same tables, get a list of <strong>all products including duplicates</strong> (use <code>UNION ALL</code>).</p></li><li><p>Find <strong>products common</strong> to both Jan and Feb.</p></li><li><p>Find <strong>products only in Jan</strong> (not in Feb).</p></li><li><p>Find <strong>products only in Feb</strong> (not in Jan).</p></li><li><p>Create <code>sales_mar</code> table, add some products, and combine <strong>Jan + Feb + Mar</strong> into one unique list.</p></li><li><p>Show <strong>customers who shopped in both months</strong> (<code>customers_jan</code> and <code>customers_feb</code>).</p></li><li><p>Show <strong>customers who only shopped in Jan</strong>.</p></li><li><p>Show <strong>customers who only shopped in Feb</strong>.</p></li><li><p>Use <code>UNION</code> to combine Jan and Feb customer lists, then count <strong>how many unique customers</strong> across both months.</p></li></ol><div><hr></div><div><hr></div><h1>Chapter 8 &#8212; Data Cleaning &amp; Transformation</h1><p>Here you&#8217;ll clean messy text with <code>TRIM</code>, <code>UPPER/LOWER</code>, <code>SUBSTRING</code>, and <code>CONCAT</code>.<br>You&#8217;ll fix dates with <code>DATEDIFF</code>, <code>DATE_ADD</code>, and type conversions (<code>CAST</code>).<br>It also introduces pivoting (rows &#8594; columns) and unpivoting (columns &#8594; rows).<br>This chapter is critical for preparing raw data into ML-ready formats.</p><div><hr></div><h2>1. Layman Explanation</h2><p>Think of raw data like messy exam papers: some names misspelled, some blanks, dates written differently, random spaces.<br>Before you can feed it to Python/ML, you must:</p><ul><li><p><strong>Fix text</strong> &#8594; trim spaces, make lowercase/uppercase, extract substrings.</p></li><li><p><strong>Fix dates</strong> &#8594; convert strings to proper dates, calculate differences.</p></li><li><p><strong>Fix types</strong> &#8594; turn numbers stored as text into real numbers.</p></li><li><p><strong>Reshape data</strong> &#8594; pivot (rows &#8594; columns) or unpivot (columns &#8594; rows).</p></li></ul><p>&#128073; Without this, your AI model will get garbage input &#8594; garbage predictions.</p><div><hr></div><h2>2. Examples (fully runnable SQL blocks)</h2><div><hr></div><h3>Example 1 &#8212; String functions</h3><pre><code><code>-- Example 1: String cleaning
DROP TABLE IF EXISTS users_raw;
CREATE TABLE users_raw (
  id INT PRIMARY KEY,
  name VARCHAR(100),
  email VARCHAR(120)
);

INSERT INTO users_raw VALUES
(1, &#8216;   Alice   &#8216;, &#8216;ALICE@EXAMPLE.COM&#8217;),
(2, &#8216;bob&#8217;, &#8216;bob@example.com&#8217;),
(3, &#8216;Carla G.&#8217;, &#8216;carla@example.COM&#8217;);

-- Trim spaces
SELECT id, TRIM(name) AS clean_name FROM users_raw;

-- Uppercase / Lowercase
SELECT id, UPPER(name) AS name_upper, LOWER(email) AS email_lower
FROM users_raw;

-- Substring
SELECT id, SUBSTRING(name, 1, 5) AS first_five_chars FROM users_raw;

-- Concatenate
SELECT id, CONCAT(TRIM(name), &#8216; &lt;&#8217;, LOWER(email), &#8216;&gt;&#8217;) AS formatted_contact
FROM users_raw;
</code></code></pre><p>&#128073; Used to standardize text (emails, names, categories).</p><div><hr></div><h3>Example 2 &#8212; Pattern matching with LIKE / REGEXP</h3><pre><code><code>-- Example 2: Pattern matching
SELECT * FROM users_raw WHERE email LIKE &#8216;%.COM&#8217;;   -- ends with .COM

SELECT * FROM users_raw WHERE name REGEXP &#8216;^[A-Z]&#8217;; -- names starting with capital letter
</code></code></pre><div><hr></div><h3>Example 3 &#8212; Date &amp; time functions</h3><pre><code><code>-- Example 3: Date operations
DROP TABLE IF EXISTS orders3;
CREATE TABLE orders3 (
  id INT PRIMARY KEY,
  customer VARCHAR(50),
  order_date DATE,
  delivery_date DATE
);

INSERT INTO orders3 VALUES
(1,&#8217;Alice&#8217;,&#8217;2024-09-01&#8217;,&#8217;2024-09-05&#8217;),
(2,&#8217;Bob&#8217;,&#8217;2024-09-10&#8217;,&#8217;2024-09-12&#8217;),
(3,&#8217;Carla&#8217;,&#8217;2024-09-15&#8217;,&#8217;2024-09-20&#8217;);

-- Difference in days
SELECT customer, DATEDIFF(delivery_date, order_date) AS delivery_days
FROM orders3;

-- Add/Subtract days
SELECT customer, DATE_ADD(order_date, INTERVAL 7 DAY) AS followup_date
FROM orders3;

-- Extract year/month/day
SELECT customer, YEAR(order_date) AS year, MONTH(order_date) AS month
FROM orders3;
</code></code></pre><p>&#128073; Great for <strong>time-based features</strong> (e.g., delivery delay, recency).</p><div><hr></div><h3>Example 4 &#8212; Data type conversion</h3><pre><code><code>-- Example 4: CAST &amp; CONVERT
DROP TABLE IF EXISTS prices;
CREATE TABLE prices (
  id INT PRIMARY KEY,
  price_text VARCHAR(20)
);

INSERT INTO prices VALUES
(1, &#8216;100.50&#8217;),
(2, &#8216;250&#8217;),
(3, &#8216;75.25&#8217;);

-- Convert text to decimal
SELECT id, price_text, CAST(price_text AS DECIMAL(10,2)) AS price_value
FROM prices;
</code></code></pre><p>&#128073; Useful when data is imported as text but should be numbers.</p><div><hr></div><h3>Example 5 &#8212; Pivoting (rows &#8594; columns)</h3><pre><code><code>-- Example 5: Pivot (manual using CASE)
DROP TABLE IF EXISTS sales4;
CREATE TABLE sales4 (
  id INT PRIMARY KEY,
  product VARCHAR(50),
  region VARCHAR(50),
  amount INT
);

INSERT INTO sales4 VALUES
(1,&#8217;Laptop&#8217;,&#8217;US&#8217;,1000),
(2,&#8217;Laptop&#8217;,&#8217;EU&#8217;,1200),
(3,&#8217;Mouse&#8217;,&#8217;US&#8217;,50),
(4,&#8217;Mouse&#8217;,&#8217;EU&#8217;,70);

-- Pivot: revenue by region as columns
SELECT product,
       SUM(CASE WHEN region=&#8217;US&#8217; THEN amount ELSE 0 END) AS US_revenue,
       SUM(CASE WHEN region=&#8217;EU&#8217; THEN amount ELSE 0 END) AS EU_revenue
FROM sales4
GROUP BY product;
</code></code></pre><p>&#128073; Very handy for reporting features.</p><div><hr></div><h3>Example 6 &#8212; Unpivot (columns &#8594; rows)</h3><pre><code><code>-- Example 6: Unpivot simulation (manual with UNION)
SELECT product, &#8216;US&#8217; AS region, SUM(CASE WHEN region=&#8217;US&#8217; THEN amount ELSE 0 END) AS revenue
FROM sales4 GROUP BY product
UNION
SELECT product, &#8216;EU&#8217; AS region, SUM(CASE WHEN region=&#8217;EU&#8217; THEN amount ELSE 0 END) AS revenue
FROM sales4 GROUP BY product;
</code></code></pre><p>&#128073; Turns wide data back into long format, useful for ML pipelines.</p><div><hr></div><h2>3. Exercises (10 problems)</h2><ol><li><p>From <code>users_raw</code>, clean <code>name</code> by removing spaces and making it all lowercase.</p></li><li><p>From <code>users_raw</code>, show emails in lowercase only.</p></li><li><p>From <code>users_raw</code>, create a new column combining <code>name</code> + <code>&lt;email&gt;</code>.</p></li><li><p>From <code>users_raw</code>, find names starting with &#8220;C&#8221;.</p></li><li><p>From <code>orders3</code>, calculate delivery delay in days.</p></li><li><p>From <code>orders3</code>, extract only the month of each <code>order_date</code>.</p></li><li><p>From <code>orders3</code>, add 30 days to <code>order_date</code> as <code>expected_followup</code>.</p></li><li><p>From <code>prices</code>, convert <code>price_text</code> into decimal and add 10% tax.</p></li><li><p>From <code>sales4</code>, pivot so that each product shows <strong>US and EU revenue separately</strong>.</p></li><li><p>From <code>sales4</code>, unpivot into two columns (<code>product</code>, <code>region_revenue</code>) where region is <code>US</code> or <code>EU</code>.</p></li></ol><div><hr></div><p></p><div><hr></div><h1>Chapter 9 &#8212; Performance &amp; Optimization (Indexes, Query Plans, Tuning)</h1><p>This chapter focuses on speeding up queries for large datasets.<br>You&#8217;ll learn about indexes (clustered and non-clustered), composite indexes, and how to analyze queries with <code>EXPLAIN</code>.<br>It emphasizes writing efficient queries (avoid <code>SELECT *</code>, index joins).<br>Optimized SQL is crucial when working with millions of rows in AI pipelines.</p><div><hr></div><h2>1. Layman Explanation</h2><p>When your database is small, queries feel instant. But with <strong>millions of rows</strong>, a badly written query can take <strong>minutes or hours</strong>.</p><p>&#128073; Imagine searching for a word in a <strong>notebook</strong> vs a <strong>dictionary</strong>:</p><ul><li><p>Notebook &#8594; you scan page by page &#8594; slow.</p></li><li><p>Dictionary &#8594; sorted with an index &#8594; very fast.</p></li></ul><p>SQL has similar ideas: <strong>indexes</strong> and <strong>query plans</strong>.</p><div><hr></div><h3>Key Concepts</h3><ol><li><p><strong>Indexes</strong></p><ul><li><p>Work like a book&#8217;s index &#8594; point directly to rows instead of scanning everything.</p></li><li><p><strong>Clustered index</strong>: table rows stored in order of primary key (only one per table).</p></li><li><p><strong>Non-clustered index</strong>: a separate pointer structure to speed up lookups.</p></li><li><p>Downside: Indexes speed up <code>SELECT</code> but slow down <code>INSERT/UPDATE/DELETE</code> (because they need updating too).</p></li></ul></li><li><p><strong>EXPLAIN keyword</strong></p><ul><li><p>Tells you how MySQL will execute your query.</p></li><li><p>Shows if it uses index or scans whole table (<code>ALL</code>).</p></li></ul></li><li><p><strong>Joins vs Subqueries</strong></p><ul><li><p>Sometimes a join is faster than a subquery, sometimes opposite.</p></li><li><p>Always test with <code>EXPLAIN</code>.</p></li></ul></li><li><p><strong>Best Practices</strong></p><ul><li><p>Use <code>LIMIT</code> while testing queries.</p></li><li><p>Select only required columns (avoid <code>SELECT *</code> in production).</p></li><li><p>Index frequently filtered columns (WHERE, JOIN, ORDER BY).</p></li><li><p>Avoid unnecessary nested subqueries.</p></li></ul></li></ol><div><hr></div><h2>2. Examples (fully runnable SQL)</h2><div><hr></div><h3>Example 1 &#8212; Table scan vs index</h3><pre><code><code>-- Example 1: Index basics
DROP TABLE IF EXISTS big_customers;
CREATE TABLE big_customers (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(100),
  email VARCHAR(120),
  city VARCHAR(50)
);

-- Insert 10 sample rows (imagine millions in real life)
INSERT INTO big_customers (name, email, city) VALUES
(&#8217;Alice&#8217;,&#8217;alice@example.com&#8217;,&#8217;Paris&#8217;),
(&#8217;Bob&#8217;,&#8217;bob@example.com&#8217;,&#8217;London&#8217;),
(&#8217;Carla&#8217;,&#8217;carla@example.com&#8217;,&#8217;Paris&#8217;),
(&#8217;Dan&#8217;,&#8217;dan@example.com&#8217;,&#8217;Berlin&#8217;),
(&#8217;Eve&#8217;,&#8217;eve@example.com&#8217;,&#8217;Paris&#8217;),
(&#8217;Frank&#8217;,&#8217;frank@example.com&#8217;,&#8217;London&#8217;),
(&#8217;Gina&#8217;,&#8217;gina@example.com&#8217;,&#8217;Berlin&#8217;),
(&#8217;Hank&#8217;,&#8217;hank@example.com&#8217;,&#8217;Paris&#8217;),
(&#8217;Ivy&#8217;,&#8217;ivy@example.com&#8217;,&#8217;Rome&#8217;),
(&#8217;Jack&#8217;,&#8217;jack@example.com&#8217;,&#8217;Paris&#8217;);

-- Without index: search by city
EXPLAIN SELECT * FROM big_customers WHERE city=&#8217;Paris&#8217;;

-- Create index on city
CREATE INDEX idx_city ON big_customers(city);

-- With index: search by city again
EXPLAIN SELECT * FROM big_customers WHERE city=&#8217;Paris&#8217;;
</code></code></pre><p>&#128073; Before index: <code>type=ALL</code> (full scan).<br>&#128073; After index: uses <code>ref</code> on <code>idx_city</code> (much faster for large data).</p><div><hr></div><h3>Example 2 &#8212; Composite index</h3><pre><code><code>-- Example 2: Composite index
CREATE INDEX idx_city_email ON big_customers(city, email);

-- Query uses both columns
EXPLAIN SELECT * FROM big_customers WHERE city=&#8217;Paris&#8217; AND email=&#8217;alice@example.com&#8217;;
</code></code></pre><p>&#128073; Composite indexes are like <strong>multi-column dictionaries</strong>.</p><div><hr></div><h3>Example 3 &#8212; Avoid SELECT *</h3><pre><code><code>-- Example 3: Bad vs Good
-- Bad (fetches everything)
SELECT * FROM big_customers WHERE city=&#8217;Paris&#8217;;

-- Good (fetch only what you need)
SELECT name, email FROM big_customers WHERE city=&#8217;Paris&#8217;;
</code></code></pre><p>&#128073; Saves memory and network when handling large results.</p><div><hr></div><h3>Example 4 &#8212; Join optimization</h3><pre><code><code>-- Example 4: Join optimization
DROP TABLE IF EXISTS orders4;
CREATE TABLE orders4 (
  id INT PRIMARY KEY AUTO_INCREMENT,
  customer_id INT,
  amount DECIMAL(10,2),
  INDEX (customer_id)  -- index on join column
);

INSERT INTO orders4 (customer_id, amount) VALUES
(1, 200), (2, 150), (1, 300), (3, 400), (5, 250);

-- Check join performance
EXPLAIN
SELECT c.name, o.amount
FROM big_customers c
JOIN orders4 o ON c.id = o.customer_id;
</code></code></pre><p>&#128073; Always <strong>index join columns</strong> (<code>customer_id</code> here).</p><div><hr></div><h3>Example 5 &#8212; Subquery vs Join</h3><pre><code><code>-- Example 5: Subquery vs Join

-- Subquery
EXPLAIN
SELECT name FROM big_customers
WHERE id IN (SELECT customer_id FROM orders4);

-- Join
EXPLAIN
SELECT DISTINCT c.name
FROM big_customers c
JOIN orders4 o ON c.id = o.customer_id;
</code></code></pre><p>&#128073; Both work, but one may be faster depending on data size. Always test.</p><div><hr></div><h2>3. Exercises (10 problems)</h2><ol><li><p>Add an index on <code>email</code> in <code>big_customers</code>. Test with <code>EXPLAIN</code> before &amp; after.</p></li><li><p>Add a composite index on <code>(city, name)</code> and query customers in <code>&#8220;Paris&#8221;</code> with a specific name.</p></li><li><p>Compare performance of <code>SELECT *</code> vs selecting only <code>name,email</code>.</p></li><li><p>Use <code>EXPLAIN</code> to check how MySQL executes <code>SELECT * FROM big_customers WHERE city=&#8217;London&#8217;</code>.</p></li><li><p>Create a new table <code>transactions</code> with <code>customer_id</code>, <code>amount</code>, <code>date</code>. Add an index on <code>customer_id</code>.</p></li><li><p>Join <code>big_customers</code> with <code>orders4</code> and show customer names with amounts. Ensure <code>customer_id</code> is indexed.</p></li><li><p>Find customers who have orders using a <strong>subquery</strong> (<code>IN</code>). Then do the same with a **JOIN<code>. Compare </code>EXPLAIN`.</p></li><li><p>Write a query to show top 3 customers by total order amount (use <code>SUM</code> + <code>GROUP BY</code> + <code>ORDER BY</code>).</p></li><li><p>Drop the index on <code>city</code> and compare query time vs with index.</p></li><li><p>Find all customers from <code>Paris</code> who also have at least 1 order. Ensure optimized query.</p></li></ol><div><hr></div><div><hr></div><h1>Chapter 10 &#8212; AI/Data-Job Specific SQL Topics</h1><p>The final chapter ties everything to real-world AI/ML use cases.<br>You&#8217;ll learn SQL for feature engineering, time-series analysis, ETL workflows, and data quality checks.<br>It also shows SQL integration with Python (<code>pandas</code>, <code>SQLAlchemy</code>) and cloud data warehouses.<br>This equips you to build feature stores and pipelines directly from SQL to ML models.</p><div><hr></div><h2>1. Layman Explanation</h2><p>Up to now, we learned SQL basics, joins, grouping, window functions, etc.<br>But how do we actually use SQL <strong>as a Data Scientist / ML Engineer</strong>?</p><p>&#128073; Typical AI/Data job tasks with SQL:</p><ul><li><p><strong>Feature engineering</strong>: derive new variables (e.g., average spend per customer, churn flags).</p></li><li><p><strong>Time-series analysis</strong>: lag, lead, cumulative sums (stock prices, IoT logs).</p></li><li><p><strong>ETL workflows</strong>: extract &#8594; transform &#8594; load &#8594; clean datasets for ML models.</p></li><li><p><strong>Data quality checks</strong>: find missing values, duplicates, anomalies.</p></li><li><p><strong>SQL + Python integration</strong>: pull SQL results directly into pandas for model training.</p></li><li><p><strong>Work with Data Warehouses</strong>: BigQuery, Snowflake, Redshift, Synapse &#8594; all use SQL.</p></li></ul><div><hr></div><h2>2. Examples (fully runnable SQL)</h2><div><hr></div><h3>Example 1 &#8212; Feature Engineering (customer spend metrics)</h3><pre><code><code>-- Example 1: Feature Engineering
DROP TABLE IF EXISTS transactions;
CREATE TABLE transactions (
  id INT AUTO_INCREMENT PRIMARY KEY,
  customer_id INT,
  amount DECIMAL(10,2),
  trans_date DATE
);

INSERT INTO transactions (customer_id, amount, trans_date) VALUES
(1, 200, &#8216;2024-09-01&#8217;),
(1, 150, &#8216;2024-09-10&#8217;),
(2, 300, &#8216;2024-09-02&#8217;),
(2, 100, &#8216;2024-09-15&#8217;),
(3, 50,  &#8216;2024-09-05&#8217;);

-- Feature 1: total spend per customer
SELECT customer_id, SUM(amount) AS total_spend
FROM transactions
GROUP BY customer_id;

-- Feature 2: average transaction value per customer
SELECT customer_id, AVG(amount) AS avg_spend
FROM transactions
GROUP BY customer_id;

-- Feature 3: transaction count (frequency)
SELECT customer_id, COUNT(*) AS txn_count
FROM transactions
GROUP BY customer_id;
</code></code></pre><p>&#128073; These features go directly into ML models (customer segmentation, churn prediction).</p><div><hr></div><h3>Example 2 &#8212; Time Series with Window Functions</h3><pre><code><code>-- Example 2: Time Series
-- Cumulative spend over time per customer
SELECT customer_id, trans_date, amount,
       SUM(amount) OVER (PARTITION BY customer_id ORDER BY trans_date) AS cumulative_spend,
       LAG(amount) OVER (PARTITION BY customer_id ORDER BY trans_date) AS prev_spend
FROM transactions;
</code></code></pre><p>&#128073; Useful for <strong>RFM (Recency, Frequency, Monetary)</strong> models.</p><div><hr></div><h3>Example 3 &#8212; ETL Workflow (staging &#8594; clean table)</h3><pre><code><code>-- Example 3: ETL-style insert into clean table
DROP TABLE IF EXISTS transactions_clean;
CREATE TABLE transactions_clean AS
SELECT customer_id,
       amount,
       trans_date,
       CASE WHEN amount &lt; 0 THEN 0 ELSE amount END AS cleaned_amount
FROM transactions;
</code></code></pre><p>&#128073; In practice, this step feeds <strong>feature store / ML pipeline</strong>.</p><div><hr></div><h3>Example 4 &#8212; Data Quality Checks</h3><pre><code><code>-- Example 4: Data quality checks
-- 1. Missing values
SELECT * FROM transactions WHERE amount IS NULL;

-- 2. Duplicates
SELECT customer_id, trans_date, COUNT(*) AS cnt
FROM transactions
GROUP BY customer_id, trans_date
HAVING cnt &gt; 1;

-- 3. Outliers (very large amounts)
SELECT * FROM transactions WHERE amount &gt; 1000;
</code></code></pre><p>&#128073; Common before feeding data into ML models.</p><div><hr></div><h3>Example 5 &#8212; SQL + Python (pandas integration)</h3><pre><code><code># Example 5: Python integration (pandas + MySQL)
import pandas as pd
import mysql.connector

# Connect
conn = mysql.connector.connect(
    host=&#8221;localhost&#8221;,
    user=&#8221;root&#8221;,
    password=&#8221;your_password&#8221;,
    database=&#8221;test_db&#8221;
)

# Load SQL query result into pandas
query = &#8220;&#8221;&#8220;
SELECT customer_id, SUM(amount) AS total_spend, COUNT(*) AS txn_count
FROM transactions
GROUP BY customer_id
&#8220;&#8221;&#8220;
df = pd.read_sql(query, conn)

print(df)
</code></code></pre><p>&#128073; Now <code>df</code> is a <strong>feature dataset</strong> ready for ML training in Python.</p><div><hr></div><h3>Example 6 &#8212; Data Warehouses (Cloud SQL flavor)</h3><pre><code><code>-- Example 6: Syntax similarities in cloud warehouses
-- In BigQuery / Snowflake / Redshift:
SELECT customer_id,
       SUM(amount) AS total_spend,
       COUNT(*) AS txn_count,
       AVG(amount) AS avg_spend
FROM transactions
GROUP BY customer_id;
</code></code></pre><p>&#128073; Good news: <strong>the SQL you&#8217;ve learned works across cloud data warehouses</strong> with tiny syntax tweaks.</p><div><hr></div><h2>3. Exercises (10 problems)</h2><ol><li><p>From <code>transactions</code>, calculate each customer&#8217;s <strong>maximum transaction amount</strong>.</p></li><li><p>Calculate <strong>average spend per month per customer</strong>.</p></li><li><p>For each transaction, show <strong>previous transaction amount</strong> (use <code>LAG</code>).</p></li><li><p>For each customer, calculate <strong>cumulative spend over time</strong>.</p></li><li><p>Build a &#8220;churn flag&#8221; &#8594; show customers who have <strong>no transactions in the last 30 days</strong>.</p></li><li><p>Write a query to detect <strong>duplicate transactions</strong> (same customer_id + date + amount).</p></li><li><p>Write a query to detect <strong>missing or NULL amounts</strong>.</p></li><li><p>Create a clean table where negative amounts are set to 0.</p></li><li><p>Use <code>JOIN</code> to combine <code>transactions</code> with a <code>customers</code> table (create one) and get features per customer.</p></li><li><p>Pull customer features (<code>total_spend</code>, <code>txn_count</code>) into Python (using <code>pandas.read_sql</code>).</p></li></ol><div><hr></div><h2>&#9989; Summary of the Whole Roadmap</h2><ul><li><p><strong>Chapter 1&#8211;2</strong>: Foundations + Aggregations &#8594; query basics.</p></li><li><p><strong>Chapter 3&#8211;4</strong>: Joins + Subqueries &#8594; combining datasets.</p></li><li><p><strong>Chapter 5</strong>: Window Functions &#8594; ranking, time-series, rolling features.</p></li><li><p><strong>Chapter 6&#8211;7</strong>: Data Manipulation + Set Ops &#8594; loading, updating, merging, comparing.</p></li><li><p><strong>Chapter 8</strong>: Cleaning + Transformation &#8594; preprocessing for ML.</p></li><li><p><strong>Chapter 9</strong>: Optimization &#8594; indexes, EXPLAIN, tuning big queries.</p></li><li><p><strong>Chapter 10</strong>: AI/ML Applications &#8594; feature engineering, ETL, quality checks, SQL+Python integration.</p></li></ul><p>&#128073; With this SQL skillset, you&#8217;re <strong>job-ready for AI/Data/ML roles</strong>. You&#8217;ll be able to:</p><ul><li><p>Query massive datasets.</p></li><li><p>Engineer ML features.</p></li><li><p>Clean &amp; validate data.</p></li><li><p>Integrate SQL directly into Python ML workflows.</p></li></ul><div><hr></div><p></p>]]></content:encoded></item><item><title><![CDATA[From Python Learner to AI Engineer: 8 Weeks, 50 Projects]]></title><description><![CDATA[From Zero to AI Hero: Python & Computer Vision Job-Ready Program]]></description><link>https://careerbytecode.substack.com/p/python-developer-to-ai-engineer-transformation-78assessments-50projects</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/python-developer-to-ai-engineer-transformation-78assessments-50projects</guid><dc:creator><![CDATA[Jenefer Rexee George]]></dc:creator><pubDate>Tue, 23 Sep 2025 10:18:53 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!p-tr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9686444-3815-491e-bbda-17e2dfc0386a_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!p-tr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9686444-3815-491e-bbda-17e2dfc0386a_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!p-tr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9686444-3815-491e-bbda-17e2dfc0386a_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!p-tr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9686444-3815-491e-bbda-17e2dfc0386a_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!p-tr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9686444-3815-491e-bbda-17e2dfc0386a_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!p-tr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9686444-3815-491e-bbda-17e2dfc0386a_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!p-tr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9686444-3815-491e-bbda-17e2dfc0386a_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c9686444-3815-491e-bbda-17e2dfc0386a_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1457492,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/169468274?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9686444-3815-491e-bbda-17e2dfc0386a_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!p-tr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9686444-3815-491e-bbda-17e2dfc0386a_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!p-tr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9686444-3815-491e-bbda-17e2dfc0386a_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!p-tr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9686444-3815-491e-bbda-17e2dfc0386a_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!p-tr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc9686444-3815-491e-bbda-17e2dfc0386a_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h1><strong>MODULE 1: INTRODUCTION TO COMPUTER VISION</strong></h1><p><strong>Week 1 | Goal: </strong>Understand the foundations and potential of Computer Vision</p><p><strong>Day 1 &#8211; What is Computer Vision?</strong></p><ul><li><p>History, inspiration from human vision</p></li><li><p>Where it's used: retail, healthcare, traffic, defense, etc.</p></li><li><p>How it connects with AI and ML</p></li></ul><p><strong>Day 2 &#8211; Tools and Libraries Setup</strong></p><ul><li><p>Installing OpenCV, NumPy, Matplotlib</p></li><li><p>Intro to IDE&#8230;</p></li></ul>
      <p>
          <a href="https://careerbytecode.substack.com/p/python-developer-to-ai-engineer-transformation-78assessments-50projects">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Mastering Data & SQL: Raw Data to Real-Time Dashboards in 50 Days]]></title><description><![CDATA[Python, SQL & Power BI: The Triple Skillset Recruiters Want]]></description><link>https://careerbytecode.substack.com/p/mastering-data-sql-raw-data-to-real-time-dashboards-in-50-days</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/mastering-data-sql-raw-data-to-real-time-dashboards-in-50-days</guid><dc:creator><![CDATA[KIRUTHIGA R]]></dc:creator><pubDate>Fri, 19 Sep 2025 17:10:59 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ICTi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5047a8-79f2-4725-bb44-d86d9eab20e9_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ICTi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5047a8-79f2-4725-bb44-d86d9eab20e9_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ICTi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5047a8-79f2-4725-bb44-d86d9eab20e9_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!ICTi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5047a8-79f2-4725-bb44-d86d9eab20e9_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!ICTi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5047a8-79f2-4725-bb44-d86d9eab20e9_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!ICTi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5047a8-79f2-4725-bb44-d86d9eab20e9_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ICTi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5047a8-79f2-4725-bb44-d86d9eab20e9_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2c5047a8-79f2-4725-bb44-d86d9eab20e9_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:809035,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/170757915?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5047a8-79f2-4725-bb44-d86d9eab20e9_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ICTi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5047a8-79f2-4725-bb44-d86d9eab20e9_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!ICTi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5047a8-79f2-4725-bb44-d86d9eab20e9_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!ICTi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5047a8-79f2-4725-bb44-d86d9eab20e9_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!ICTi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5047a8-79f2-4725-bb44-d86d9eab20e9_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h2><strong>&#128218; Course Structure</strong></h2><ul><li><p>&#128197; <strong>Duration:</strong> 50 Days (7 Weeks Approx.)</p></li><li><p>&#129504; Format: 5 sessions/week</p></li><li><p>&#128188; Tools: Python (for scraping), MySQL, Power BI</p></li></ul><h4><strong>&#129504; Skills You'll Learn</strong></h4><ul><li><p><strong>Data Fundamentals &amp; Collection<br></strong> Learn types of data, web scraping, API use, and cleaning techniques to prepare real-world datasets.</p></li><li><p><strong>DBMS &amp; RDBMS Concepts<br></strong> Understand ER models, keys, normalization, CAP the&#8230;</p></li></ul>
      <p>
          <a href="https://careerbytecode.substack.com/p/mastering-data-sql-raw-data-to-real-time-dashboards-in-50-days">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Python for Data Science & Analytics: A Complete 6-Week Job-Ready Program]]></title><description><![CDATA[End-to-End Data Science with Python: Job Preparation, Projects & Deployment in 6 Weeks]]></description><link>https://careerbytecode.substack.com/p/python-for-data-science-analytics-a-complete-6-week-job-ready-program</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/python-for-data-science-analytics-a-complete-6-week-job-ready-program</guid><dc:creator><![CDATA[Dharshini]]></dc:creator><pubDate>Thu, 18 Sep 2025 09:26:16 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qTiV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a6f892-68bf-4bbb-8279-15c64fb21b4f_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qTiV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a6f892-68bf-4bbb-8279-15c64fb21b4f_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qTiV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a6f892-68bf-4bbb-8279-15c64fb21b4f_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!qTiV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a6f892-68bf-4bbb-8279-15c64fb21b4f_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!qTiV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a6f892-68bf-4bbb-8279-15c64fb21b4f_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!qTiV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a6f892-68bf-4bbb-8279-15c64fb21b4f_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qTiV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a6f892-68bf-4bbb-8279-15c64fb21b4f_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b8a6f892-68bf-4bbb-8279-15c64fb21b4f_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:829079,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/169060307?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a6f892-68bf-4bbb-8279-15c64fb21b4f_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qTiV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a6f892-68bf-4bbb-8279-15c64fb21b4f_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!qTiV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a6f892-68bf-4bbb-8279-15c64fb21b4f_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!qTiV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a6f892-68bf-4bbb-8279-15c64fb21b4f_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!qTiV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb8a6f892-68bf-4bbb-8279-15c64fb21b4f_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p></p><p></p>
      <p>
          <a href="https://careerbytecode.substack.com/p/python-for-data-science-analytics-a-complete-6-week-job-ready-program">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[SQL Mastery for AI & Data: From Basics to Feature Engineering]]></title><description><![CDATA[The Complete SQL Roadmap for AI/ML Engineers]]></description><link>https://careerbytecode.substack.com/p/sql-mastery-for-ai-data-engineers-complete-realtime-handson-training</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/sql-mastery-for-ai-data-engineers-complete-realtime-handson-training</guid><dc:creator><![CDATA[CareerByteCode]]></dc:creator><pubDate>Tue, 16 Sep 2025 15:56:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!DInw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F451b1b16-39bd-4fdf-873a-ebd1f3ee5384_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DInw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F451b1b16-39bd-4fdf-873a-ebd1f3ee5384_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DInw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F451b1b16-39bd-4fdf-873a-ebd1f3ee5384_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!DInw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F451b1b16-39bd-4fdf-873a-ebd1f3ee5384_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!DInw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F451b1b16-39bd-4fdf-873a-ebd1f3ee5384_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!DInw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F451b1b16-39bd-4fdf-873a-ebd1f3ee5384_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DInw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F451b1b16-39bd-4fdf-873a-ebd1f3ee5384_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/451b1b16-39bd-4fdf-873a-ebd1f3ee5384_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:357877,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/173743869?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F451b1b16-39bd-4fdf-873a-ebd1f3ee5384_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DInw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F451b1b16-39bd-4fdf-873a-ebd1f3ee5384_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!DInw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F451b1b16-39bd-4fdf-873a-ebd1f3ee5384_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!DInw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F451b1b16-39bd-4fdf-873a-ebd1f3ee5384_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!DInw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F451b1b16-39bd-4fdf-873a-ebd1f3ee5384_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Python + AI is a strong combo, and <strong>SQL is a must-have</strong> because most AI/ML workflows need structured data from databases.<br>For AI/ML/data-related jobs, you don&#8217;t need to be a full-time DBA, but you <strong>must be comfortable with querying, cleaning, and transforming data</strong> efficiently.</p><p>Here&#8217;s a <strong>SQL roadmap for AI/Data/ML jobs</strong> &#128071;</p><div><hr></div><h2>&#128313; 1. SQL Basics (Foundations)</h2><ul><li><p>What is SQL? (DDL, DML, DQL, DCL, TCL)</p></li><li><p>Database concepts: tables, rows, columns, primary keys, foreign keys</p></li><li><p><code>SELECT</code>, <code>FROM</code>, <code>WHERE</code> basics</p></li><li><p>Filtering data with conditions (<code>=</code>, <code>&lt;</code>, <code>&gt;</code>, <code>&lt;&gt;</code>, <code>BETWEEN</code>, <code>IN</code>, <code>LIKE</code>)</p></li><li><p>Sorting results with <code>ORDER BY</code></p></li><li><p>Limiting results (<code>LIMIT</code> / <code>TOP</code>)</p></li><li><p>Aliases (<code>AS</code>)</p></li></ul><div><hr></div><h2>&#128313; 2. Aggregations &amp; Grouping</h2><ul><li><p><code>COUNT()</code>, <code>SUM()</code>, <code>AVG()</code>, <code>MIN()</code>, <code>MAX()</code></p></li><li><p><code>GROUP BY</code> (single and multiple columns)</p></li><li><p><code>HAVING</code> vs <code>WHERE</code></p></li><li><p>Distinct values (<code>DISTINCT</code>)</p></li></ul><div><hr></div><h2>&#128313; 3. Joins (Very Important for AI Jobs)</h2><ul><li><p>Inner Join</p></li><li><p>Left Join</p></li><li><p>Right Join</p></li><li><p>Full Outer Join</p></li><li><p>Self Join</p></li><li><p>Cross Join</p></li><li><p>Multi-table joins<br>&#128073; Most ML feature engineering needs joining multiple datasets.</p></li></ul><div><hr></div><h2>&#128313; 4. Subqueries &amp; Derived Tables</h2><ul><li><p>Simple subqueries (in <code>WHERE</code>, <code>SELECT</code>, <code>FROM</code>)</p></li><li><p>Correlated subqueries</p></li><li><p><code>EXISTS</code> vs <code>IN</code></p></li><li><p>Common Table Expressions (CTEs) with <code>WITH</code></p></li></ul><div><hr></div><h2>&#128313; 5. Advanced Filtering &amp; Window Functions</h2><ul><li><p><code>CASE WHEN</code> for conditional columns</p></li><li><p><code>COALESCE</code>, <code>NULLIF</code>, handling NULL values</p></li><li><p>Ranking functions (<code>ROW_NUMBER</code>, <code>RANK</code>, <code>DENSE_RANK</code>)</p></li><li><p>Aggregates with windowing (<code>SUM() OVER()</code>, <code>AVG() OVER()</code>)</p></li><li><p>Moving averages, cumulative sums<br>&#128073; Very useful for <strong>time series AI problems</strong> (stock, IoT, logs).</p></li></ul><div><hr></div><h2>&#128313; 6. Data Manipulation</h2><ul><li><p><code>INSERT</code>, <code>UPDATE</code>, <code>DELETE</code></p></li><li><p><code>MERGE</code> (UPSERT operations)</p></li><li><p>Bulk inserts</p></li></ul><div><hr></div><h2>&#128313; 7. Set Operations</h2><ul><li><p><code>UNION</code> vs <code>UNION ALL</code></p></li><li><p><code>INTERSECT</code></p></li><li><p><code>EXCEPT</code> / <code>MINUS</code></p></li></ul><div><hr></div><h2>&#128313; 8. Data Cleaning &amp; Transformation (Critical for AI/ML)</h2><ul><li><p>String functions (<code>TRIM</code>, <code>SUBSTRING</code>, <code>CONCAT</code>, <code>UPPER/LOWER</code>)</p></li><li><p>Date &amp; time functions (<code>DATEADD</code>, <code>DATEDIFF</code>, <code>EXTRACT</code>)</p></li><li><p>Converting data types (<code>CAST</code>, <code>CONVERT</code>)</p></li><li><p>Pivoting &amp; unpivoting data (<code>PIVOT</code>, <code>UNPIVOT</code>)</p></li></ul><div><hr></div><h2>&#128313; 9. Performance &amp; Optimization (Intermediate Level)</h2><ul><li><p>Indexes basics (clustered, non-clustered)</p></li><li><p>Query execution plan (basic understanding)</p></li><li><p><code>EXPLAIN</code> keyword to analyze queries</p></li><li><p>Using appropriate joins vs subqueries for performance</p></li></ul><div><hr></div><h2>&#128313; 10. AI/Data-Job Specific SQL Topics</h2><ul><li><p>Writing queries for <strong>feature engineering</strong></p></li><li><p>SQL for <strong>time series</strong> (lag, lead, window)</p></li><li><p>SQL for <strong>ETL workflows</strong></p></li><li><p>SQL for <strong>data quality checks</strong> (missing, duplicates, anomalies)</p></li><li><p>SQL integration with <strong>Python (pandas + SQLAlchemy)</strong></p></li><li><p>Using SQL in <strong>data warehouses</strong> (BigQuery, Snowflake, Redshift, Synapse)</p></li></ul><div><hr></div><p>&#9989; <strong>Summary:</strong><br>For AI/data jobs, you need to be <strong>very strong in SELECT queries, joins, aggregations, subqueries, and window functions</strong>.<br>DBA-level topics (backups, replication, clustering) are <strong>not required</strong> unless you aim for data engineering.</p><p></p><blockquote><p>&#9989; <strong>Run environment</strong>: examples below are written for <strong>SQLite</strong> (<code>sqlite3</code>). SQLite is zero-config and runs on Windows/Mac/Linux. If you use MySQL/Postgres, the logic is the same but a few tiny syntax differences apply</p></blockquote><div><hr></div><h1>Chapter 1 &#8212; SQL Basics (Foundations)</h1><h2>What this chapter covers (plain language)</h2><p>SQL is the language used to talk to relational databases. Think of a database as a set of spreadsheets (tables). SQL lets you:</p><ul><li><p>Create and change tables (like creating a new sheet).</p></li><li><p>Put rows into tables (like typing rows into spreadsheets).</p></li><li><p>Ask questions (queries) &#8212; that&#8217;s the most common: &#8220;Give me all customers who bought X&#8221;.</p></li><li><p>Make simple filters, sort the results, and rename columns in the results.</p></li></ul><p>You don&#8217;t need to be a database admin to be useful for AI/data work &#8212; you just need to be comfortable with asking the right questions and extracting the right data.</p><div><hr></div><h2>Very short vocabulary (layman)</h2><ul><li><p><strong>Table</strong>: like a spreadsheet page (e.g., <code>employees</code>).</p></li><li><p><strong>Row</strong>: one record (one person, one order).</p></li><li><p><strong>Column</strong>: property of the row (name, price).</p></li><li><p><strong>Primary Key (PK)</strong>: unique id for each row (like a student ID).</p></li><li><p><strong>Foreign Key (FK)</strong>: a link from one table to a row in another table (like employee&#8217;s department id).</p></li><li><p><strong>Query</strong>: a question you ask the database (<code>SELECT ...</code>).</p></li><li><p><strong>DDL</strong>: commands that define structure (CREATE, DROP).</p></li><li><p><strong>DML</strong>: commands that change data (INSERT, UPDATE, DELETE).</p></li><li><p><strong>DQL</strong>: query language &#8212; <code>SELECT</code> statements (data retrieval).</p></li></ul><div><hr></div><h2>How I&#8217;ll show examples</h2><p>Each example block is self-contained: it drops the table if it exists, creates the table, inserts rows, and runs the SELECT you need to see the result. Copy the whole block and paste into <code>sqlite3</code> and it will run.</p><div><hr></div><h2>Example 1 &#8212; Very first query: <code>SELECT</code> and <code>SELECT *</code></h2><p><strong>What we want</strong>: get all rows and columns from a table.</p><pre><code><code>-- Example 1: list all employees
DROP TABLE IF EXISTS employees;

CREATE TABLE employees (
  id INTEGER PRIMARY KEY,
  first_name TEXT,
  last_name TEXT,
  role TEXT,
  salary INTEGER
);

INSERT INTO employees (id, first_name, last_name, role, salary) VALUES
(1, 'Asha', 'Kumar', 'Data Analyst', 50000),
(2, 'John', 'Doe', 'ML Engineer', 90000),
(3, 'Maya', 'Singh', 'Data Scientist', 85000),
(4, 'Liam', 'Ng', 'DevOps', 75000),
(5, 'Sara', 'Khan', 'Intern', 20000);

-- The simplest question: give me everything
SELECT * FROM employees;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>DROP TABLE IF EXISTS</code> &#8212; remove old table so the code can be run many times without error.</p></li><li><p><code>CREATE TABLE</code> &#8212; defines columns.</p></li><li><p><code>INSERT INTO</code> &#8212; adds rows (we manually provide IDs so this works everywhere).</p></li><li><p><code>SELECT * FROM employees;</code> &#8212; &#8220;give me every column of every row&#8221; (like opening the whole spreadsheet).</p></li></ul><div><hr></div><h2>Example 2 &#8212; Select specific columns and <code>WHERE</code> filter</h2><p><strong>What we want</strong>: pick certain columns and filter rows.</p><pre><code><code>-- Example 2: basic column selection and filtering
DROP TABLE IF EXISTS products;

CREATE TABLE products (
  product_id INTEGER PRIMARY KEY,
  name TEXT,
  category TEXT,
  price INTEGER,
  stock INTEGER
);

INSERT INTO products (product_id, name, category, price, stock) VALUES
(101, 'Latte', 'Beverage', 4, 100),
(102, 'Espresso', 'Beverage', 3, 50),
(103, 'Muffin', 'Food', 2, 0),
(104, 'Bagel', 'Food', 2, 30),
(105, 'GreenTea', 'Beverage', 3, 20);

-- Show only name and price for products that cost 3 or more
SELECT name, price
FROM products
WHERE price &gt;= 3;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>SELECT name, price</code> &#8212; only fetch these columns (faster and cleaner).</p></li><li><p><code>WHERE price &gt;= 3</code> &#8212; only rows where the price is at least 3. <code>WHERE</code> is used to filter like Excel filters.</p></li></ul><p><strong>More filters (run separately):</strong></p><pre><code><code>-- Products out of stock
SELECT * FROM products WHERE stock = 0;

-- Products that are either category 'Food' or price &gt; 3
SELECT * FROM products WHERE category = 'Food' OR price &gt; 3;

-- Products with names containing 'e' (simple text match)
SELECT * FROM products WHERE name LIKE '%e%';

-- Products with IDs in this small set
SELECT * FROM products WHERE product_id IN (101, 104);
</code></code></pre><div><hr></div><h2>Example 3 &#8212; <code>ORDER BY</code> and <code>LIMIT</code> (sorting and top-n)</h2><p><strong>What we want</strong>: sort results and take only top rows (e.g., top 3 salaries).</p><pre><code><code>-- Example 3: orders and top-n
DROP TABLE IF EXISTS orders;

CREATE TABLE orders (
  order_id INTEGER PRIMARY KEY,
  customer TEXT,
  amount INTEGER,
  order_date TEXT  -- We'll store date as text for this beginner example
);

INSERT INTO orders (order_id, customer, amount, order_date) VALUES
(1, 'Asha', 120, '2025-09-01'),
(2, 'John', 500, '2025-09-02'),
(3, 'Maya', 300, '2025-09-03'),
(4, 'Liam', 50, '2025-08-28'),
(5, 'Sara', 700, '2025-09-05');

-- Show orders sorted by amount, highest first
SELECT * FROM orders ORDER BY amount DESC;

-- Show only the top 3 biggest orders
SELECT * FROM orders ORDER BY amount DESC LIMIT 3;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>ORDER BY amount DESC</code> &#8212; sorts rows by <code>amount</code> from big &#8594; small. <code>ASC</code> would be small &#8594; big.</p></li><li><p><code>LIMIT 3</code> &#8212; return only the first 3 rows of that sorted list (useful for top-k queries).</p></li></ul><div><hr></div><h2>Example 4 &#8212; Column aliases &amp; simple expressions</h2><p><strong>What we want</strong>: rename output columns and compute new columns.</p><pre><code><code>-- Example 4: aliases and computed columns
DROP TABLE IF EXISTS customers;

CREATE TABLE customers (
  cid INTEGER PRIMARY KEY,
  first TEXT,
  last TEXT,
  country TEXT,
  purchases INTEGER
);

INSERT INTO customers (cid, first, last, country, purchases) VALUES
(1, 'Ravi', 'Patel', 'India', 5),
(2, 'Emma', 'Brown', 'UK', 2),
(3, 'Chen', 'Lee', 'China', 8),
(4, 'Olivia', 'Garcia', 'Spain', 1);

-- Make a full_name column (concatenate) and show an adjusted metric
SELECT
  cid,
  first || ' ' || last AS full_name,  -- in SQLite use || to join strings
  purchases,
  purchases * 10 AS purchase_score     -- a computed column
FROM customers;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>AS full_name</code> gives a friendlier name to the calculated column.</p></li><li><p><code>first || ' ' || last</code> combines first and last name (SQLite style).</p></li><li><p><code>purchases * 10 AS purchase_score</code> shows how we can compute values on the fly &#8212; great for feature engineering later.</p></li></ul><blockquote><p>Note: In MySQL/Postgres you might use <code>CONCAT(first, ' ', last)</code> instead of <code>||</code> &#8212; but the above is SQLite-safe.</p></blockquote><div><hr></div><h2>Example 5 &#8212; <code>NULL</code>, <code>IS NULL</code>, and <code>COALESCE</code></h2><p><strong>What we want</strong>: learn how missing values behave and how to replace them.</p><pre><code><code>-- Example 5: handling NULLs
DROP TABLE IF EXISTS inventory;

CREATE TABLE inventory (
  item_id INTEGER PRIMARY KEY,
  name TEXT,
  location TEXT,
  quantity INTEGER
);

INSERT INTO inventory (item_id, name, location, quantity) VALUES
(1, 'Widget A', 'Aisle 1', 10),
(2, 'Widget B', NULL, 5),
(3, 'Widget C', 'Aisle 3', NULL),
(4, 'Widget D', NULL, NULL);

-- Find rows where location is unknown
SELECT * FROM inventory WHERE location IS NULL;

-- Find rows where quantity is missing
SELECT * FROM inventory WHERE quantity IS NULL;

-- Use COALESCE to replace NULL with a default for display
SELECT item_id, name,
       COALESCE(location, 'UNKNOWN') AS location_text,
       COALESCE(quantity, 0) AS qty
FROM inventory;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>NULL</code> means &#8220;unknown&#8221; or &#8220;no value&#8221;.</p></li><li><p><code>IS NULL</code> is how you check for unknowns. <code>= NULL</code> will not work.</p></li><li><p><code>COALESCE</code> picks the first non-null value &#8212; handy to show readable defaults.</p></li></ul><div><hr></div><h2>Example 6 &#8212; Primary key, foreign key, and a simple relationship</h2><p><strong>What we want</strong>: show how two tables relate (department &#8594; employees).</p><pre><code><code>-- Example 6: departments and employees (basic FK)
PRAGMA foreign_keys = ON;  -- make SQLite enforce foreign keys in this session

DROP TABLE IF EXISTS employees_dept;
DROP TABLE IF EXISTS departments;

CREATE TABLE departments (
  id INTEGER PRIMARY KEY,
  dept_name TEXT
);

CREATE TABLE employees_dept (
  emp_id INTEGER PRIMARY KEY,
  name TEXT,
  dept_id INTEGER,
  salary INTEGER,
  FOREIGN KEY (dept_id) REFERENCES departments(id)
);

INSERT INTO departments (id, dept_name) VALUES
(10, 'Engineering'),
(20, 'Data'),
(30, 'HR');

INSERT INTO employees_dept (emp_id, name, dept_id, salary) VALUES
(100, 'Asha', 20, 60000),
(101, 'John', 10, 90000),
(102, 'Maya', 20, 85000),
(103, 'Liam', 10, 70000),
(104, 'Sara', 30, 40000);

-- Show employees and their dept_id (raw)
SELECT * FROM employees_dept;

-- Very simple join to show department name (we'll cover joins deeply later)
SELECT e.emp_id, e.name, e.salary, d.dept_name
FROM employees_dept e
JOIN departments d ON e.dept_id = d.id;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>departments</code> has a unique <code>id</code> per row &#8212; that&#8217;s the primary key.</p></li><li><p><code>employees_dept.dept_id</code> stores the department id &#8212; a foreign key linking to <code>departments</code>.</p></li><li><p>The <code>JOIN</code> pulls department names into the employee view. This is how you stitch related tables together.</p></li></ul><div><hr></div><h2>Quick checklist: the key basic commands you just learned</h2><ul><li><p><code>CREATE TABLE</code> &#8212; make a new table.</p></li><li><p><code>DROP TABLE IF EXISTS</code> &#8212; remove an old table.</p></li><li><p><code>INSERT INTO ... VALUES (...)</code> &#8212; add rows.</p></li><li><p><code>SELECT column1, column2 FROM table</code> &#8212; pick columns you want.</p></li><li><p><code>WHERE</code> &#8212; filter rows by conditions.</p></li><li><p><code>ORDER BY ... ASC|DESC</code> &#8212; sort results.</p></li><li><p><code>LIMIT n</code> &#8212; take only the first n rows.</p></li><li><p><code>AS</code> &#8212; rename a column in the results.</p></li><li><p><code>IS NULL</code> / <code>COALESCE</code> &#8212; handle missing values.</p></li><li><p>Primary Key (unique id) and Foreign Key (link between tables).</p></li></ul><div><hr></div><h2>10 Exercises (Chapter 1) &#8212; practice (use the tables from the examples)</h2><p>Do these on your own. Each exercise assumes you already ran the example blocks above (so the tables exist). If they don&#8217;t, re-run the relevant example block before starting.</p><ol><li><p><strong>List names and roles</strong>: From <code>employees</code>, show <code>first_name</code>, <code>last_name</code>, and <code>role</code> only.</p></li><li><p><strong>High earners</strong>: From <code>employees</code>, list rows where <code>salary</code> is greater than 70,000. Sort them by salary descending.</p></li><li><p><strong>Products with vowel</strong>: From <code>products</code>, show items whose name contains the letter <code>a</code> (case sensitive is fine).</p></li><li><p><strong>Out of stock</strong>: From <code>products</code>, return product <code>name</code> and <code>category</code> for all items with <code>stock = 0</code>.</p></li><li><p><strong>Top customers</strong>: From <code>orders</code>, list the top 2 customers by <code>amount</code>.</p></li><li><p><strong>Create a view (or simulated)</strong>: Write a query that shows each <code>customer</code> and their <code>amount</code> as <code>order_amount</code> (use <code>AS</code> to rename the column).</p></li><li><p><strong>Replace NULLs</strong>: From <code>inventory</code>, produce a list where <code>location</code> is replaced with <code>'UNKNOWN'</code> and <code>quantity</code> replaced with <code>0</code>. (Use <code>COALESCE</code>.)</p></li><li><p><strong>Department lookup</strong>: Using <code>employees_dept</code> and <code>departments</code>, show <code>name</code> and <code>dept_name</code> for employees in the <code>Data</code> department only.</p></li><li><p><strong>Add a new product</strong>: Insert a new product into <code>products</code> with <code>product_id 106</code> and then query to show it exists.</p></li><li><p><strong>Count rows</strong>: Use a <code>SELECT</code> to count how many rows are in <code>employees</code> (use <code>COUNT(*)</code>). This introduces a tiny aggregation &#8212; we&#8217;ll do full aggregations next chapter.</p></li></ol><div><hr></div><h2>Short tips &amp; pitfalls (layman)</h2><ul><li><p>Always <code>DROP TABLE IF EXISTS</code> at the top of example scripts when learning &#8212; avoids "table already exists" errors.</p></li><li><p><code>NULL</code> is not the same as an empty string <code>''</code>. Use <code>IS NULL</code> to check nulls.</p></li><li><p><code>WHERE</code> filters rows; <code>HAVING</code> (we&#8217;ll meet later) filters groups.</p></li><li><p>Practice by copying the code into <code>sqlite3</code> and step through line by line. Change values, re-run, see what changes.</p></li></ul><div><hr></div><p></p><div><hr></div><h1>Chapter 2 &#8212; Aggregations &amp; Grouping</h1><h2>What this chapter covers (plain language)</h2><p>When you have <strong>lots of rows</strong>, you usually don&#8217;t want to see each row &#8212; you want <strong>summary numbers</strong>:</p><ul><li><p>How many customers bought something?</p></li><li><p>What&#8217;s the average salary?</p></li><li><p>What&#8217;s the total revenue last week?</p></li></ul><p>That&#8217;s what <strong>aggregate functions</strong> do. Then, with <strong>GROUP BY</strong>, you can split data into categories (e.g., sales per country).</p><div><hr></div><h2>The 5 most common aggregate functions</h2><ul><li><p><code>COUNT()</code> &#8594; how many rows (or values).</p></li><li><p><code>SUM()</code> &#8594; total of numbers.</p></li><li><p><code>AVG()</code> &#8594; average of numbers.</p></li><li><p><code>MIN()</code> &#8594; smallest value.</p></li><li><p><code>MAX()</code> &#8594; biggest value.</p></li></ul><div><hr></div><h2>Example 1 &#8212; Counting rows</h2><pre><code><code>-- Example 1: counting rows
DROP TABLE IF EXISTS sales;

CREATE TABLE sales (
  sale_id INTEGER PRIMARY KEY,
  product TEXT,
  quantity INTEGER,
  price INTEGER
);

INSERT INTO sales (sale_id, product, quantity, price) VALUES
(1, 'Latte', 2, 4),
(2, 'Latte', 1, 4),
(3, 'Espresso', 3, 3),
(4, 'Muffin', 5, 2),
(5, 'Espresso', 2, 3),
(6, 'Latte', 4, 4);

-- Count all rows
SELECT COUNT(*) AS total_sales FROM sales;

-- Count only rows where product = 'Latte'
SELECT COUNT(*) AS latte_sales FROM sales WHERE product = 'Latte';
</code></code></pre><p><strong>Explanation</strong>:</p><ul><li><p><code>COUNT(*)</code> = number of rows in the table.</p></li><li><p>You can add <code>WHERE</code> to count only a subset.</p></li></ul><div><hr></div><h2>Example 2 &#8212; SUM and AVG</h2><pre><code><code>-- Example 2: SUM and AVG
-- Total quantity sold
SELECT SUM(quantity) AS total_quantity FROM sales;

-- Average price of items
SELECT AVG(price) AS avg_price FROM sales;

-- Total revenue = quantity * price for all rows
SELECT SUM(quantity * price) AS total_revenue FROM sales;
</code></code></pre><p><strong>Explanation</strong>:</p><ul><li><p><code>SUM(quantity)</code> adds up all quantities.</p></li><li><p><code>AVG(price)</code> gives the mean of all prices.</p></li><li><p>You can calculate expressions inside aggregate functions (here: <code>quantity * price</code>).</p></li></ul><div><hr></div><h2>Example 3 &#8212; MIN and MAX</h2><pre><code><code>-- Example 3: MIN and MAX
-- Cheapest item price
SELECT MIN(price) AS min_price FROM sales;

-- Most expensive item price
SELECT MAX(price) AS max_price FROM sales;

-- Largest quantity in a single sale
SELECT MAX(quantity) AS largest_order FROM sales;
</code></code></pre><p><strong>Explanation</strong>:</p><ul><li><p><code>MIN()</code> finds the smallest number.</p></li><li><p><code>MAX()</code> finds the largest number.</p></li></ul><div><hr></div><h2>Example 4 &#8212; GROUP BY (splitting into categories)</h2><pre><code><code>-- Example 4: GROUP BY
-- Total quantity sold per product
SELECT product, SUM(quantity) AS total_qty
FROM sales
GROUP BY product;

-- Average price per product
SELECT product, AVG(price) AS avg_price
FROM sales
GROUP BY product;

-- Count how many times each product was sold
SELECT product, COUNT(*) AS order_count
FROM sales
GROUP BY product;
</code></code></pre><p><strong>Explanation</strong>:</p><ul><li><p><code>GROUP BY product</code> means: split the table by product, then run the aggregate separately for each group.</p></li><li><p>Without <code>GROUP BY</code>, aggregates give one row. With <code>GROUP BY</code>, you get one row per group.</p></li></ul><div><hr></div><h2>Example 5 &#8212; GROUP BY with multiple columns</h2><pre><code><code>-- Example 5: grouping by multiple columns
DROP TABLE IF EXISTS employee_salaries;

CREATE TABLE employee_salaries (
  emp_id INTEGER PRIMARY KEY,
  department TEXT,
  role TEXT,
  salary INTEGER
);

INSERT INTO employee_salaries (emp_id, department, role, salary) VALUES
(1, 'Data', 'Analyst', 50000),
(2, 'Data', 'Scientist', 85000),
(3, 'Engineering', 'DevOps', 75000),
(4, 'Engineering', 'Developer', 70000),
(5, 'Engineering', 'Developer', 72000),
(6, 'HR', 'Recruiter', 40000);

-- Average salary per department
SELECT department, AVG(salary) AS avg_salary
FROM employee_salaries
GROUP BY department;

-- Average salary per department + role
SELECT department, role, AVG(salary) AS avg_salary
FROM employee_salaries
GROUP BY department, role;
</code></code></pre><p><strong>Explanation</strong>:</p><ul><li><p>You can group by more than one column.</p></li><li><p>First query groups by department.</p></li><li><p>Second query groups by both department <strong>and</strong> role.</p></li></ul><div><hr></div><h2>Example 6 &#8212; HAVING (filter groups)</h2><pre><code><code>-- Example 6: HAVING
-- Only show departments where average salary &gt; 60000
SELECT department, AVG(salary) AS avg_salary
FROM employee_salaries
GROUP BY department
HAVING AVG(salary) &gt; 60000;

-- Only show products sold more than 2 times
SELECT product, COUNT(*) AS order_count
FROM sales
GROUP BY product
HAVING COUNT(*) &gt; 2;
</code></code></pre><p><strong>Explanation</strong>:</p><ul><li><p><code>WHERE</code> filters rows <strong>before grouping</strong>.</p></li><li><p><code>HAVING</code> filters <strong>after grouping</strong>.</p></li><li><p>Rule of thumb: <code>WHERE</code> is for rows, <code>HAVING</code> is for groups.</p></li></ul><div><hr></div><h2>Example 7 &#8212; DISTINCT vs GROUP BY</h2><pre><code><code>-- Example 7: DISTINCT vs GROUP BY
DROP TABLE IF EXISTS students;

CREATE TABLE students (
  id INTEGER PRIMARY KEY,
  name TEXT,
  class TEXT
);

INSERT INTO students (id, name, class) VALUES
(1, 'Asha', 'Math'),
(2, 'John', 'Science'),
(3, 'Maya', 'Math'),
(4, 'Liam', 'English'),
(5, 'Sara', 'Science');

-- Unique classes with DISTINCT
SELECT DISTINCT class FROM students;

-- Same result using GROUP BY
SELECT class FROM students GROUP BY class;
</code></code></pre><p><strong>Explanation</strong>:</p><ul><li><p><code>DISTINCT</code> removes duplicates.</p></li><li><p><code>GROUP BY</code> can also achieve that &#8212; but it&#8217;s more powerful because you can add aggregates.</p></li></ul><div><hr></div><h2>10 Exercises (Chapter 2) &#8212; practice</h2><p>Use the <code>sales</code>, <code>employee_salaries</code>, and <code>students</code> tables created above.</p><ol><li><p>Find the <strong>total revenue per product</strong> from the <code>sales</code> table.</p></li><li><p>Find the <strong>average quantity per product</strong>.</p></li><li><p>Show the <strong>product with the maximum average price</strong>.</p></li><li><p>Find the <strong>total number of distinct products</strong> in the <code>sales</code> table (use <code>COUNT(DISTINCT ...)</code>).</p></li><li><p>From <code>employee_salaries</code>, show the <strong>highest salary in each department</strong>.</p></li><li><p>From <code>employee_salaries</code>, show <strong>department and role combinations where average salary is below 60,000</strong>.</p></li><li><p>From <code>sales</code>, show only products where the <strong>total quantity sold is more than 5</strong>.</p></li><li><p>From <code>students</code>, count how many students are in each class.</p></li><li><p>From <code>sales</code>, calculate the <strong>average revenue (quantity * price)</strong> per product.</p></li><li><p>From <code>employee_salaries</code>, calculate the <strong>total salary cost per department</strong> and sort results from highest to lowest.</p></li></ol><div><hr></div><p>&#9989; <strong>Summary of this chapter</strong></p><ul><li><p><code>COUNT</code>, <code>SUM</code>, <code>AVG</code>, <code>MIN</code>, <code>MAX</code> summarize data.</p></li><li><p><code>GROUP BY</code> splits data into categories.</p></li><li><p><code>HAVING</code> filters groups.</p></li><li><p><code>DISTINCT</code> removes duplicates (like Excel&#8217;s "Remove Duplicates").</p></li></ul><div><hr></div><p></p><h1>Chapter 3 &#8212; Joins (Combining Tables)</h1><p>Now let&#8217;s move to the most <strong>critical SQL concept for AI/Data jobs</strong> &#8212; <strong>Joins</strong>.<br>Without joins, you&#8217;ll only query one table at a time. But in the real world, data is spread across <strong>many tables</strong> &#8212; customer info, orders, payments, products. Joins let you <strong>connect</strong> them.</p><h2>What this chapter covers (plain language)</h2><p>Think of each table like a sheet in Excel. A <strong>join</strong> is like using <strong>VLOOKUP</strong> to bring data from one sheet into another &#8212; but more powerful.</p><p>We&#8217;ll cover:</p><ul><li><p>Inner Join</p></li><li><p>Left Join</p></li><li><p>Right Join (not in SQLite, but I&#8217;ll show the workaround)</p></li><li><p>Full Outer Join (also workaround in SQLite)</p></li><li><p>Cross Join</p></li><li><p>Self Join</p></li></ul><div><hr></div><h2>Example setup (for all join examples)</h2><p>We&#8217;ll create two related tables: <code>customers</code> and <code>orders</code>.</p><pre><code><code>DROP TABLE IF EXISTS customers;
DROP TABLE IF EXISTS orders;

CREATE TABLE customers (
  customer_id INTEGER PRIMARY KEY,
  name TEXT,
  country TEXT
);

CREATE TABLE orders (
  order_id INTEGER PRIMARY KEY,
  customer_id INTEGER,
  product TEXT,
  amount INTEGER
);

INSERT INTO customers (customer_id, name, country) VALUES
(1, 'Asha', 'India'),
(2, 'John', 'USA'),
(3, 'Maya', 'UK'),
(4, 'Liam', 'Canada');

INSERT INTO orders (order_id, customer_id, product, amount) VALUES
(101, 1, 'Laptop', 1000),
(102, 1, 'Mouse', 20),
(103, 2, 'Keyboard', 50),
(104, 2, 'Monitor', 200),
(105, 3, 'Tablet', 300);
</code></code></pre><div><hr></div><h2>Example 1 &#8212; INNER JOIN</h2><pre><code><code>-- Inner join: only customers who have placed orders
SELECT c.customer_id, c.name, o.product, o.amount
FROM customers c
INNER JOIN orders o
  ON c.customer_id = o.customer_id;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>INNER JOIN = "Only keep rows where both tables have a match."</p></li><li><p>Here: only customers who placed at least one order appear.</p></li><li><p><code>Liam</code> (customer 4) does not appear because he has no orders.</p></li></ul><div><hr></div><h2>Example 2 &#8212; LEFT JOIN</h2><pre><code><code>-- Left join: all customers, even if they have no orders
SELECT c.customer_id, c.name, o.product, o.amount
FROM customers c
LEFT JOIN orders o
  ON c.customer_id = o.customer_id;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>LEFT JOIN = &#8220;Take all rows from the <strong>left table</strong> (customers), and bring data from the right (orders) if it exists.&#8221;</p></li><li><p>If no match, the columns from the right table are <code>NULL</code>.</p></li><li><p>Liam now appears, but with <code>NULL</code> for product and amount.</p></li></ul><div><hr></div><h2>Example 3 &#8212; RIGHT JOIN (simulated in SQLite)</h2><p>SQLite doesn&#8217;t have <code>RIGHT JOIN</code>, but we can flip the tables and use LEFT JOIN.</p><pre><code><code>-- Right join equivalent: all orders, even if no matching customer
SELECT o.order_id, o.product, o.amount, c.name, c.country
FROM orders o
LEFT JOIN customers c
  ON o.customer_id = c.customer_id;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>This is a "right join" in disguise: take all orders, bring in customer info if available.</p></li><li><p>If there&#8217;s an order with a customer_id not in customers, it will show <code>NULL</code> for name/country.</p></li></ul><div><hr></div><h2>Example 4 &#8212; FULL OUTER JOIN (simulated in SQLite)</h2><p>SQLite also doesn&#8217;t support <code>FULL JOIN</code> directly. But we can simulate with <code>UNION</code>.</p><pre><code><code>-- Full outer join = all customers + all orders
SELECT c.customer_id, c.name, o.product, o.amount
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id

UNION

SELECT c.customer_id, c.name, o.product, o.amount
FROM customers c
RIGHT JOIN orders o ON c.customer_id = o.customer_id; -- in SQLite, use the LEFT JOIN flip trick
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>FULL OUTER JOIN = &#8220;Give me everything, whether or not there&#8217;s a match.&#8221;</p></li><li><p>You&#8217;ll see customers without orders and orders without customers.</p></li></ul><div><hr></div><h2>Example 5 &#8212; CROSS JOIN</h2><pre><code><code>-- Cross join: every customer paired with every product
DROP TABLE IF EXISTS products;
CREATE TABLE products (
  pid INTEGER PRIMARY KEY,
  pname TEXT
);

INSERT INTO products (pid, pname) VALUES
(1, 'Phone'),
(2, 'Laptop'),
(3, 'Headphones');

-- Cartesian product
SELECT c.name, p.pname
FROM customers c
CROSS JOIN products p;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>CROSS JOIN = every row of one table combined with every row of another.</p></li><li><p>If there are 4 customers &#215; 3 products = 12 rows.</p></li><li><p>Usually used for generating combinations, not for normal reporting.</p></li></ul><div><hr></div><h2>Example 6 &#8212; SELF JOIN</h2><pre><code><code>-- Self join: employees referencing managers
DROP TABLE IF EXISTS employees;
CREATE TABLE employees (
  emp_id INTEGER PRIMARY KEY,
  name TEXT,
  manager_id INTEGER
);

INSERT INTO employees (emp_id, name, manager_id) VALUES
(1, 'Alice', NULL),   -- CEO
(2, 'Bob', 1),        -- Alice manages Bob
(3, 'Charlie', 1),    -- Alice manages Charlie
(4, 'David', 2);      -- Bob manages David

-- Self join: find employee and their manager name
SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m
  ON e.manager_id = m.emp_id;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>A self join joins a table to itself.</p></li><li><p>Here, employees reference their manager via <code>manager_id</code>.</p></li><li><p>David &#8594; Bob, Bob &#8594; Alice, Alice has no manager.</p></li></ul><div><hr></div><h2>Quick checklist: Joins</h2><ul><li><p>INNER JOIN = only matching rows.</p></li><li><p>LEFT JOIN = all from left + matches from right.</p></li><li><p>RIGHT JOIN = all from right + matches from left (simulate in SQLite).</p></li><li><p>FULL OUTER JOIN = all rows from both (simulate with <code>UNION</code>).</p></li><li><p>CROSS JOIN = every combination.</p></li><li><p>SELF JOIN = table joined with itself.</p></li></ul><div><hr></div><h2>10 Exercises (Chapter 3)</h2><ol><li><p>Show all customers and their orders (use INNER JOIN).</p></li><li><p>Show all customers, even those without orders (use LEFT JOIN).</p></li><li><p>Show all orders, even if no customer exists for them (use RIGHT JOIN simulation).</p></li><li><p>Create a query to show <strong>customer name + country + total order amount</strong> (hint: join + SUM + GROUP BY).</p></li><li><p>Find customers who <strong>have no orders</strong> (LEFT JOIN + <code>WHERE order_id IS NULL</code>).</p></li><li><p>Find products that have <strong>never been ordered</strong> (use <code>products</code> + <code>orders</code>).</p></li><li><p>Using <code>employees</code>, list all employees with their manager name.</p></li><li><p>Using <code>employees</code>, find employees who are <strong>managers</strong> (appear in <code>manager_id</code>).</p></li><li><p>Generate all combinations of customer names and products (use CROSS JOIN).</p></li><li><p>Create a query that shows all customers with number of orders, including those with 0 orders.</p></li></ol><div><hr></div><p>&#9989; <strong>Summary of this chapter</strong></p><ul><li><p>Joins let you combine related tables.</p></li><li><p>They are the <strong>heart of SQL for AI/data jobs</strong> (most feature engineering is multi-table joins).</p></li><li><p>Must master LEFT JOIN + GROUP BY for real projects.</p></li></ul><div><hr></div><p></p><h1>Chapter 4 &#8212; Subqueries &amp; CTEs</h1><p>Now we go to <strong>Chapter 4 &#8212; Subqueries &amp; CTEs (Common Table Expressions)</strong>.<br>This is where SQL gets really powerful: you can write <strong>queries inside queries</strong> to handle complex data questions.</p><h2>What this chapter covers (plain language)</h2><ul><li><p><strong>Subquery</strong> = a query inside another query.</p></li><li><p>You can put a subquery in:</p><ul><li><p><code>WHERE</code> &#8594; filter rows based on another query.</p></li><li><p><code>SELECT</code> &#8594; create new calculated columns.</p></li><li><p><code>FROM</code> &#8594; use subquery results as a temporary table.</p></li></ul></li><li><p><strong>Correlated Subquery</strong> = subquery that depends on the outer query.</p></li><li><p><strong>CTE (Common Table Expression)</strong> = a readable way to build temporary tables with <code>WITH</code>.</p></li></ul><div><hr></div><h2>Example setup</h2><p>We&#8217;ll reuse <code>customers</code> and <code>orders</code>, and add <code>payments</code>.</p><pre><code><code>DROP TABLE IF EXISTS customers;
DROP TABLE IF EXISTS orders;
DROP TABLE IF EXISTS payments;

CREATE TABLE customers (
  customer_id INTEGER PRIMARY KEY,
  name TEXT,
  country TEXT
);

CREATE TABLE orders (
  order_id INTEGER PRIMARY KEY,
  customer_id INTEGER,
  product TEXT,
  amount INTEGER
);

CREATE TABLE payments (
  payment_id INTEGER PRIMARY KEY,
  order_id INTEGER,
  payment_amount INTEGER
);

INSERT INTO customers (customer_id, name, country) VALUES
(1, 'Asha', 'India'),
(2, 'John', 'USA'),
(3, 'Maya', 'UK'),
(4, 'Liam', 'Canada');

INSERT INTO orders (order_id, customer_id, product, amount) VALUES
(101, 1, 'Laptop', 1000),
(102, 1, 'Mouse', 20),
(103, 2, 'Keyboard', 50),
(104, 2, 'Monitor', 200),
(105, 3, 'Tablet', 300);

INSERT INTO payments (payment_id, order_id, payment_amount) VALUES
(1, 101, 1000),
(2, 102, 20),
(3, 103, 40),   -- underpaid
(4, 104, 200),
(5, 105, 300);
</code></code></pre><div><hr></div><h2>Example 1 &#8212; Subquery in WHERE</h2><pre><code><code>-- Customers who have placed at least one order
SELECT name
FROM customers
WHERE customer_id IN (
  SELECT DISTINCT customer_id
  FROM orders
);
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>First the inner query finds all <code>customer_id</code> from <code>orders</code>.</p></li><li><p>The outer query checks which customers are in that list.</p></li><li><p>This avoids having to join.</p></li></ul><div><hr></div><h2>Example 2 &#8212; Subquery in SELECT</h2><pre><code><code>-- Show each customer and their total order amount
SELECT
  name,
  (SELECT SUM(amount)
   FROM orders o
   WHERE o.customer_id = c.customer_id) AS total_spent
FROM customers c;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>For each customer row, SQL runs the subquery to sum their orders.</p></li><li><p>This is like an Excel formula in each row.</p></li></ul><div><hr></div><h2>Example 3 &#8212; Subquery in FROM (derived table)</h2><pre><code><code>-- Find customers and their average order size
SELECT c.name, avg_orders.avg_amount
FROM customers c
JOIN (
  SELECT customer_id, AVG(amount) AS avg_amount
  FROM orders
  GROUP BY customer_id
) avg_orders
  ON c.customer_id = avg_orders.customer_id;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>The subquery in <code>FROM</code> calculates average order per customer.</p></li><li><p>We join that temporary table back to <code>customers</code>.</p></li><li><p>This is more efficient when reusing aggregates.</p></li></ul><div><hr></div><h2>Example 4 &#8212; Correlated subquery</h2><pre><code><code>-- Find customers who have an order larger than 500
SELECT name
FROM customers c
WHERE EXISTS (
  SELECT 1
  FROM orders o
  WHERE o.customer_id = c.customer_id
    AND o.amount &gt; 500
);
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>EXISTS</code> returns true if the subquery finds at least one row.</p></li><li><p>Here, it checks if each customer has a big order (&gt;500).</p></li><li><p>This depends on the outer query &#8594; correlated subquery.</p></li></ul><div><hr></div><h2>Example 5 &#8212; CTE (WITH clause)</h2><pre><code><code>-- CTE to calculate total payments vs orders
WITH order_totals AS (
  SELECT o.order_id, o.amount AS order_amount,
         COALESCE(SUM(p.payment_amount), 0) AS total_paid
  FROM orders o
  LEFT JOIN payments p ON o.order_id = p.order_id
  GROUP BY o.order_id
)
SELECT order_id, order_amount, total_paid,
       (order_amount - total_paid) AS balance
FROM order_totals;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>WITH order_totals AS (...)</code> defines a <strong>temporary table</strong>.</p></li><li><p>Then you can query it like a normal table.</p></li><li><p>Much cleaner than nested subqueries, easier to read.</p></li></ul><div><hr></div><h2>Example 6 &#8212; Multiple CTEs</h2><pre><code><code>-- CTEs can be chained
WITH order_totals AS (
  SELECT customer_id, SUM(amount) AS total_amount
  FROM orders
  GROUP BY customer_id
),
customer_payments AS (
  SELECT o.customer_id, SUM(p.payment_amount) AS total_paid
  FROM orders o
  JOIN payments p ON o.order_id = p.order_id
  GROUP BY o.customer_id
)
SELECT c.name, o.total_amount, cp.total_paid
FROM customers c
LEFT JOIN order_totals o ON c.customer_id = o.customer_id
LEFT JOIN customer_payments cp ON c.customer_id = cp.customer_id;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>First CTE calculates total order amount per customer.</p></li><li><p>Second CTE calculates total payments per customer.</p></li><li><p>Final query joins them all for a clear report.</p></li></ul><div><hr></div><h2>Quick checklist</h2><ul><li><p>Subqueries can be in <code>WHERE</code>, <code>SELECT</code>, or <code>FROM</code>.</p></li><li><p>Correlated subqueries depend on outer query.</p></li><li><p><code>EXISTS</code> is efficient for "does a row exist?" checks.</p></li><li><p>CTEs (<code>WITH</code>) make queries cleaner and reusable.</p></li></ul><div><hr></div><h2>10 Exercises (Chapter 4)</h2><ol><li><p>Write a query to list customers who have <strong>not placed any orders</strong> (use subquery in <code>WHERE</code>).</p></li><li><p>Show each customer&#8217;s name and their <strong>largest order amount</strong> (subquery in <code>SELECT</code>).</p></li><li><p>Using a subquery in <code>FROM</code>, calculate <strong>average payment per order</strong>.</p></li><li><p>Find customers who spent <strong>more than 500 in total</strong> (use correlated subquery).</p></li><li><p>Use <code>EXISTS</code> to find orders that have <strong>payments recorded</strong>.</p></li><li><p>Write a CTE to show orders and their <strong>remaining balance</strong> (order amount &#8211; total paid).</p></li><li><p>Write a query with <strong>two CTEs</strong>: one for total orders per customer, one for total payments, then join.</p></li><li><p>Find customers who have <strong>orders but no payments</strong>.</p></li><li><p>Use a subquery in <code>FROM</code> to calculate the <strong>top spender customer_id</strong>, then join to show their name.</p></li><li><p>Use a correlated subquery to show each order and whether it is <strong>above that customer&#8217;s average order size</strong>.</p></li></ol><div><hr></div><p>&#9989; <strong>Summary of this chapter</strong></p><ul><li><p>Subqueries let you nest questions inside questions.</p></li><li><p>CTEs make big queries readable and modular.</p></li><li><p>These are essential for complex analytics, especially in AI/ML pipelines where you need to <strong>prepare features</strong> from multiple data sources.</p></li></ul><div><hr></div><h1>Chapter 5 &#8212; Advanced Filtering &amp; Window Functions</h1><p>Now we&#8217;re moving into <strong>Chapter 5 &#8212; Advanced Filtering &amp; Window Functions</strong>.<br>This is one of the most <strong>critical chapters for AI/Data jobs</strong> because:</p><ul><li><p>You&#8217;ll need to handle <strong>ranking</strong> (e.g., top N customers).</p></li><li><p>You&#8217;ll calculate <strong>running totals, moving averages, differences</strong> &#8594; essential in <strong>time-series problems</strong> (stocks, sensors, logs).</p></li><li><p>You&#8217;ll handle <strong>conditional logic</strong> for feature engineering.</p></li></ul><div><hr></div><h2>What this chapter covers (plain language)</h2><ul><li><p><strong>CASE WHEN</strong> &#8594; if-else conditions inside SQL.</p></li><li><p><strong>COALESCE / NULLIF</strong> &#8594; deal with <code>NULL</code> values.</p></li><li><p><strong>Window functions</strong> (<code>OVER()</code>) &#8594; look at rows <strong>relative to each other</strong>.</p></li><li><p>Ranking: <code>ROW_NUMBER()</code>, <code>RANK()</code>, <code>DENSE_RANK()</code>.</p></li><li><p>Running totals, moving averages: <code>SUM() OVER()</code>, <code>AVG() OVER()</code>.</p></li><li><p>Time-series helpers: <code>LAG()</code>, <code>LEAD()</code>.</p></li></ul><div><hr></div><h2>Example setup (sales data)</h2><pre><code><code>DROP TABLE IF EXISTS sales;
CREATE TABLE sales (
  sale_id INTEGER PRIMARY KEY,
  customer TEXT,
  amount INTEGER,
  sale_date TEXT
);

INSERT INTO sales (sale_id, customer, amount, sale_date) VALUES
(1, 'Asha', 100, '2025-09-01'),
(2, 'John', 200, '2025-09-01'),
(3, 'Asha', 300, '2025-09-02'),
(4, 'Maya', 150, '2025-09-02'),
(5, 'John', 400, '2025-09-03'),
(6, 'Asha', 250, '2025-09-04'),
(7, 'Maya', 500, '2025-09-05');
</code></code></pre><div><hr></div><h2>Example 1 &#8212; CASE WHEN (if-else logic)</h2><pre><code><code>-- Label sales as 'High' if &gt; 300 else 'Low'
SELECT sale_id, customer, amount,
       CASE
         WHEN amount &gt; 300 THEN 'High'
         ELSE 'Low'
       END AS sale_category
FROM sales;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>CASE WHEN</code> works like <code>IF</code> in Excel or Python.</p></li><li><p>Here, sales above 300 are "High", others "Low".</p></li><li><p>You can nest multiple conditions too.</p></li></ul><div><hr></div><h2>Example 2 &#8212; COALESCE and NULLIF</h2><pre><code><code>DROP TABLE IF EXISTS payments;
CREATE TABLE payments (
  pay_id INTEGER PRIMARY KEY,
  customer TEXT,
  amount INTEGER,
  discount INTEGER
);

INSERT INTO payments (pay_id, customer, amount, discount) VALUES
(1, 'Asha', 100, NULL),
(2, 'John', 200, 20),
(3, 'Maya', 150, 0),
(4, 'Liam', 300, NULL);

-- Replace NULL discount with 0
SELECT pay_id, customer, amount,
       COALESCE(discount, 0) AS discount_applied
FROM payments;

-- Avoid divide-by-zero errors with NULLIF
SELECT pay_id, customer,
       amount / NULLIF(discount, 0) AS ratio
FROM payments;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>COALESCE(x, 0)</code> replaces NULL with a default (0).</p></li><li><p><code>NULLIF(x, 0)</code> returns NULL if <code>x = 0</code> (avoids divide by zero errors).</p></li></ul><div><hr></div><h2>Example 3 &#8212; ROW_NUMBER, RANK, DENSE_RANK</h2><pre><code><code>-- Rank sales per customer
SELECT customer, amount,
       ROW_NUMBER() OVER (PARTITION BY customer ORDER BY amount DESC) AS row_num,
       RANK() OVER (PARTITION BY customer ORDER BY amount DESC) AS rank_val,
       DENSE_RANK() OVER (PARTITION BY customer ORDER BY amount DESC) AS dense_rank_val
FROM sales;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>ROW_NUMBER()</code> &#8594; unique sequence (1,2,3&#8230;).</p></li><li><p><code>RANK()</code> &#8594; gives gaps (1,2,2,4).</p></li><li><p><code>DENSE_RANK()</code> &#8594; no gaps (1,2,2,3).</p></li><li><p><code>PARTITION BY customer</code> &#8594; restart numbering for each customer.</p></li></ul><div><hr></div><h2>Example 4 &#8212; Running totals with SUM OVER</h2><pre><code><code>-- Running total of sales by date
SELECT sale_date, customer, amount,
       SUM(amount) OVER (ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total
FROM sales;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>SUM(amount) OVER (ORDER BY sale_date)</code> &#8594; running total.</p></li><li><p><code>UNBOUNDED PRECEDING</code> = start from the first row.</p></li><li><p><code>CURRENT ROW</code> = up to this row.</p></li></ul><div><hr></div><h2>Example 5 &#8212; Moving averages with AVG OVER</h2><pre><code><code>-- 2-day moving average sales amount
SELECT sale_date, customer, amount,
       AVG(amount) OVER (
         ORDER BY sale_date
         ROWS BETWEEN 1 PRECEDING AND CURRENT ROW
       ) AS moving_avg
FROM sales;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>Looks at "current row + previous 1 row".</p></li><li><p>Calculates average over that window.</p></li><li><p>Useful for smoothing noisy time-series data.</p></li></ul><div><hr></div><h2>Example 6 &#8212; LAG and LEAD (time-series difference)</h2><pre><code><code>-- Compare each sale with previous sale (LAG)
SELECT sale_id, customer, amount, sale_date,
       LAG(amount) OVER (PARTITION BY customer ORDER BY sale_date) AS prev_amount,
       (amount - LAG(amount) OVER (PARTITION BY customer ORDER BY sale_date)) AS change_from_prev
FROM sales;

-- Look ahead with LEAD
SELECT sale_id, customer, amount, sale_date,
       LEAD(amount) OVER (PARTITION BY customer ORDER BY sale_date) AS next_amount
FROM sales;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>LAG(x)</code> &#8594; fetch previous row&#8217;s value.</p></li><li><p><code>LEAD(x)</code> &#8594; fetch next row&#8217;s value.</p></li><li><p>Great for calculating <strong>differences, growth rates, trends</strong>.</p></li></ul><div><hr></div><h2>Quick checklist</h2><ul><li><p><code>CASE WHEN</code> = if-else in SQL.</p></li><li><p><code>COALESCE</code> = replace NULL.</p></li><li><p><code>NULLIF</code> = avoid divide-by-zero.</p></li><li><p><code>ROW_NUMBER</code>, <code>RANK</code>, <code>DENSE_RANK</code> = row ranking.</p></li><li><p><code>SUM OVER</code> = running total.</p></li><li><p><code>AVG OVER</code> = moving average.</p></li><li><p><code>LAG</code> / <code>LEAD</code> = compare with previous/next row.</p></li></ul><div><hr></div><h2>10 Exercises (Chapter 5)</h2><ol><li><p>Label sales as <code>"Big"</code> if &gt; 250, <code>"Medium"</code> if between 100&#8211;250, else <code>"Small"</code>.</p></li><li><p>Show payments with NULL discounts replaced by 0 using <code>COALESCE</code>.</p></li><li><p>Find the <strong>top 2 highest sales per customer</strong> (use ROW_NUMBER).</p></li><li><p>Calculate the <strong>total revenue so far (running total)</strong> ordered by <code>sale_date</code>.</p></li><li><p>Find the <strong>average sales amount</strong> per customer (use <code>AVG() OVER PARTITION</code>).</p></li><li><p>Show each sale and the difference from the <strong>previous sale amount</strong> for that customer (use <code>LAG</code>).</p></li><li><p>Show each sale and the next sale amount for that customer (use <code>LEAD</code>).</p></li><li><p>Create a query that calculates a <strong>3-day moving average</strong> of sales.</p></li><li><p>Rank customers by <strong>total sales amount</strong> across all dates (use RANK).</p></li><li><p>Write a query that shows sales where the <strong>amount is greater than the customer&#8217;s average sale amount</strong> (use window AVG + comparison).</p></li></ol><div><hr></div><p>&#9989; <strong>Summary of this chapter</strong></p><ul><li><p>Window functions let you analyze <strong>trends across rows</strong> &#8212; essential for AI (time-series, ranking, anomaly detection).</p></li><li><p>Mastering <code>ROW_NUMBER</code>, <code>RANK</code>, <code>LAG</code>, <code>LEAD</code>, and running totals will make your SQL stand out.</p></li></ul><div><hr></div><h1>Chapter 6 &#8212; Data Manipulation (INSERT, UPDATE, DELETE, MERGE)</h1><p>Now we&#8217;ll cover <strong>Chapter 6 &#8212; Data Manipulation (INSERT, UPDATE, DELETE, MERGE/UPSERT)</strong>.</p><p>This is about <strong>changing data</strong>, not just reading it. In AI/data workflows, you&#8217;ll often <strong>insert cleaned data</strong>, <strong>update values</strong>, or <strong>delete errors</strong>. For ETL (Extract &#8594; Transform &#8594; Load), this chapter is key.</p><div><hr></div><h2>What this chapter covers (plain language)</h2><ul><li><p><code>INSERT</code> &#8594; add new rows.</p></li><li><p><code>UPDATE</code> &#8594; change values in existing rows.</p></li><li><p><code>DELETE</code> &#8594; remove rows.</p></li><li><p><code>MERGE</code> (or UPSERT) &#8594; insert new rows or update if they already exist.</p></li></ul><div><hr></div><h2>Example setup</h2><pre><code><code>DROP TABLE IF EXISTS employees;
CREATE TABLE employees (
  emp_id INTEGER PRIMARY KEY,
  name TEXT,
  role TEXT,
  salary INTEGER
);

INSERT INTO employees (emp_id, name, role, salary) VALUES
(1, 'Asha', 'Data Analyst', 50000),
(2, 'John', 'ML Engineer', 90000),
(3, 'Maya', 'Data Scientist', 85000);
</code></code></pre><div><hr></div><h2>Example 1 &#8212; INSERT</h2><pre><code><code>-- Insert a single row
INSERT INTO employees (emp_id, name, role, salary)
VALUES (4, 'Liam', 'DevOps', 75000);

-- Insert multiple rows at once
INSERT INTO employees (emp_id, name, role, salary)
VALUES
(5, 'Sara', 'Intern', 20000),
(6, 'Chen', 'Data Engineer', 80000);

-- Check the data
SELECT * FROM employees;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>INSERT INTO table (columns) VALUES (values)</code> adds a row.</p></li><li><p>You can add multiple rows in one statement.</p></li></ul><div><hr></div><h2>Example 2 &#8212; UPDATE</h2><pre><code><code>-- Update Sara's salary
UPDATE employees
SET salary = 25000
WHERE name = 'Sara';

-- Increase salary of all "Data" roles by 10%
UPDATE employees
SET salary = salary * 1.1
WHERE role LIKE 'Data%';

-- Check results
SELECT * FROM employees;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>UPDATE table SET column = value WHERE condition</code>.</p></li><li><p>Without <code>WHERE</code>, <strong>all rows</strong> will be updated (dangerous!).</p></li></ul><div><hr></div><h2>Example 3 &#8212; DELETE</h2><pre><code><code>-- Delete interns
DELETE FROM employees
WHERE role = 'Intern';

-- Delete all employees with salary &lt; 30000
DELETE FROM employees
WHERE salary &lt; 30000;

-- Check
SELECT * FROM employees;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>DELETE FROM table WHERE condition</code>.</p></li><li><p>If you forget <code>WHERE</code>, it deletes <strong>everything</strong>. Always double-check!</p></li></ul><div><hr></div><h2>Example 4 &#8212; UPSERT (INSERT OR REPLACE in SQLite)</h2><pre><code><code>-- If emp_id exists, replace it. If not, insert new.
INSERT OR REPLACE INTO employees (emp_id, name, role, salary)
VALUES (2, 'John', 'ML Engineer', 95000);

-- Insert new employee with same method
INSERT OR REPLACE INTO employees (emp_id, name, role, salary)
VALUES (7, 'Emma', 'AI Researcher', 100000);

SELECT * FROM employees;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>UPSERT = Update if exists, Insert if not.</p></li><li><p>In SQLite: <code>INSERT OR REPLACE</code>.</p></li><li><p>In PostgreSQL: <code>INSERT ... ON CONFLICT (id) DO UPDATE</code>.</p></li><li><p>In MySQL: <code>INSERT ... ON DUPLICATE KEY UPDATE</code>.</p></li></ul><div><hr></div><h2>Example 5 &#8212; MERGE (manual simulation for SQLite)</h2><p>SQLite doesn&#8217;t support <code>MERGE</code> directly. But let&#8217;s simulate.</p><p>Suppose we have a new data table:</p><pre><code><code>DROP TABLE IF EXISTS new_employees;
CREATE TABLE new_employees (
  emp_id INTEGER PRIMARY KEY,
  name TEXT,
  role TEXT,
  salary INTEGER
);

INSERT INTO new_employees (emp_id, name, role, salary) VALUES
(2, 'John', 'ML Engineer', 97000),  -- existing employee (update)
(8, 'Olivia', 'Data Engineer', 82000); -- new employee
</code></code></pre><p>Simulate MERGE:</p><pre><code><code>-- Step 1: Update existing
UPDATE employees
SET salary = (SELECT salary FROM new_employees ne WHERE ne.emp_id = employees.emp_id)
WHERE emp_id IN (SELECT emp_id FROM new_employees);

-- Step 2: Insert new ones
INSERT INTO employees (emp_id, name, role, salary)
SELECT ne.emp_id, ne.name, ne.role, ne.salary
FROM new_employees ne
WHERE ne.emp_id NOT IN (SELECT emp_id FROM employees);

-- Check final
SELECT * FROM employees;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>First <code>UPDATE</code> matches rows by <code>emp_id</code> and changes salary.</p></li><li><p>Then <code>INSERT</code> adds any new rows missing in <code>employees</code>.</p></li><li><p>That&#8217;s what <code>MERGE</code> does in big databases (Oracle, SQL Server).</p></li></ul><div><hr></div><h2>Quick checklist</h2><ul><li><p><code>INSERT</code> &#8594; add rows.</p></li><li><p><code>UPDATE</code> &#8594; change rows (always use <code>WHERE</code>).</p></li><li><p><code>DELETE</code> &#8594; remove rows (always use <code>WHERE</code>).</p></li><li><p><code>UPSERT/MERGE</code> &#8594; insert or update depending on whether the row exists.</p></li></ul><div><hr></div><h2>10 Exercises (Chapter 6)</h2><ol><li><p>Insert a new employee <code>"Ravi"</code> with role <code>"Data Intern"</code> and salary <code>15000</code>.</p></li><li><p>Insert 2 new employees in one query: <code>"Emma"</code> (AI Engineer, 110000), <code>"Noah"</code> (ML Intern, 18000).</p></li><li><p>Update salary of all <code>"Engineer"</code> roles by +5000.</p></li><li><p>Update <code>"Asha"</code>&#8217;s role from <code>"Data Analyst"</code> to <code>"Senior Data Analyst"</code>.</p></li><li><p>Delete all employees with role <code>"Intern"</code>.</p></li><li><p>Delete employees whose salary is <strong>less than 20000</strong>.</p></li><li><p>Use UPSERT to update John&#8217;s salary to <code>120000</code>.</p></li><li><p>Use UPSERT to insert a new employee <code>"David"</code> (DevOps, 70000).</p></li><li><p>Create a new table <code>new_hires</code> with 2 rows (1 existing emp_id, 1 new). Simulate MERGE: update the existing one, insert the new one.</p></li><li><p>Write a query that deletes all employees with <code>"Data"</code> in their role <strong>but only if salary &lt; 60000</strong>.</p></li></ol><div><hr></div><p>&#9989; <strong>Summary of this chapter</strong></p><ul><li><p>These commands are part of <strong>ETL and data cleaning</strong>.</p></li><li><p>In AI/data projects, you often <strong>insert raw data</strong>, <strong>update corrections</strong>, <strong>delete wrong rows</strong>, or <strong>merge new data feeds</strong>.</p></li><li><p>Always be careful with <code>UPDATE</code> and <code>DELETE</code> &#8212; forgetting <code>WHERE</code> wipes everything.</p></li></ul><div><hr></div><h1>Chapter 7 &#8212; Set Operations</h1><p>Let&#8217;s move to <strong>Chapter 7 &#8212; Set Operations (UNION, INTERSECT, EXCEPT)</strong>.</p><p>Set operations are about <strong>combining results of multiple queries</strong>. This is super useful in <strong>data integration, filtering, and feature creation</strong>.</p><div><hr></div><h2>What this chapter covers (plain language)</h2><ul><li><p><strong>UNION</strong> &#8594; combine results, remove duplicates.</p></li><li><p><strong>UNION ALL</strong> &#8594; combine results, keep duplicates.</p></li><li><p><strong>INTERSECT</strong> &#8594; rows that appear in both queries.</p></li><li><p><strong>EXCEPT / MINUS</strong> &#8594; rows in one query but not the other.</p></li></ul><p>&#128073; These are like <strong>Venn diagram operations</strong> for SQL.</p><div><hr></div><h2>Example setup</h2><pre><code><code>DROP TABLE IF EXISTS team_a;
DROP TABLE IF EXISTS team_b;

CREATE TABLE team_a (
  name TEXT
);

CREATE TABLE team_b (
  name TEXT
);

INSERT INTO team_a (name) VALUES
('Asha'),
('John'),
('Maya'),
('Liam');

INSERT INTO team_b (name) VALUES
('Maya'),
('John'),
('Olivia'),
('Emma');
</code></code></pre><ul><li><p>Team A: Asha, John, Maya, Liam</p></li><li><p>Team B: Maya, John, Olivia, Emma</p></li></ul><div><hr></div><h2>Example 1 &#8212; UNION (no duplicates)</h2><pre><code><code>-- All unique members from both teams
SELECT name FROM team_a
UNION
SELECT name FROM team_b;
</code></code></pre><p><strong>Result</strong>: Asha, John, Liam, Maya, Olivia, Emma (no duplicates).</p><p><strong>Layman explanation</strong>:</p><ul><li><p><code>UNION</code> merges results from both queries.</p></li><li><p>Duplicates are removed automatically.</p></li></ul><div><hr></div><h2>Example 2 &#8212; UNION ALL (keep duplicates)</h2><pre><code><code>-- All members, including duplicates
SELECT name FROM team_a
UNION ALL
SELECT name FROM team_b;
</code></code></pre><p><strong>Result</strong>: John and Maya appear twice (once from each team).</p><p><strong>Layman explanation</strong>:</p><ul><li><p><code>UNION ALL</code> keeps duplicates.</p></li><li><p>Faster than <code>UNION</code> (since no deduplication).</p></li></ul><div><hr></div><h2>Example 3 &#8212; INTERSECT</h2><pre><code><code>-- Members common to both teams
SELECT name FROM team_a
INTERSECT
SELECT name FROM team_b;
</code></code></pre><p><strong>Result</strong>: John, Maya</p><p><strong>Layman explanation</strong>:</p><ul><li><p><code>INTERSECT</code> = only rows that appear in both sets.</p></li><li><p>Like the overlap in a Venn diagram.</p></li></ul><div><hr></div><h2>Example 4 &#8212; EXCEPT (or MINUS)</h2><pre><code><code>-- Members in Team A but not in Team B
SELECT name FROM team_a
EXCEPT
SELECT name FROM team_b;
</code></code></pre><p><strong>Result</strong>: Asha, Liam</p><p><strong>Layman explanation</strong>:</p><ul><li><p><code>EXCEPT</code> = rows from first query that are not in second.</p></li><li><p>In Oracle, it&#8217;s called <code>MINUS</code>.</p></li></ul><div><hr></div><h2>Example 5 &#8212; More practical example (Orders vs Payments)</h2><p>Let&#8217;s reuse orders and payments.</p><pre><code><code>DROP TABLE IF EXISTS orders;
DROP TABLE IF EXISTS payments;

CREATE TABLE orders (
  order_id INTEGER PRIMARY KEY,
  customer TEXT
);

CREATE TABLE payments (
  payment_id INTEGER PRIMARY KEY,
  order_id INTEGER
);

INSERT INTO orders (order_id, customer) VALUES
(1, 'Asha'),
(2, 'John'),
(3, 'Maya'),
(4, 'Liam');

INSERT INTO payments (payment_id, order_id) VALUES
(101, 1),
(102, 2),
(103, 3);
</code></code></pre><ul><li><p>Orders: 1&#8211;4</p></li><li><p>Payments: 1&#8211;3</p></li></ul><pre><code><code>-- Orders that have been paid (intersection)
SELECT order_id FROM orders
INTERSECT
SELECT order_id FROM payments;

-- Orders that have not been paid (set difference)
SELECT order_id FROM orders
EXCEPT
SELECT order_id FROM payments;
</code></code></pre><p><strong>Result</strong>:</p><ul><li><p>Paid: 1, 2, 3</p></li><li><p>Not Paid: 4</p></li></ul><div><hr></div><h2>Quick checklist</h2><ul><li><p><code>UNION</code> = combine, remove duplicates.</p></li><li><p><code>UNION ALL</code> = combine, keep duplicates.</p></li><li><p><code>INTERSECT</code> = common rows.</p></li><li><p><code>EXCEPT</code> = rows in first query but not second.</p></li></ul><div><hr></div><h2>10 Exercises (Chapter 7)</h2><ol><li><p>List all unique names from <code>team_a</code> and <code>team_b</code> (use UNION).</p></li><li><p>List all names including duplicates (use UNION ALL).</p></li><li><p>Find names common to both teams (use INTERSECT).</p></li><li><p>Find names only in Team A (use EXCEPT).</p></li><li><p>Find names only in Team B (use EXCEPT).</p></li><li><p>Using <code>orders</code> and <code>payments</code>, find orders that have been paid (use INTERSECT).</p></li><li><p>Using <code>orders</code> and <code>payments</code>, find orders that have not been paid (use EXCEPT).</p></li><li><p>Insert a duplicate row into <code>team_a</code> (<code>John</code> again). Show difference between UNION and UNION ALL results.</p></li><li><p>Combine all customers and all employees into one list (create small extra tables).</p></li><li><p>Write a query to get customers who placed orders but are <strong>not in payments table</strong>.</p></li></ol><div><hr></div><p>&#9989; <strong>Summary of this chapter</strong></p><ul><li><p>Set operations are <strong>like Venn diagrams in SQL</strong>.</p></li><li><p>They are powerful for <strong>data comparison</strong> (paid vs unpaid, active vs inactive, A/B group differences).</p></li><li><p>Very handy in AI for <strong>feature creation and labeling</strong>.</p></li></ul><div><hr></div><h1>Chapter 8 &#8212; Data Cleaning &amp; Transformation</h1><p>Let&#8217;s continue with <strong>Chapter 8 &#8212; Data Cleaning &amp; Transformation</strong>.<br>This is one of the <strong>most practical chapters</strong> for AI/ML, because before you train any model, you&#8217;ll spend <strong>70&#8211;80% of your time cleaning and transforming raw data</strong>.</p><div><hr></div><h2>What this chapter covers (plain language)</h2><ul><li><p><strong>String functions</strong> &#8594; cleaning names, trimming spaces, searching text.</p></li><li><p><strong>Date &amp; time functions</strong> &#8594; extracting day/month/year, calculating differences.</p></li><li><p><strong>Type conversion</strong> &#8594; converting text to numbers or dates.</p></li><li><p><strong>Pivot/Unpivot</strong> &#8594; reshape data from wide &#8594; long or long &#8594; wide.</p></li></ul><div><hr></div><h2>Example setup</h2><pre><code><code>DROP TABLE IF EXISTS raw_data;
CREATE TABLE raw_data (
  id INTEGER PRIMARY KEY,
  name TEXT,
  email TEXT,
  signup_date TEXT,
  score TEXT
);

INSERT INTO raw_data (id, name, email, signup_date, score) VALUES
(1, '  Asha  ', 'asha@example.com', '2025-01-10', '85'),
(2, 'John', 'john@example.com', '2025-02-15', '90'),
(3, 'Maya Singh', 'maya_singh@example.com', '2025-03-20', 'NULL'),
(4, 'Liam', 'liam@example.com', '2025-03-25', '72'),
(5, 'Sara  ', 'sara@example.com', '2025-04-05', '88');
</code></code></pre><div><hr></div><h2>Example 1 &#8212; String functions</h2><pre><code><code>-- TRIM spaces
SELECT id, name, TRIM(name) AS clean_name FROM raw_data;

-- UPPER / LOWER
SELECT id, UPPER(name) AS upper_name, LOWER(name) AS lower_name FROM raw_data;

-- SUBSTRING (get first 4 letters)
SELECT id, SUBSTR(name, 1, 4) AS short_name FROM raw_data;

-- FIND position of '@' in email
SELECT id, INSTR(email, '@') AS at_position FROM raw_data;

-- CONCAT (combine name + email)
SELECT id, name || ' &lt;' || email || '&gt;' AS contact_info FROM raw_data;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>TRIM()</code> &#8594; removes extra spaces.</p></li><li><p><code>UPPER()</code>, <code>LOWER()</code> &#8594; normalize text.</p></li><li><p><code>SUBSTR()</code> &#8594; extract part of a string.</p></li><li><p><code>INSTR()</code> &#8594; find character position.</p></li><li><p><code>||</code> (SQLite) &#8594; concatenate strings.</p></li></ul><div><hr></div><h2>Example 2 &#8212; Date functions</h2><pre><code><code>-- Extract year, month, day
SELECT id, signup_date,
       STRFTIME('%Y', signup_date) AS year,
       STRFTIME('%m', signup_date) AS month,
       STRFTIME('%d', signup_date) AS day
FROM raw_data;

-- Days since signup
SELECT id, signup_date,
       JULIANDAY('2025-09-16') - JULIANDAY(signup_date) AS days_since_signup
FROM raw_data;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>STRFTIME('%Y')</code> &#8594; year, <code>%m</code> &#8594; month, <code>%d</code> &#8594; day.</p></li><li><p><code>JULIANDAY(date)</code> &#8594; number format &#8594; lets you subtract dates.</p></li></ul><div><hr></div><h2>Example 3 &#8212; Type conversion</h2><pre><code><code>-- Convert score from TEXT to INTEGER
SELECT id, name, CAST(score AS INTEGER) AS score_num
FROM raw_data;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>CAST(x AS INTEGER)</code> converts text &#8594; number.</p></li><li><p>Useful when data is stored as text in CSV files.</p></li></ul><div><hr></div><h2>Example 4 &#8212; Handling NULLs in transformation</h2><pre><code><code>-- Replace invalid score 'NULL' with 0
SELECT id, name,
       CASE WHEN score = 'NULL' THEN 0 ELSE CAST(score AS INTEGER) END AS clean_score
FROM raw_data;

-- OR using NULLIF + COALESCE
SELECT id, name,
       COALESCE(NULLIF(score, 'NULL'), 0) AS clean_score
FROM raw_data;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>NULLIF(score, 'NULL')</code> &#8594; treat <code>'NULL'</code> string as NULL.</p></li><li><p><code>COALESCE(..., 0)</code> &#8594; replace NULL with 0.</p></li></ul><div><hr></div><h2>Example 5 &#8212; Pivot (long &#8594; wide)</h2><p>Let&#8217;s make a table with scores in subjects.</p><pre><code><code>DROP TABLE IF EXISTS marks;
CREATE TABLE marks (
  student TEXT,
  subject TEXT,
  score INTEGER
);

INSERT INTO marks (student, subject, score) VALUES
('Asha', 'Math', 85),
('Asha', 'Science', 90),
('John', 'Math', 78),
('John', 'Science', 88);
</code></code></pre><p>Pivot (manual in SQLite):</p><pre><code><code>SELECT student,
       SUM(CASE WHEN subject = 'Math' THEN score END) AS math_score,
       SUM(CASE WHEN subject = 'Science' THEN score END) AS science_score
FROM marks
GROUP BY student;
</code></code></pre><p><strong>Result</strong>:</p><ul><li><p>Asha &#8594; 85, 90</p></li><li><p>John &#8594; 78, 88</p></li></ul><p><strong>Layman explanation</strong>:</p><ul><li><p>Pivot = convert "rows" into "columns".</p></li><li><p>We simulate it with <code>CASE WHEN</code>.</p></li></ul><div><hr></div><h2>Example 6 &#8212; Unpivot (wide &#8594; long)</h2><p>Suppose you have wide-format data:</p><pre><code><code>DROP TABLE IF EXISTS student_scores;
CREATE TABLE student_scores (
  student TEXT,
  math INTEGER,
  science INTEGER
);

INSERT INTO student_scores (student, math, science) VALUES
('Asha', 85, 90),
('John', 78, 88);
</code></code></pre><p>Unpivot (manual in SQLite):</p><pre><code><code>SELECT student, 'Math' AS subject, math AS score FROM student_scores
UNION ALL
SELECT student, 'Science' AS subject, science AS score FROM student_scores;
</code></code></pre><p><strong>Result</strong>:</p><ul><li><p>Asha, Math, 85</p></li><li><p>Asha, Science, 90</p></li><li><p>John, Math, 78</p></li><li><p>John, Science, 88</p></li></ul><p><strong>Layman explanation</strong>:</p><ul><li><p>Unpivot = convert "columns" into "rows".</p></li><li><p>Useful when you need to normalize wide Excel-like tables.</p></li></ul><div><hr></div><h2>Quick checklist</h2><ul><li><p><code>TRIM</code>, <code>UPPER</code>, <code>SUBSTR</code>, <code>INSTR</code> &#8594; clean strings.</p></li><li><p><code>STRFTIME</code>, <code>JULIANDAY</code> &#8594; extract and calculate with dates.</p></li><li><p><code>CAST</code>, <code>COALESCE</code>, <code>NULLIF</code> &#8594; fix dirty types and missing values.</p></li><li><p><code>CASE WHEN</code> inside SELECT &#8594; conditional transformation.</p></li><li><p>Pivot = rows &#8594; columns.</p></li><li><p>Unpivot = columns &#8594; rows.</p></li></ul><div><hr></div><h2>10 Exercises (Chapter 8)</h2><ol><li><p>Clean the <code>raw_data.name</code> column by trimming spaces.</p></li><li><p>Convert all names to uppercase.</p></li><li><p>Extract the year of signup for each customer.</p></li><li><p>Find customers who signed up in March (<code>%m = '03'</code>).</p></li><li><p>Convert <code>score</code> column to integer, treating <code>'NULL'</code> as 0.</p></li><li><p>Show number of days since each customer signed up (relative to today).</p></li><li><p>Create a pivot table from <code>marks</code> showing each student&#8217;s math and science score.</p></li><li><p>Create an unpivot table from <code>student_scores</code> showing subject + score.</p></li><li><p>Find customers whose email domain is <code>example.com</code> (use SUBSTR/INSTR).</p></li><li><p>Create a new column <code>score_category</code>: <code>"High"</code> if score &#8805; 85, <code>"Low"</code> otherwise.</p></li></ol><div><hr></div><p>&#9989; <strong>Summary of this chapter</strong></p><ul><li><p>This is the <strong>bread and butter of feature engineering</strong>: clean strings, handle dates, fix types, reshape data.</p></li><li><p>Pivot/unpivot is especially important in analytics pipelines.</p></li><li><p>Mastering this chapter makes you valuable for AI jobs, since 80% of ML time is <strong>data prep</strong>.</p></li></ul><div><hr></div><h1>Chapter 9 &#8212; Performance &amp; Optimization</h1><p>Let&#8217;s dive into <strong>Chapter 9 &#8212; Performance &amp; Optimization</strong>.<br>This is a <strong>must-know for AI/data jobs</strong>, because when you query millions of rows, <strong>slow SQL will waste hours</strong>. Even as a data/AI engineer, you need to understand <strong>indexes and query tuning basics</strong>.</p><div><hr></div><h2>What this chapter covers (plain language)</h2><ul><li><p>Why queries get slow.</p></li><li><p>How <strong>indexes</strong> speed things up.</p></li><li><p>How to check what SQL is doing (EXPLAIN).</p></li><li><p>Basic tips to make queries faster.</p></li></ul><p>&#9889; Reminder: You don&#8217;t need DBA-level tuning, but you <strong>must know enough</strong> to avoid writing queries that take hours instead of seconds.</p><div><hr></div><h2>Example setup</h2><pre><code><code>DROP TABLE IF EXISTS big_orders;
CREATE TABLE big_orders (
  order_id INTEGER PRIMARY KEY,
  customer TEXT,
  amount INTEGER,
  order_date TEXT
);

-- Insert 20 rows (imagine millions in real life)
INSERT INTO big_orders (order_id, customer, amount, order_date) VALUES
(1, 'Asha', 200, '2025-01-01'),
(2, 'John', 500, '2025-01-02'),
(3, 'Maya', 300, '2025-01-03'),
(4, 'Liam', 700, '2025-01-04'),
(5, 'Sara', 150, '2025-01-05'),
(6, 'Asha', 900, '2025-02-01'),
(7, 'John', 450, '2025-02-02'),
(8, 'Maya', 600, '2025-02-03'),
(9, 'Liam', 1000, '2025-02-04'),
(10, 'Sara', 120, '2025-02-05'),
(11, 'Asha', 400, '2025-03-01'),
(12, 'John', 250, '2025-03-02'),
(13, 'Maya', 850, '2025-03-03'),
(14, 'Liam', 950, '2025-03-04'),
(15, 'Sara', 500, '2025-03-05'),
(16, 'Asha', 100, '2025-04-01'),
(17, 'John', 750, '2025-04-02'),
(18, 'Maya', 200, '2025-04-03'),
(19, 'Liam', 300, '2025-04-04'),
(20, 'Sara', 400, '2025-04-05');
</code></code></pre><div><hr></div><h2>Example 1 &#8212; Full table scan</h2><pre><code><code>-- Find orders where amount &gt; 800
EXPLAIN QUERY PLAN
SELECT * FROM big_orders WHERE amount &gt; 800;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>Without an index, SQL will <strong>check every row</strong> (called a full table scan).</p></li><li><p>With 20 rows, it&#8217;s fine. With 20 million rows, it&#8217;s <strong>very slow</strong>.</p></li></ul><div><hr></div><h2>Example 2 &#8212; Creating an index</h2><pre><code><code>-- Create index on amount
CREATE INDEX idx_amount ON big_orders(amount);

-- Now run the same query
EXPLAIN QUERY PLAN
SELECT * FROM big_orders WHERE amount &gt; 800;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>An <strong>index</strong> is like the index in a book &#8594; faster lookup.</p></li><li><p>Now SQL doesn&#8217;t scan all rows, it jumps to rows where <code>amount &gt; 800</code>.</p></li></ul><div><hr></div><h2>Example 3 &#8212; Index on multiple columns</h2><pre><code><code>-- Index on (customer, order_date)
CREATE INDEX idx_customer_date ON big_orders(customer, order_date);

-- Query using that index
SELECT * FROM big_orders
WHERE customer = 'Asha' AND order_date &gt; '2025-02-01';
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>Composite indexes speed up queries filtering by <strong>two or more columns</strong>.</p></li><li><p>But only useful if your WHERE matches the order of columns.</p></li></ul><div><hr></div><h2>Example 4 &#8212; Avoiding SELECT *</h2><pre><code><code>-- Bad: SELECT *
SELECT * FROM big_orders WHERE customer = 'John';

-- Good: only select needed columns
SELECT customer, amount FROM big_orders WHERE customer = 'John';
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>SELECT *</code> loads all columns, even if you don&#8217;t need them.</p></li><li><p>In huge tables with 50+ columns, this slows down queries.</p></li></ul><div><hr></div><h2>Example 5 &#8212; Avoiding unnecessary functions in WHERE</h2><pre><code><code>-- Bad: function on column (index not used)
SELECT * FROM big_orders
WHERE STRFTIME('%Y', order_date) = '2025';

-- Good: compare directly (uses index)
SELECT * FROM big_orders
WHERE order_date BETWEEN '2025-01-01' AND '2025-12-31';
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>If you wrap columns in functions, indexes are ignored.</p></li><li><p>Instead, filter using raw values.</p></li></ul><div><hr></div><h2>Example 6 &#8212; LIMIT for efficiency</h2><pre><code><code>-- Get top 5 biggest orders
SELECT customer, amount
FROM big_orders
ORDER BY amount DESC
LIMIT 5;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>Always use <code>LIMIT</code> when exploring.</p></li><li><p>Otherwise, queries may return <strong>millions of rows</strong> and choke memory.</p></li></ul><div><hr></div><h2>Quick checklist (Performance Rules of Thumb)</h2><ul><li><p>Always index columns used in <code>WHERE</code>, <code>JOIN</code>, <code>ORDER BY</code>.</p></li><li><p>Avoid <code>SELECT *</code>, pick only needed columns.</p></li><li><p>Avoid wrapping columns in functions inside <code>WHERE</code>.</p></li><li><p>Use <code>LIMIT</code> when exploring.</p></li><li><p>Use <code>EXPLAIN</code> to check if indexes are used.</p></li></ul><div><hr></div><h2>10 Exercises (Chapter 9)</h2><ol><li><p>Create an index on <code>customer</code> in <code>big_orders</code>. Run a query filtering by <code>customer</code> and check with <code>EXPLAIN</code>.</p></li><li><p>Create a composite index on <code>(customer, amount)</code> and query John&#8217;s orders above 400.</p></li><li><p>Write a query to get the <strong>top 3 biggest orders</strong>.</p></li><li><p>Write a query to find orders in March 2025 without using functions in WHERE.</p></li><li><p>Compare <code>SELECT *</code> vs selecting only <code>customer, amount</code>.</p></li><li><p>Delete index <code>idx_amount</code> and check how <code>EXPLAIN</code> changes for <code>amount &gt; 800</code>.</p></li><li><p>Find all orders by <code>Asha</code> after <code>2025-03-01</code> (ensure your index helps).</p></li><li><p>Create a query that sorts by <code>order_date DESC</code> and limits to last 2 orders.</p></li><li><p>Insert 2 duplicate rows for <code>John</code> with amount 500. How would you ensure uniqueness? (Hint: PRIMARY KEY, UNIQUE).</p></li><li><p>Use <code>EXPLAIN QUERY PLAN</code> on a simple query, and check whether it says "USING INDEX".</p></li></ol><div><hr></div><p>&#9989; <strong>Summary of this chapter</strong></p><ul><li><p>SQL performance is mostly about <strong>indexes</strong>.</p></li><li><p>Good habits: avoid <code>SELECT *</code>, use LIMIT, filter smartly.</p></li><li><p>For AI/data jobs, you don&#8217;t need to be a tuning expert &#8212; but knowing this saves you from <strong>slow pipelines</strong>.</p></li></ul><div><hr></div><p>Perfect Bavi &#128640; Now we&#8217;ve reached the <strong>final practical chapter</strong>:<br><strong>Chapter 10 &#8212; AI/Data Job Specific SQL (Feature Engineering, Time-Series, Data Quality Checks)</strong>.</p><p>This is where everything we&#8217;ve learned ties into <strong>AI/ML workflows</strong>. SQL here is used to <strong>prepare datasets</strong>, create <strong>features</strong>, and ensure <strong>data quality</strong> before training models.</p><div><hr></div><h1>Chapter 10 &#8212; AI/Data Job Specific SQL</h1><div><hr></div><h2>What this chapter covers (plain language)</h2><ul><li><p><strong>Feature engineering in SQL</strong> (new columns from raw data).</p></li><li><p><strong>Time-series operations</strong> (lags, moving averages).</p></li><li><p><strong>ETL workflows</strong> (Extract &#8594; Transform &#8594; Load).</p></li><li><p><strong>Data quality checks</strong> (missing values, duplicates).</p></li><li><p><strong>SQL + Python integration</strong> (using Pandas + SQLAlchemy).</p></li></ul><div><hr></div><h2>Example setup (transactions)</h2><pre><code><code>DROP TABLE IF EXISTS transactions;
CREATE TABLE transactions (
  txn_id INTEGER PRIMARY KEY,
  customer TEXT,
  amount INTEGER,
  txn_date TEXT
);

INSERT INTO transactions (txn_id, customer, amount, txn_date) VALUES
(1, 'Asha', 100, '2025-01-01'),
(2, 'Asha', 200, '2025-01-05'),
(3, 'John', 500, '2025-01-02'),
(4, 'John', 50, '2025-01-10'),
(5, 'Maya', 300, '2025-01-03'),
(6, 'Maya', 400, '2025-01-06'),
(7, 'Maya', 150, '2025-01-09');
</code></code></pre><div><hr></div><h2>Example 1 &#8212; Feature engineering: totals and averages</h2><pre><code><code>-- Total and average spend per customer
SELECT customer,
       SUM(amount) AS total_spent,
       AVG(amount) AS avg_spent,
       COUNT(*) AS txn_count
FROM transactions
GROUP BY customer;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>Features = new columns for ML (like "total spend", "average spend").</p></li><li><p>This is classic SQL feature engineering.</p></li></ul><div><hr></div><h2>Example 2 &#8212; Recency feature (days since last transaction)</h2><pre><code><code>-- Days since last transaction (relative to 2025-01-15)
SELECT customer,
       MAX(txn_date) AS last_txn,
       JULIANDAY('2025-01-15') - JULIANDAY(MAX(txn_date)) AS days_since_last
FROM transactions
GROUP BY customer;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>Recency is a key feature in customer churn models.</p></li><li><p>Here, we calculate days since the most recent transaction.</p></li></ul><div><hr></div><h2>Example 3 &#8212; Time-series: lag feature</h2><pre><code><code>-- Compare each txn amount to previous txn of same customer
SELECT txn_id, customer, txn_date, amount,
       LAG(amount) OVER (PARTITION BY customer ORDER BY txn_date) AS prev_amount,
       (amount - LAG(amount) OVER (PARTITION BY customer ORDER BY txn_date)) AS diff_from_prev
FROM transactions;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p><code>LAG()</code> &#8594; fetch previous transaction.</p></li><li><p>The <code>diff_from_prev</code> feature helps detect anomalies/trends.</p></li></ul><div><hr></div><h2>Example 4 &#8212; Moving average feature</h2><pre><code><code>-- 2-transaction moving average per customer
SELECT txn_id, customer, txn_date, amount,
       AVG(amount) OVER (
         PARTITION BY customer
         ORDER BY txn_date
         ROWS BETWEEN 1 PRECEDING AND CURRENT ROW
       ) AS moving_avg
FROM transactions;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>Moving averages smooth out noisy data.</p></li><li><p>Very useful for forecasting (stock prices, sales).</p></li></ul><div><hr></div><h2>Example 5 &#8212; Data quality checks</h2><pre><code><code>-- Missing values check
SELECT * FROM transactions
WHERE customer IS NULL OR amount IS NULL OR txn_date IS NULL;

-- Duplicate detection
SELECT customer, txn_date, COUNT(*) AS dup_count
FROM transactions
GROUP BY customer, txn_date
HAVING COUNT(*) &gt; 1;

-- Outlier detection (txns &gt; 3x average)
WITH avg_txn AS (
  SELECT AVG(amount) AS avg_amt FROM transactions
)
SELECT t.*
FROM transactions t, avg_txn
WHERE t.amount &gt; 3 * avg_txn.avg_amt;
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>AI pipelines break if you have missing values or duplicates.</p></li><li><p>SQL can quickly check data quality before loading into ML.</p></li></ul><div><hr></div><h2>Example 6 &#8212; SQL + Python integration (concept)</h2><p>In real projects, you&#8217;ll pull SQL data into Pandas for ML.</p><pre><code><code>import pandas as pd
from sqlalchemy import create_engine

# Connect to SQLite DB
engine = create_engine("sqlite:///mydb.db")

# Load features directly from SQL
query = """
SELECT customer,
       SUM(amount) AS total_spent,
       AVG(amount) AS avg_spent,
       COUNT(*) AS txn_count
FROM transactions
GROUP BY customer;
"""
df = pd.read_sql(query, engine)
print(df)
</code></code></pre><p><strong>Layman explanation</strong>:</p><ul><li><p>Use <code>pandas.read_sql()</code> to directly fetch query results.</p></li><li><p>SQL does the <strong>aggregation</strong>, Python does the <strong>ML</strong>.</p></li></ul><div><hr></div><h2>Quick checklist (AI/ML focus)</h2><ul><li><p><strong>Feature engineering</strong> &#8594; totals, averages, recency, frequency.</p></li><li><p><strong>Time-series</strong> &#8594; lag, lead, moving averages.</p></li><li><p><strong>Data quality</strong> &#8594; check for NULLs, duplicates, outliers.</p></li><li><p><strong>ETL in SQL</strong> &#8594; clean + transform before exporting to Python.</p></li><li><p><strong>SQL + Pandas</strong> &#8594; combine the best of both worlds.</p></li></ul><div><hr></div><h2>10 Exercises (Chapter 10)</h2><ol><li><p>Calculate each customer&#8217;s <strong>total transactions</strong> and <strong>average spend</strong>.</p></li><li><p>Find customers who spent <strong>more than 500 in total</strong>.</p></li><li><p>For each customer, calculate <strong>days since last txn</strong> (relative to 2025-01-15).</p></li><li><p>Use <code>LAG()</code> to show difference between each txn and previous txn.</p></li><li><p>Use a 3-transaction moving average per customer.</p></li><li><p>Check if any rows have <code>NULL</code> values in <code>transactions</code>.</p></li><li><p>Find if there are duplicate <code>(customer, txn_date)</code> rows.</p></li><li><p>Detect outlier transactions &gt; 2&#215; customer&#8217;s average.</p></li><li><p>Combine SQL + Python: pull transaction summary into Pandas and plot bar chart (code in Python).</p></li><li><p>Create features: <code>total_spent</code>, <code>txn_count</code>, <code>days_since_last</code> &#8594; imagine these as model inputs.</p></li></ol><div><hr></div><p>&#9989; <strong>Summary of this chapter</strong></p><ul><li><p>SQL is not just for querying &#8594; it&#8217;s a <strong>feature engineering toolkit</strong>.</p></li><li><p>Time-series SQL (<code>LAG</code>, <code>LEAD</code>, moving averages) = gold for forecasting.</p></li><li><p>Data quality SQL prevents garbage-in &#8594; garbage-out in ML.</p></li><li><p>In real AI projects: <strong>SQL prepares the data &#8594; Python/R trains the model</strong>.</p></li></ul><div><hr></div><p></p>]]></content:encoded></item><item><title><![CDATA[QA Cloud-Native Testing Bootcamp Using Manual, Automation & DevOps]]></title><description><![CDATA[Full-Stack QA Training: Automation, API, DevOps & Real-Time Projects]]></description><link>https://careerbytecode.substack.com/p/qa-cloud-native-testing-bootcamp-live-handson-training-using-manual-automation-devops</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/qa-cloud-native-testing-bootcamp-live-handson-training-using-manual-automation-devops</guid><dc:creator><![CDATA[CareerByteCode]]></dc:creator><pubDate>Mon, 28 Jul 2025 21:18:28 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!gNLa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a1b12e5-5ec4-4e22-9c5e-04da94b7c17e_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gNLa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a1b12e5-5ec4-4e22-9c5e-04da94b7c17e_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gNLa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a1b12e5-5ec4-4e22-9c5e-04da94b7c17e_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!gNLa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a1b12e5-5ec4-4e22-9c5e-04da94b7c17e_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!gNLa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a1b12e5-5ec4-4e22-9c5e-04da94b7c17e_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!gNLa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a1b12e5-5ec4-4e22-9c5e-04da94b7c17e_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gNLa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a1b12e5-5ec4-4e22-9c5e-04da94b7c17e_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1a1b12e5-5ec4-4e22-9c5e-04da94b7c17e_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:453609,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/168945351?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a1b12e5-5ec4-4e22-9c5e-04da94b7c17e_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gNLa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a1b12e5-5ec4-4e22-9c5e-04da94b7c17e_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!gNLa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a1b12e5-5ec4-4e22-9c5e-04da94b7c17e_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!gNLa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a1b12e5-5ec4-4e22-9c5e-04da94b7c17e_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!gNLa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a1b12e5-5ec4-4e22-9c5e-04da94b7c17e_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h2><strong>&#128313; Week 1: Introduction to Software Testing (Manual Testing Basics)</strong></h2><h3><strong>&#127919; Learning Objectives:</strong></h3><ul><li><p>Understand software testing life cycle and its role in SDLC</p></li><li><p>Learn test planning, case writing, and defect reporting</p></li></ul><h3><strong>&#9989; Topics Covered:</strong></h3><ul><li><p>What is QA? QC vs Testing</p></li><li><p>SDLC, STLC &amp; Agile Testing Basics</p></li><li><p>Types of Testing (Functional, Regression, Smoke, UAT, etc.)</p></li><li><p>Test Plan, Test Strategy, Test Case vs Test Scenario</p></li><li><p>Bug Life Cycle: Severity vs Priority</p></li><li><p>Exploratory Testing, Boundary Value, and Equivalence Partitioning</p></li><li><p>Defect Reporting using JIRA</p></li></ul><h2>Day 1 :</h2><h4><strong>What is QA? QC vs Testing</strong></h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DsF1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23df3afc-b3e1-4d93-b477-cd7b7ca74015_316x281.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DsF1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23df3afc-b3e1-4d93-b477-cd7b7ca74015_316x281.png 424w, https://substackcdn.com/image/fetch/$s_!DsF1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23df3afc-b3e1-4d93-b477-cd7b7ca74015_316x281.png 848w, https://substackcdn.com/image/fetch/$s_!DsF1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23df3afc-b3e1-4d93-b477-cd7b7ca74015_316x281.png 1272w, https://substackcdn.com/image/fetch/$s_!DsF1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23df3afc-b3e1-4d93-b477-cd7b7ca74015_316x281.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DsF1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23df3afc-b3e1-4d93-b477-cd7b7ca74015_316x281.png" width="316" height="281" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/23df3afc-b3e1-4d93-b477-cd7b7ca74015_316x281.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:281,&quot;width&quot;:316,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!DsF1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23df3afc-b3e1-4d93-b477-cd7b7ca74015_316x281.png 424w, https://substackcdn.com/image/fetch/$s_!DsF1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23df3afc-b3e1-4d93-b477-cd7b7ca74015_316x281.png 848w, https://substackcdn.com/image/fetch/$s_!DsF1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23df3afc-b3e1-4d93-b477-cd7b7ca74015_316x281.png 1272w, https://substackcdn.com/image/fetch/$s_!DsF1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F23df3afc-b3e1-4d93-b477-cd7b7ca74015_316x281.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Quality Assurance(QA)</strong> is process oriented, ensures to build the right product and focuses on preventing defects by improving and monitoring the processes to develop the product.</p><p><em>Example-</em> QA is like the manager in the pizza restaurant checks if the chefs are using cleaned tools, fresh ingredients and following the pizza recipe correctly which makes sure the process is right or not.</p><p><strong>Quality Control(QC)</strong> is product oriented, ensuring that the software meets defined standards and requirements by identifying the defects in the product before releasing it.</p><p>Example- QC is like the final check of pizza before delivering/giving/serving it to the customer to make sure it looks and tastes good.</p><p><strong>Testing</strong> is like an activity within QC. It executes the software to find defects and verify if the software functions as expected.</p><p>Example- Testing is like tasting a slice of pizza to check the flavours, toppings and cooking are just right before serving it to the customer.</p><p></p><h4><strong>SDLC, STLC &amp; Agile Testing Basics</strong></h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SQe-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87420de6-4fde-4f1f-86df-41a723c44ab5_713x353.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SQe-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87420de6-4fde-4f1f-86df-41a723c44ab5_713x353.png 424w, https://substackcdn.com/image/fetch/$s_!SQe-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87420de6-4fde-4f1f-86df-41a723c44ab5_713x353.png 848w, https://substackcdn.com/image/fetch/$s_!SQe-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87420de6-4fde-4f1f-86df-41a723c44ab5_713x353.png 1272w, https://substackcdn.com/image/fetch/$s_!SQe-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87420de6-4fde-4f1f-86df-41a723c44ab5_713x353.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SQe-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87420de6-4fde-4f1f-86df-41a723c44ab5_713x353.png" width="713" height="353" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/87420de6-4fde-4f1f-86df-41a723c44ab5_713x353.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:353,&quot;width&quot;:713,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:&quot;&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!SQe-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87420de6-4fde-4f1f-86df-41a723c44ab5_713x353.png 424w, https://substackcdn.com/image/fetch/$s_!SQe-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87420de6-4fde-4f1f-86df-41a723c44ab5_713x353.png 848w, https://substackcdn.com/image/fetch/$s_!SQe-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87420de6-4fde-4f1f-86df-41a723c44ab5_713x353.png 1272w, https://substackcdn.com/image/fetch/$s_!SQe-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87420de6-4fde-4f1f-86df-41a723c44ab5_713x353.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p>
      <p>
          <a href="https://careerbytecode.substack.com/p/qa-cloud-native-testing-bootcamp-live-handson-training-using-manual-automation-devops">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Class 31: Mastering Ingress in Kubernetes with Helm on Azure AKS – Step-by-Step Routing in Action]]></title><description><![CDATA[Setting Up NGINX Ingress with AKS (Cloud DevOps Bootcamp)]]></description><link>https://careerbytecode.substack.com/p/class31-mastering-ingress-in-kubernetes-with-helm-on-azure-aks-step-by-step-routing-in-action</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/class31-mastering-ingress-in-kubernetes-with-helm-on-azure-aks-step-by-step-routing-in-action</guid><dc:creator><![CDATA[CareerByteCode]]></dc:creator><pubDate>Mon, 28 Jul 2025 07:50:52 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!16nZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc319f18-da3f-4a2b-9ca5-bfec0fdf963c_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!16nZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc319f18-da3f-4a2b-9ca5-bfec0fdf963c_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!16nZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc319f18-da3f-4a2b-9ca5-bfec0fdf963c_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!16nZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc319f18-da3f-4a2b-9ca5-bfec0fdf963c_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!16nZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc319f18-da3f-4a2b-9ca5-bfec0fdf963c_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!16nZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc319f18-da3f-4a2b-9ca5-bfec0fdf963c_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!16nZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc319f18-da3f-4a2b-9ca5-bfec0fdf963c_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cc319f18-da3f-4a2b-9ca5-bfec0fdf963c_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:442947,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/169433686?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc319f18-da3f-4a2b-9ca5-bfec0fdf963c_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!16nZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc319f18-da3f-4a2b-9ca5-bfec0fdf963c_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!16nZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc319f18-da3f-4a2b-9ca5-bfec0fdf963c_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!16nZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc319f18-da3f-4a2b-9ca5-bfec0fdf963c_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!16nZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc319f18-da3f-4a2b-9ca5-bfec0fdf963c_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p></p><h3>&#128640; Introduction</h3><p>In Kubernetes, <strong>Ingress</strong> offers a powerful way to expose HTTP and HTTPS services running inside the cluster to the outside world. Rather than exposing each service with a separate LoadBalancer or NodePort, you can use a single Ingress Controller to route traffic to multiple services based on hostname or path rules.</p><p>In this session, you&#8217;ll learn how to:</p><ul><li><p>Deploy two versions of a Hello World app.</p></li><li><p>Install the NGINX Ingress Controller using <strong>Helm</strong>.</p></li><li><p>Create an Ingress Resource to route traffic based on hostnames.</p></li><li><p>Access the apps via a custom domain simulation (via <code>/etc/hosts</code>).</p></li><li><p>Understand DNS configuration options.</p></li></ul><p>We are using an <strong>Azure Kubernetes Service (AKS)</strong> cluster with two worker nodes, and <code>kubectl</code> is configured to connect to the cluster.</p><p></p>
      <p>
          <a href="https://careerbytecode.substack.com/p/class31-mastering-ingress-in-kubernetes-with-helm-on-azure-aks-step-by-step-routing-in-action">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Class 22: Mastering CI/CD Pipelines with Jenkins, SonarQube, and Nexus – Automating Code Quality, Artifact Management, and Seamless Deployments]]></title><description><![CDATA[By automating code quality checks and managing artifacts efficiently, we ensure that only quality-verified code reaches production, reducing errors and speeding up delivery cycles.]]></description><link>https://careerbytecode.substack.com/p/class22-mastering-cicd-pipelines-with-jenkins-sonarqube-and-nexus-automating-code-quality-artifact-management-and-seamless-deployments</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/class22-mastering-cicd-pipelines-with-jenkins-sonarqube-and-nexus-automating-code-quality-artifact-management-and-seamless-deployments</guid><dc:creator><![CDATA[CareerByteCode]]></dc:creator><pubDate>Sun, 29 Jun 2025 19:56:40 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!tSB6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbca42b68-dc12-42d0-b568-467931992acc_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tSB6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbca42b68-dc12-42d0-b568-467931992acc_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tSB6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbca42b68-dc12-42d0-b568-467931992acc_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!tSB6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbca42b68-dc12-42d0-b568-467931992acc_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!tSB6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbca42b68-dc12-42d0-b568-467931992acc_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!tSB6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbca42b68-dc12-42d0-b568-467931992acc_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tSB6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbca42b68-dc12-42d0-b568-467931992acc_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bca42b68-dc12-42d0-b568-467931992acc_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1128836,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/167125495?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbca42b68-dc12-42d0-b568-467931992acc_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tSB6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbca42b68-dc12-42d0-b568-467931992acc_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!tSB6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbca42b68-dc12-42d0-b568-467931992acc_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!tSB6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbca42b68-dc12-42d0-b568-467931992acc_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!tSB6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbca42b68-dc12-42d0-b568-467931992acc_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p></p><p>&#128273; <strong>Key Takeaways:</strong></p><ul><li><p><strong>CI/CD Pipeline Setup</strong>: Integrated <strong>Jenkins</strong>, <strong>SonarQube</strong>, and <strong>Nexus</strong> for a streamlined build and deployment pipeline.</p></li><li><p><strong>Automated Code Quality</strong>: Learn how to use <strong>SonarQube</strong> for code quality checks and <strong>Nexus</strong> for artifact management.</p></li><li><p><strong>Building Robust Pipelines</strong>: Automate deployment from <strong>GitHub</strong> to <strong>Jenkins</strong>, analyze with <strong>SonarQube</strong>, and push artifacts to <strong>Nexus</strong>.</p></li><li><p><strong>Maven Integration</strong>: Manage <strong>artifact versions</strong> (SNAPSHOT vs. RELEASE) with <strong>Nexus</strong> to avoid overwriting and maintain version control.</p></li><li><p><strong>SonarQube Setup</strong>: Configure <strong>SonarQube</strong> for static code analysis and enforce <strong>quality gates</strong> before production.</p></li><li><p><strong>Deploy to Nexus</strong>: Store <strong>SNAPSHOT</strong> and <strong>RELEASE</strong> artifacts in <strong>Nexus</strong>, maintaining traceability and version control.</p></li><li><p><strong>Practical Demo</strong>: Live demo of <strong>Jenkins setup</strong>, <strong>SonarQube analysis</strong>, and <strong>Nexus deployment</strong> for artifact management and quality assurance.</p></li></ul><p>&#128073; <strong>Why This Class Matters?</strong></p><ul><li><p>CI/CD pipelines are essential in today&#8217;s agile environments. By automating code quality checks and managing artifacts efficiently, we ensure that only <strong>quality-verified code</strong> reaches production, reducing errors and speeding up delivery cycles.</p></li></ul><p>&#127760; <strong>Catch up on today&#8217;s session</strong> and get all the details here:<br>Class 22 - Jenkins, SonarQube, and Nexus CI/CD Pipeline</p><p>&#128172; <strong>Share this with your peers</strong> and colleagues who want to boost their <strong>DevOps skills</strong>! &#128104;&#8205;&#128187;&#128105;&#8205;&#128187;</p><p></p>
      <p>
          <a href="https://careerbytecode.substack.com/p/class22-mastering-cicd-pipelines-with-jenkins-sonarqube-and-nexus-automating-code-quality-artifact-management-and-seamless-deployments">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Class 30 - Mastering CI/CD with Jenkins: Integrating SonarQube and Nexus for Automated Builds and Deployments]]></title><description><![CDATA[By automating code quality checks and managing artifacts properly, you ensure that only the highest quality code is deployed, reducing errors and speeding up delivery cycles.]]></description><link>https://careerbytecode.substack.com/p/class30-mastering-cicd-with-jenkins-integrating-sonarqube-and-nexus-for-automated-builds-and-deployments</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/class30-mastering-cicd-with-jenkins-integrating-sonarqube-and-nexus-for-automated-builds-and-deployments</guid><dc:creator><![CDATA[CareerByteCode]]></dc:creator><pubDate>Sun, 29 Jun 2025 19:43:49 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!PE2I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf15384e-0748-4566-9eff-db73c185dfc5_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!PE2I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf15384e-0748-4566-9eff-db73c185dfc5_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!PE2I!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf15384e-0748-4566-9eff-db73c185dfc5_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!PE2I!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf15384e-0748-4566-9eff-db73c185dfc5_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!PE2I!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf15384e-0748-4566-9eff-db73c185dfc5_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!PE2I!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf15384e-0748-4566-9eff-db73c185dfc5_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!PE2I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf15384e-0748-4566-9eff-db73c185dfc5_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/df15384e-0748-4566-9eff-db73c185dfc5_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:484618,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/167124191?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf15384e-0748-4566-9eff-db73c185dfc5_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!PE2I!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf15384e-0748-4566-9eff-db73c185dfc5_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!PE2I!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf15384e-0748-4566-9eff-db73c185dfc5_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!PE2I!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf15384e-0748-4566-9eff-db73c185dfc5_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!PE2I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf15384e-0748-4566-9eff-db73c185dfc5_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p></p><h3>&#128273; <strong>Key Takeaways from Today&#8217;s Class:</strong></h3><ol><li><p><strong>CI/CD Pipeline Setup</strong>:</p><ul><li><p>Integrated <strong>Jenkins</strong>, <strong>SonarQube</strong>, and <strong>Nexus</strong> for a seamless <strong>build</strong> and <strong>deployment</strong> pipeline.</p></li><li><p>Automated <strong>code quality checks</strong> using SonarQube and <strong>artifact management</strong> using Nexus.</p></li></ul></li><li><p><strong>Building Robust Pipelines</strong>:</p><ul><li><p>Learn how to <strong>automatically deploy</strong> code from <strong>GitHub</strong> to Jenkins, analyze it with SonarQube, and push the resulting artifacts to Nexus for version control.</p></li></ul></li><li><p><strong>Maven Integration</strong>:</p><ul><li><p>Managed <strong>artifact versions</strong> (SNAPSHOT vs. RELEASE) to avoid <strong>overwriting</strong> and ensure <strong>version discipline</strong> using Nexus.</p></li></ul></li><li><p><strong>SonarQube Setup</strong>:</p><ul><li><p>Configured <strong>SonarQube</strong> for static code analysis and enforced <strong>quality gates</strong> before production.</p></li><li><p>Ensured only <strong>quality-verified code</strong> reaches production environments.</p></li></ul></li><li><p><strong>Deploy to Nexus</strong>:</p><ul><li><p>Learn to configure <strong>Nexus</strong> for storing development and production artifacts, maintaining traceability and version control.</p></li><li><p>Pushed <strong>SNAPSHOT</strong> and <strong>RELEASE</strong> artifacts to different repositories for better management.</p></li></ul></li><li><p><strong>Practical Demo</strong>:</p><ul><li><p><strong>Live demo</strong> of setting up Jenkins, configuring SonarQube for analysis, and deploying artifacts to Nexus.</p></li><li><p>Walkthrough on <strong>version management</strong>, <strong>quality control</strong>, and <strong>deployment automation</strong>.</p></li></ul></li></ol><div><hr></div><p>&#128073; <strong>Why This Class Matters?</strong></p><ul><li><p><strong>Continuous Integration</strong> and <strong>Continuous Delivery (CI/CD)</strong> pipelines are vital for today&#8217;s agile development environment.</p></li><li><p>By automating code quality checks and managing artifacts properly, you ensure that only the highest quality code is deployed, reducing errors and speeding up delivery cycles.</p></li></ul><p>&#127760; <strong>Check out today&#8217;s session and get all the details here</strong>:<br></p><p>&#128172; <strong>Feel free to share with your peers and colleagues who want to enhance their DevOps skills!</strong> &#128105;&#8205;&#128187;&#128104;&#8205;&#128187;</p><p></p>
      <p>
          <a href="https://careerbytecode.substack.com/p/class30-mastering-cicd-with-jenkins-integrating-sonarqube-and-nexus-for-automated-builds-and-deployments">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Class 29 Training: Cloud DevOps Real-Time Projects Assignment & Effective Presentation Skills ]]></title><description><![CDATA[We took a huge step forward in transforming how our students approach real-time projects.]]></description><link>https://careerbytecode.substack.com/p/class29-training-cloud-devops-real-time-projects-assignment-effective-presentation-skills</link><guid isPermaLink="false">https://careerbytecode.substack.com/p/class29-training-cloud-devops-real-time-projects-assignment-effective-presentation-skills</guid><dc:creator><![CDATA[CareerByteCode]]></dc:creator><pubDate>Mon, 23 Jun 2025 06:36:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Mwny!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F543a6cce-f333-4ce1-a795-6ea4db3e37d3_1280x720.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Mwny!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F543a6cce-f333-4ce1-a795-6ea4db3e37d3_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Mwny!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F543a6cce-f333-4ce1-a795-6ea4db3e37d3_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!Mwny!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F543a6cce-f333-4ce1-a795-6ea4db3e37d3_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!Mwny!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F543a6cce-f333-4ce1-a795-6ea4db3e37d3_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!Mwny!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F543a6cce-f333-4ce1-a795-6ea4db3e37d3_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Mwny!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F543a6cce-f333-4ce1-a795-6ea4db3e37d3_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/543a6cce-f333-4ce1-a795-6ea4db3e37d3_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:720378,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://careerbytecode.substack.com/i/166575417?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F543a6cce-f333-4ce1-a795-6ea4db3e37d3_1280x720.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Mwny!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F543a6cce-f333-4ce1-a795-6ea4db3e37d3_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!Mwny!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F543a6cce-f333-4ce1-a795-6ea4db3e37d3_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!Mwny!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F543a6cce-f333-4ce1-a795-6ea4db3e37d3_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!Mwny!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F543a6cce-f333-4ce1-a795-6ea4db3e37d3_1280x720.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p></p><p></p><p>Today, in Class 29, we took a huge step forward in transforming how our students approach real-time projects. At <strong>CareerByteCode</strong>, we're not just interested in delivering courses &#8212; we're here to <em>shape successful careers</em> that stand out in a highly competitive market. &#128188;&#10024;</p><p>We understand each student's career needs and goals, and we&#8217;re committed to fine-tuning their path. That's why we don&#8217;t just teach concepts, but also focus on empowering our students with the skills to <em>present</em> and <em>sell</em> their work effectively.</p><h3>&#128205; <strong>What Makes CareerByteCode Different?</strong> &#128205;</h3><p>In today's class, we emphasized something critical for career growth &#8212; <strong>selling your skills</strong>. It's not just about knowing 1000 different tools, it's about how well you can showcase your expertise. &#128273;&#128295;</p><h3>&#127775; <strong>Key Takeaways from Today&#8217;s Session:</strong></h3><ol><li><p><strong>Real-Time Project Assignment</strong>:<br>We allocated 20+ real-time projects across <strong>AWS</strong>, <strong>Azure</strong>, <strong>Ansible</strong>, <strong>Terraform</strong>, <strong>DevOps</strong>, <strong>Docker</strong>, <strong>Kubernetes</strong>, and <strong>Git</strong>. Each student received 3 projects to work on, ensuring hands-on exposure to diverse tools and practices.</p></li><li><p><strong>Presentation Skills</strong>:<br>The main goal of today&#8217;s session was to help students prepare and present their projects <strong>confidently</strong>. It&#8217;s one thing to build a project, but it's another to present it effectively. We covered techniques to communicate technical concepts clearly and persuasively.</p></li><li><p><strong>Building Strong Foundations</strong>:<br>Before running fast, we ensure that our students have a <strong>strong foundation</strong>. We guide them to start with confidence and <em>clarity</em> before moving ahead with more complex challenges.</p></li></ol><h3>&#128293; <strong>How Are We Different?</strong> &#128293;</h3><p>At CareerByteCode, we believe in <strong>personalized learning</strong>. We don't believe in just delivering courses &#8212; we understand our students, their needs, and fine-tune their career goals. &#128161;</p><p><strong>The Power of Real-Time Projects</strong>:<br>By working on <strong>110 real-time projects</strong>, our students not only gain the technical expertise but also the confidence to apply their skills in real-world scenarios. &#128188;&#128640;</p><h3>&#128260; <strong>Next Steps for Students:</strong></h3><ul><li><p><strong>Prepare</strong>: Dive deep into your allocated projects.</p></li><li><p><strong>Present</strong>: Work on your presentation skills.</p></li><li><p><strong>Share</strong>: Showcase what you&#8217;ve learned confidently, and get valuable feedback.</p></li></ul><p>&#128172; <strong>Real Projects = Real Success</strong> &#128172;</p><p>By the end of this session, students will be better equipped to not only <em>build</em> their technical expertise but also <em>market</em> it effectively to potential employers.</p><div><hr></div><p>&#127919; <strong>Stay tuned for more sessions where we will cover even more advanced DevOps and Cloud topics!</strong> &#127775;</p><p>&#128293; <strong>Want to know how our personalized training helps you stand out? Get in touch with us today!</strong> &#128293;</p><h2>Class 1</h2><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;9a6c96e0-2552-49e4-82ea-2b82d6b608dc&quot;,&quot;duration&quot;:null}"></div><p></p><p></p>]]></content:encoded></item></channel></rss>