<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Emilio Ochieng</title>
    <description>The latest articles on DEV Community by Emilio Ochieng (@emilio_ochieng_632030149c).</description>
    <link>https://dev.to/emilio_ochieng_632030149c</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3952242%2F0b868e53-1a86-4fa0-aef0-3313df4f055c.jpeg</url>
      <title>DEV Community: Emilio Ochieng</title>
      <link>https://dev.to/emilio_ochieng_632030149c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emilio_ochieng_632030149c"/>
    <language>en</language>
    <item>
      <title>Object-Oriented Programming Explained</title>
      <dc:creator>Emilio Ochieng</dc:creator>
      <pubDate>Fri, 02 Oct 2026 19:25:25 +0000</pubDate>
      <link>https://dev.to/emilio_ochieng_632030149c/object-oriented-programming-explained-2250</link>
      <guid>https://dev.to/emilio_ochieng_632030149c/object-oriented-programming-explained-2250</guid>
      <description>&lt;p&gt;This article explains OOP through one running example, a simple bank account, in Python.&lt;/p&gt;

&lt;p&gt;What is OOP?&lt;/p&gt;

&lt;p&gt;OOP is a way of organizing code around objects, which bundle together:&lt;/p&gt;

&lt;p&gt;Data (called attributes), such as an account's owner and balance&lt;br&gt;
Behavior (called methods), such as deposit and withdraw&lt;/p&gt;

&lt;p&gt;The alternative is writing loose functions that pass data around. That works for small scripts, but as programs grow, it gets hard to see which function is allowed to change which data. OOP keeps related data and behavior in one place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Classes and objects&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A class is a blueprint. An object is something built from that blueprint.&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
class BankAccount:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, owner, balance=0):&lt;br&gt;
        self.owner = owner&lt;br&gt;
        self.balance = balance&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def deposit(self, amount):
    self.balance += amount

def withdraw(self, amount):
    if amount &amp;gt; self.balance:
        raise ValueError("Insufficient funds")
    self.balance -= amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;ann = BankAccount("Ann", 1000)&lt;br&gt;
ben = BankAccount("Ben")&lt;/p&gt;

&lt;p&gt;ann.deposit(500)&lt;br&gt;
print(ann.balance)  # 1500&lt;br&gt;
print(ben.balance)  # 0&lt;/p&gt;

&lt;p&gt;BankAccount is the class. ann and ben are two separate objects, each with their own balance. &lt;em&gt;init&lt;/em&gt; is the constructor that runs when you create an object, and self refers to the specific object being worked on.&lt;/p&gt;

&lt;p&gt;The four pillars of OOP&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Encapsulation&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Encapsulation means hiding an object's internal details and controlling access to them. Right now anyone can write ann.balance = 1,000,000, which defeats the purpose of having a withdraw rule.&lt;/p&gt;

&lt;p&gt;Python uses a naming convention: a leading underscore means "internal, please don't touch".&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
class BankAccount:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, owner, balance=0):&lt;br&gt;
        self.owner = owner&lt;br&gt;
        self._balance = balance&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@property
def balance(self):
    return self._balance

def deposit(self, amount):
    if amount &amp;lt;= 0:
        raise ValueError("Deposit must be positive")
    self._balance += amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now the balance can be read but not set directly. The only way to change it is through methods that enforce the rules. That is the main payoff of encapsulation: the object protects its own consistency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Abstraction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Abstraction means exposing a simple interface and hiding the complexity behind it. You press a key on your keyboard without knowing how the signal travels through the circuitry.&lt;/p&gt;

&lt;p&gt;In code, account.withdraw(200) is the interface. Whether it checks fraud rules, writes to a database or sends an SMS is not the caller's concern, and it can change later without breaking the code that calls it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Inheritance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inheritance lets a class reuse and extend another class. A savings account is a bank account with some extras:&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
class SavingsAccount(BankAccount):&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, owner, balance=0, rate=0.05):&lt;br&gt;
        super().&lt;strong&gt;init&lt;/strong&gt;(owner, balance)&lt;br&gt;
        self.rate = rate&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def add_interest(self):
    self.deposit(self._balance * self.rate)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;SavingsAccount gets deposit, withdraw and balance for free from BankAccount, and adds its own add_interest. This avoids copy-pasting code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Polymorphism&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Polymorphism means different objects can respond to the same method call in their own way.&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
class CurrentAccount(BankAccount):&lt;br&gt;
    def withdraw(self, amount):&lt;br&gt;
        # allows an overdraft of up to 500&lt;br&gt;
        if amount &amp;gt; self._balance + 500:&lt;br&gt;
            raise ValueError("Overdraft limit exceeded")&lt;br&gt;
        self._balance -= amount&lt;/p&gt;

&lt;p&gt;accounts = [BankAccount("Ann", 100), CurrentAccount("Ben", 100)]&lt;/p&gt;

&lt;p&gt;for acc in accounts:&lt;br&gt;
    acc.withdraw(300)  # each class applies its own rule&lt;/p&gt;

&lt;p&gt;The loop doesn't need to know which kind of account it has. It just calls withdraw, and each object does the right thing. This is what lets you add new account types later without rewriting the code that uses them.&lt;/p&gt;

&lt;p&gt;A note on "is-a" versus "has-a"&lt;/p&gt;

&lt;p&gt;Inheritance models an "is-a" relationship: a savings account is a bank account. Many beginners overuse it. When the relationship is "has-a", use composition, where one object holds another:&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
class Customer:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, name):&lt;br&gt;
        self.name = name&lt;br&gt;
        self.accounts = []  # a customer HAS accounts&lt;/p&gt;

&lt;p&gt;A common guideline is to prefer composition over inheritance. Deep inheritance chains become rigid and hard to change.&lt;/p&gt;

&lt;p&gt;When OOP is the wrong tool&lt;/p&gt;

&lt;p&gt;OOP is useful, but it isn't always the answer:&lt;/p&gt;

&lt;p&gt;Small scripts and data pipelines are often clearer as plain functions that transform data from one step to the next.&lt;br&gt;
Over-engineering is a real risk. If a class has one method and no state, it should probably just be a function.&lt;br&gt;
Some problems fit functional approaches better, and many modern codebases mix both styles.&lt;/p&gt;

&lt;p&gt;Use OOP when you have things with state and behavior that belong together. Don't use it just because it feels more "professional".&lt;/p&gt;

&lt;p&gt;Quick recap&lt;br&gt;
Concept One-line meaning&lt;br&gt;
Class / object  Blueprint / the thing built from it&lt;br&gt;
Encapsulation   Protect internal data behind methods&lt;br&gt;
Abstraction Show a simple interface, hide the complexity&lt;br&gt;
Inheritance Reuse and extend an existing class&lt;br&gt;
Polymorphism    Same method call, different behavior per class&lt;/p&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>SQL Functions</title>
      <dc:creator>Emilio Ochieng</dc:creator>
      <pubDate>Fri, 18 Sep 2026 09:31:19 +0000</pubDate>
      <link>https://dev.to/emilio_ochieng_632030149c/sql-functions-367k</link>
      <guid>https://dev.to/emilio_ochieng_632030149c/sql-functions-367k</guid>
      <description>&lt;h2&gt;
  
  
  What are SQL functions?
&lt;/h2&gt;

&lt;p&gt;A SQL function is a built-in operation that takes some input - a column, a value, or a set of rows - and returns a computed result. They fall into two broad categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Aggregate functions&lt;/strong&gt; - operate across multiple rows and collapse them into a single value: &lt;code&gt;COUNT&lt;/code&gt;, &lt;code&gt;SUM&lt;/code&gt;, &lt;code&gt;AVG&lt;/code&gt;, &lt;code&gt;MIN&lt;/code&gt;, &lt;code&gt;MAX&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalar functions&lt;/strong&gt; - operate on a single value at a time and return one result per row: string functions (&lt;code&gt;UPPER&lt;/code&gt;, &lt;code&gt;LOWER&lt;/code&gt;, &lt;code&gt;CONCAT&lt;/code&gt;, &lt;code&gt;LENGTH&lt;/code&gt;), numeric functions (&lt;code&gt;ROUND&lt;/code&gt;, &lt;code&gt;ABS&lt;/code&gt;), and date functions (&lt;code&gt;NOW()&lt;/code&gt;, &lt;code&gt;DATE_PART&lt;/code&gt;, &lt;code&gt;AGE()&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common functions
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;COUNT()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Aggregate&lt;/td&gt;
&lt;td&gt;Counts rows (or non-null values in a column)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SUM()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Aggregate&lt;/td&gt;
&lt;td&gt;Adds up numeric values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AVG()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Aggregate&lt;/td&gt;
&lt;td&gt;Calculates the mean&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;MIN()&lt;/code&gt; / &lt;code&gt;MAX()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Aggregate&lt;/td&gt;
&lt;td&gt;Smallest / largest value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;UPPER()&lt;/code&gt; / &lt;code&gt;LOWER()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;Changes text case&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CONCAT()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;Joins strings together&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ROUND()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Numeric&lt;/td&gt;
&lt;td&gt;Rounds a decimal to a given precision&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NOW()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Date&lt;/td&gt;
&lt;td&gt;Returns the current timestamp&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Examples - from the Sunrise Supermarket project
&lt;/h2&gt;

&lt;p&gt;Counting orders per customer - an aggregate function paired with &lt;code&gt;GROUP BY&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_orders&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding up total quantity sold per product:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_quantity&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scalar functions applied on top of the same schema — formatting a product name in uppercase for a report, and calculating price including a hypothetical 16% VAT, rounded to two decimal places:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="k"&gt;UPPER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;product_display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unit_price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;price_with_vat&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When to use them
&lt;/h2&gt;

&lt;p&gt;Aggregate functions are the right tool whenever the question is about a &lt;em&gt;group&lt;/em&gt; of rows rather than any single row - "how many," "what's the total," "what's the average." The moment &lt;code&gt;GROUP BY&lt;/code&gt; enters a query, there's almost always an aggregate function sitting next to it.&lt;/p&gt;

&lt;p&gt;Scalar functions come up constantly for formatting and light computation - cleaning up text for display, converting units, rounding currency values so they don't show absurd precision like &lt;code&gt;179.999999&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I understood from this
&lt;/h2&gt;

&lt;p&gt;The thing that clarified aggregate functions for me was realizing they only make sense in the context of grouping - &lt;code&gt;COUNT(order_id)&lt;/code&gt; on its own, with no &lt;code&gt;GROUP BY&lt;/code&gt;, just counts &lt;em&gt;all&lt;/em&gt; the rows in the result set as one number. It's the same function, but &lt;code&gt;GROUP BY customer_id&lt;/code&gt; is what turns it from "one total" into "one total per customer." Scalar functions, by contrast, never need that - they just transform each row independently, which is why you'll often see them mixed freely into a &lt;code&gt;SELECT&lt;/code&gt; list without touching the rest of the query's logic at all.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>Functions</title>
      <dc:creator>Emilio Ochieng</dc:creator>
      <pubDate>Fri, 18 Sep 2026 09:22:37 +0000</pubDate>
      <link>https://dev.to/emilio_ochieng_632030149c/functions-1g19</link>
      <guid>https://dev.to/emilio_ochieng_632030149c/functions-1g19</guid>
      <description>&lt;h2&gt;
  
  
  Defining and calling functions
&lt;/h2&gt;

&lt;p&gt;A function is a self-contained, reusable block of code designed to perform one specific task. Instead of repeating the same instructions throughout a program, you package them once, give them a name, and call that name whenever the task needs doing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello there!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;   &lt;span class="c1"&gt;# calling the function
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;def&lt;/code&gt; declares the function, followed by its name and parentheses. The indented lines beneath it are the function's &lt;strong&gt;body&lt;/strong&gt; - the code that actually runs when the function is called.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parameters and arguments
&lt;/h2&gt;

&lt;p&gt;A function can accept input through &lt;strong&gt;parameters&lt;/strong&gt; - placeholders defined in the function's signature - which get filled in with actual &lt;strong&gt;arguments&lt;/strong&gt; when the function is called:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;          &lt;span class="c1"&gt;# 'name' is the parameter
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Emilio&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="c1"&gt;# "Emilio" is the argument
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Functions can take multiple parameters, and can give them default values so an argument becomes optional:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;greeting&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;greeting&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Emilio&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                 &lt;span class="c1"&gt;# uses the default: "Hello, Emilio"
&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Emilio&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Welcome back&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# overrides it: "Welcome back, Emilio"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Return values
&lt;/h2&gt;

&lt;p&gt;A function can send a result back to whatever called it, using &lt;code&gt;return&lt;/code&gt;. This is different from &lt;code&gt;print()&lt;/code&gt;, which only displays something - &lt;code&gt;return&lt;/code&gt; actually hands the value back so it can be stored, passed along, or used in further calculations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# total now holds 300
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once a &lt;code&gt;return&lt;/code&gt; statement runs, the function stops immediately - any code after it in the function body never executes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope
&lt;/h2&gt;

&lt;p&gt;Scope determines where a variable can be seen and used. A variable created &lt;strong&gt;inside&lt;/strong&gt; a function (a &lt;strong&gt;local&lt;/strong&gt; variable) only exists within that function — it disappears once the function finishes running, and code outside the function can't access it. A variable created &lt;strong&gt;outside&lt;/strong&gt; any function (a &lt;strong&gt;global&lt;/strong&gt; variable) can be read from anywhere, including inside functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;m global&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show_message&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;local_note&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;m local&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;# works fine - global variables are visible inside functions
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;local_note&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;show_message&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;local_note&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;# this line would raise a NameError - local_note doesn't exist out here
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Practical examples
&lt;/h2&gt;

&lt;p&gt;A function that takes a list of prices and returns the total - reusable anywhere a total needs calculating, instead of rewriting the summing logic each time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;

&lt;span class="n"&gt;cart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;320&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;85&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculate_total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;   &lt;span class="c1"&gt;# 585
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I understood from this
&lt;/h2&gt;

&lt;p&gt;The distinction between &lt;code&gt;print()&lt;/code&gt; and &lt;code&gt;return&lt;/code&gt; was the one that mattered most in practice. Early on I'd write a function that "worked" because it printed the right answer to the screen - but then couldn't figure out why using that function's result in another calculation gave an error. &lt;code&gt;print()&lt;/code&gt; only shows a value; it doesn't hand it back to the program. &lt;code&gt;return&lt;/code&gt; is what actually makes a function's output usable elsewhere - &lt;code&gt;total = add(100, 200)&lt;/code&gt; only works because &lt;code&gt;add&lt;/code&gt; returns a value for &lt;code&gt;total&lt;/code&gt; to catch. Scope followed a similar lesson: a variable defined inside a function is genuinely gone once that function ends, which is exactly why &lt;code&gt;return&lt;/code&gt; exists - it's the sanctioned way to get a value out of that otherwise-sealed local scope.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>coding</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Python Data Structures</title>
      <dc:creator>Emilio Ochieng</dc:creator>
      <pubDate>Fri, 18 Sep 2026 09:11:57 +0000</pubDate>
      <link>https://dev.to/emilio_ochieng_632030149c/python-data-structures-1b57</link>
      <guid>https://dev.to/emilio_ochieng_632030149c/python-data-structures-1b57</guid>
      <description>&lt;p&gt;Python has four built-in structures for holding collections of data, and each one exists because it makes a different trade-off between order, mutability, and uniqueness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lists
&lt;/h2&gt;

&lt;p&gt;A list is an ordered, &lt;strong&gt;mutable&lt;/strong&gt; (changeable) collection, written with square brackets. Items can be added, removed, or changed after creation, and duplicates are allowed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;fruits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;apple&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;banana&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;apple&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mango&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orange&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pineapple&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# ['pineapple', 'banana', 'apple', 'mango', 'orange']
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tuples
&lt;/h2&gt;

&lt;p&gt;A tuple is an ordered, &lt;strong&gt;immutable&lt;/strong&gt; (unchangeable) collection, written with parentheses. Once created, its contents can't be modified - no adding, removing, or changing items.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;coordinates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;36.8219&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.2921&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# coordinates[0] = 40   # this would raise an error - tuples can't be modified
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Dictionaries
&lt;/h2&gt;

&lt;p&gt;A dictionary stores data as &lt;strong&gt;key-value pairs&lt;/strong&gt;, written with curly braces. Instead of accessing items by position (like a list), you access them by a unique key - which makes lookups fast and the data self-describing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Emilio ochieng&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;city&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nairobi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;loyalty_points&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;       &lt;span class="c1"&gt;# Emilio ochieng
&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;loyalty_points&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sets
&lt;/h2&gt;

&lt;p&gt;A set is an &lt;strong&gt;unordered&lt;/strong&gt; collection of &lt;strong&gt;unique&lt;/strong&gt; items - duplicates are automatically removed, and there's no guaranteed order to how items are stored.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;cities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nairobi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nakuru&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nairobi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mombasa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cities&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# {'Nairobi', 'Nakuru', 'Mombasa'} - the duplicate is gone
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sets are particularly useful for membership checks (&lt;code&gt;"Nairobi" in cities&lt;/code&gt;) and for operations like finding what two collections have in common:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;supported_cities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nairobi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nakuru&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mombasa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;customer_cities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nakuru&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Eldoret&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;supported_cities&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;customer_cities&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# {'Nakuru'} - intersection
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When to use each
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Structure&lt;/th&gt;
&lt;th&gt;Ordered?&lt;/th&gt;
&lt;th&gt;Mutable?&lt;/th&gt;
&lt;th&gt;Duplicates?&lt;/th&gt;
&lt;th&gt;Use it when...&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;List&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Allowed&lt;/td&gt;
&lt;td&gt;You need a sequence you'll modify — adding, removing, reordering items&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tuple&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Allowed&lt;/td&gt;
&lt;td&gt;The data shouldn't change — fixed coordinates, a date (year, month, day)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dictionary&lt;/td&gt;
&lt;td&gt;Insertion order (3.7+)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Keys must be unique&lt;/td&gt;
&lt;td&gt;You need to look things up by a meaningful label rather than position&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Not allowed&lt;/td&gt;
&lt;td&gt;You need uniqueness enforced, or fast membership checks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Practical examples
&lt;/h2&gt;

&lt;p&gt;Modeling something like a single row from the Sunrise Supermarket &lt;code&gt;products&lt;/code&gt; table as a dictionary - it maps naturally onto named fields the way a database row does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;product_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;product_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Maize Flour 2kg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Groceries&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unit_price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;180.00&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;product_name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; costs KES &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;unit_price&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using a list of those dictionaries to represent an entire table, and a set to quickly answer "what categories exist?":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;product_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Maize Flour 2kg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Groceries&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;product_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cooking Oil 1L&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Groceries&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;product_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bathing Soap&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Toiletries&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;categories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# {'Groceries', 'Toiletries'}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I understood from this
&lt;/h2&gt;

&lt;p&gt;Choosing between these stopped being confusing once I stopped thinking about syntax (brackets vs. braces vs. parentheses) and started thinking about the &lt;em&gt;rule&lt;/em&gt; each one enforces. A list says "order matters, and you're allowed to change your mind." A tuple says "order matters, but this is locked." A dictionary says "forget position - find things by name." A set says "I don't care about order, but I will not tolerate duplicates." Once the question became "which rule does my data actually need," the right structure usually picked itself - a database row, with its named fields, is obviously a dictionary; a fixed set of coordinates that should never change is obviously a tuple.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>python</category>
    </item>
    <item>
      <title>Operators &amp; Conditionals</title>
      <dc:creator>Emilio Ochieng</dc:creator>
      <pubDate>Fri, 18 Sep 2026 08:59:16 +0000</pubDate>
      <link>https://dev.to/emilio_ochieng_632030149c/operators-conditionals-506</link>
      <guid>https://dev.to/emilio_ochieng_632030149c/operators-conditionals-506</guid>
      <description>&lt;h2&gt;
  
  
  Arithmetic operators
&lt;/h2&gt;

&lt;p&gt;These perform basic math: &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;/&lt;/code&gt;, &lt;code&gt;%&lt;/code&gt; (modulus - the remainder after division), and &lt;code&gt;**&lt;/code&gt; (exponent).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;   &lt;span class="c1"&gt;# 650
&lt;/span&gt;&lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;         &lt;span class="c1"&gt;# 50
&lt;/span&gt;&lt;span class="n"&gt;rem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;           &lt;span class="c1"&gt;# 1  (remainder of 10 ÷ 3)
&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;           &lt;span class="c1"&gt;# 30.0
&lt;/span&gt;&lt;span class="n"&gt;power&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;        &lt;span class="c1"&gt;# 9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Comparison operators
&lt;/h2&gt;

&lt;p&gt;These compare two values and always evaluate to a boolean (&lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;): &lt;code&gt;==&lt;/code&gt; (equal to), &lt;code&gt;!=&lt;/code&gt; (not equal to), &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# True
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# True
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# False
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The most common beginner mistake here is confusing &lt;code&gt;=&lt;/code&gt; (assignment) with &lt;code&gt;==&lt;/code&gt; (comparison) - &lt;code&gt;age = 18&lt;/code&gt; sets the value; &lt;code&gt;age == 18&lt;/code&gt; checks it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Logical operators
&lt;/h2&gt;

&lt;p&gt;These combine multiple conditions: &lt;code&gt;and&lt;/code&gt; (both must be true), &lt;code&gt;or&lt;/code&gt; (at least one must be true), &lt;code&gt;not&lt;/code&gt; (flips a boolean).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="n"&gt;has_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;has_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You can enter&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conditionals: if, elif, else
&lt;/h2&gt;

&lt;p&gt;Conditionals let a program make decisions - running different code depending on whether a condition is true:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;72&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grade: A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;75&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grade: B&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grade: C&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grade: F&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python checks each condition top to bottom and runs the first block whose condition is &lt;code&gt;True&lt;/code&gt;, skipping the rest - &lt;code&gt;elif&lt;/code&gt; (else-if) lets you chain as many conditions as needed, and &lt;code&gt;else&lt;/code&gt; catches anything that didn't match.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical examples
&lt;/h2&gt;

&lt;p&gt;Combining comparison and logical operators inside a conditional - checking eligibility against two conditions at once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;
&lt;span class="n"&gt;id_present&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;id_present&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You can drive&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Not eligible yet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A slightly more layered example, using &lt;code&gt;elif&lt;/code&gt; to categorize a value into ranges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;temperature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;It&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s hot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;It&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s warm&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;It&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s cold&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I understood from this
&lt;/h2&gt;

&lt;p&gt;The distinction that mattered most here was between comparison operators (which produce a boolean answer to a single question) and logical operators (which combine several of those boolean answers into one final decision). A condition like &lt;code&gt;age &amp;gt;= 18 and has_id&lt;/code&gt; only reads cleanly once you see it as two separate &lt;code&gt;True&lt;/code&gt;/&lt;code&gt;False&lt;/code&gt; questions being joined by &lt;code&gt;and&lt;/code&gt; - Python evaluates each side independently first, then combines them. Once that clicked, writing more complex conditions stopped being about memorizing operator symbols and became about breaking a real-world rule ("you can drive if you're old enough &lt;em&gt;and&lt;/em&gt; you have ID") into the exact boolean pieces Python needs.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Data definition language and data manipulation language</title>
      <dc:creator>Emilio Ochieng</dc:creator>
      <pubDate>Thu, 17 Sep 2026 07:52:11 +0000</pubDate>
      <link>https://dev.to/emilio_ochieng_632030149c/data-definition-language-and-data-manipulation-language-14b6</link>
      <guid>https://dev.to/emilio_ochieng_632030149c/data-definition-language-and-data-manipulation-language-14b6</guid>
      <description>&lt;h2&gt;
  
  
  What is DDL?
&lt;/h2&gt;

&lt;p&gt;DDL- &lt;strong&gt;Data Definition Language&lt;/strong&gt; - is the part of SQL that defines and modifies the &lt;em&gt;structure&lt;/em&gt; of a database: the tables, their columns, data types, and constraints. It doesn't touch the data living inside those tables; it shapes the containers the data lives in.&lt;/p&gt;

&lt;p&gt;The core DDL commands are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CREATE&lt;/code&gt; - build a new table, schema, or other database object&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ALTER&lt;/code&gt; - change an existing table's structure (add/remove/modify columns)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DROP&lt;/code&gt; - delete a table or object entirely, structure and data both&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TRUNCATE&lt;/code&gt; - empty a table of all its rows while keeping the structure intact&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is DML?
&lt;/h2&gt;

&lt;p&gt;DML - &lt;strong&gt;Data Manipulation Language&lt;/strong&gt; - is what you use once the structure already exists. It reads and changes the &lt;em&gt;data&lt;/em&gt; inside the tables DDL created:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;INSERT&lt;/code&gt; - add new rows&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UPDATE&lt;/code&gt; - modify existing rows&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DELETE&lt;/code&gt; - remove rows&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SELECT&lt;/code&gt; - read rows (some references classify this separately as DQL, Data Query Language, since it only reads and never changes anything - but it's commonly grouped with DML in practice)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The distinction, in plain terms
&lt;/h2&gt;

&lt;p&gt;DDL answers "what does the data look like?" DML answers "what does the data say, right now?" You use DDL once (or occasionally, when the schema evolves) and DML constantly, every time a row needs to be added, changed, or removed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical examples - from the Sunrise Supermarket project
&lt;/h2&gt;

&lt;p&gt;When I built the Sunrise Supermarket database, the very first statements were pure DDL - defining the shape before anything could be stored in it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;full_name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;loyalty_points&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If I later decided customers needed a signup date, that's DDL too — I'm changing the shape of the table, not its contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="n"&gt;signup_date&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;CURRENT_DATE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the structure existed, everything after that was DML. Populating the table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;full_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Emilio ochieng'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'emilioochieng44@gmail.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'0705216347'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Nairobi'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Changing a row already there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Delivered'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And removing one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I understood from this
&lt;/h2&gt;

&lt;p&gt;The distinction sounds academic until you actually build something - then it becomes obvious that DDL mistakes are expensive (drop the wrong table, and the data's gone with it) while DML mistakes are usually recoverable (a bad &lt;code&gt;UPDATE&lt;/code&gt; can be corrected with another &lt;code&gt;UPDATE&lt;/code&gt;). That's part of why I lean on constraints - &lt;code&gt;NOT NULL&lt;/code&gt;, &lt;code&gt;UNIQUE&lt;/code&gt;, &lt;code&gt;CHECK&lt;/code&gt; - at the DDL stage: they're a one-time investment that quietly prevents an entire category of bad DML later. A &lt;code&gt;CHECK (unit_price &amp;gt; 0)&lt;/code&gt; on the &lt;code&gt;products&lt;/code&gt; table means no &lt;code&gt;INSERT&lt;/code&gt; or &lt;code&gt;UPDATE&lt;/code&gt; can ever sneak a negative price in, no matter who's writing the query.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>Loops</title>
      <dc:creator>Emilio Ochieng</dc:creator>
      <pubDate>Thu, 17 Sep 2026 07:36:40 +0000</pubDate>
      <link>https://dev.to/emilio_ochieng_632030149c/loops-5841</link>
      <guid>https://dev.to/emilio_ochieng_632030149c/loops-5841</guid>
      <description>&lt;h2&gt;
  
  
  Why loops matter
&lt;/h2&gt;

&lt;p&gt;A loop is a control flow structure that executes a block of code repeatedly as long as a condition holds. They matter for three reasons: they &lt;strong&gt;reduce redundancy&lt;/strong&gt; (no manually retyping the same statement), they &lt;strong&gt;save time and space&lt;/strong&gt; (keeping code short and maintainable), and they &lt;strong&gt;handle dynamic data&lt;/strong&gt; (processing a list or user input of any size without rewriting the code for each possible length).&lt;/p&gt;

&lt;h2&gt;
  
  
  for loops
&lt;/h2&gt;

&lt;p&gt;Use a &lt;code&gt;for&lt;/code&gt; loop when you know exactly what you're iterating over - a list, a range of numbers, the characters in a string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sugar&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;salt&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;flour&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;soap&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;oil&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# output
# sugar
# salt
# flour
# soap
# oil
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;for&lt;/code&gt; loops pair naturally with &lt;code&gt;range()&lt;/code&gt; when you need to repeat something a fixed number of times rather than iterate over existing items:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Attempt number&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  while loops
&lt;/h2&gt;

&lt;p&gt;Use a &lt;code&gt;while&lt;/code&gt; loop when the number of repetitions isn't known in advance and depends on a condition staying true:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The loop keeps running as long as &lt;code&gt;count &amp;lt; 5&lt;/code&gt; evaluates to &lt;code&gt;True&lt;/code&gt;. Forgetting to update &lt;code&gt;count&lt;/code&gt; inside the loop is the classic mistake here - it creates an infinite loop, since the condition never becomes false.&lt;/p&gt;

&lt;h2&gt;
  
  
  break and continue
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;break&lt;/code&gt;&lt;/strong&gt; exits the loop immediately, skipping any remaining iterations entirely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;continue&lt;/code&gt;&lt;/strong&gt; skips just the current iteration and moves on to the next one, without exiting the loop.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;          &lt;span class="c1"&gt;# stop the loop entirely once we hit 5
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# prints 0, 1, 2, 3, 4
&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;        &lt;span class="c1"&gt;# skip even numbers, keep looping
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# prints 1, 3, 5, 7, 9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  enumerate()
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;enumerate()&lt;/code&gt; gives you both the index and the value while looping over something - useful whenever you need to know &lt;em&gt;where&lt;/em&gt; an item is, not just what it is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sugar&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;salt&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;flour&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# output
# 0 -&amp;gt; sugar
# 1 -&amp;gt; salt
# 2 -&amp;gt; flour
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without &lt;code&gt;enumerate()&lt;/code&gt;, getting the index would mean manually tracking a separate counter variable and incrementing it yourself each pass through the loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical examples
&lt;/h2&gt;

&lt;p&gt;Combining several of these — looping through a list, using &lt;code&gt;enumerate()&lt;/code&gt; for numbering, and &lt;code&gt;continue&lt;/code&gt; to skip an item that doesn't meet a condition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;prices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;320&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;85&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;   &lt;span class="c1"&gt;# skip invalid entries
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Item &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: KES &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I understood from this
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;break&lt;/code&gt; and &lt;code&gt;continue&lt;/code&gt; felt interchangeable at first glance, but they solve different problems - &lt;code&gt;break&lt;/code&gt; is "I'm done here entirely," &lt;code&gt;continue&lt;/code&gt; is "not this one, but keep going." Mixing them up either cuts a loop short when it should have kept processing the rest of the list, or keeps a loop running past a point where it should have stopped. &lt;code&gt;enumerate()&lt;/code&gt; was the other thing that changed how I write loops day to day - before I understood it, I was manually creating and incrementing a counter variable alongside every &lt;code&gt;for&lt;/code&gt; loop that needed one, which is exactly the kind of repetitive bookkeeping loops are supposed to eliminate in the first place.&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Subqueries &amp; CTEs</title>
      <dc:creator>Emilio Ochieng</dc:creator>
      <pubDate>Mon, 07 Sep 2026 15:11:35 +0000</pubDate>
      <link>https://dev.to/emilio_ochieng_632030149c/subqueries-ctes-3jc7</link>
      <guid>https://dev.to/emilio_ochieng_632030149c/subqueries-ctes-3jc7</guid>
      <description>&lt;h2&gt;
  
  
  What are subqueries?
&lt;/h2&gt;

&lt;p&gt;A subquery is a query nested inside another query - it runs first, and its result is used by the outer query, whether that's as a filter condition, a computed value, or a virtual table to select from. Subqueries can appear almost anywhere: inside a &lt;code&gt;WHERE&lt;/code&gt; clause, a &lt;code&gt;SELECT&lt;/code&gt; list, or a &lt;code&gt;FROM&lt;/code&gt; clause.&lt;/p&gt;

&lt;p&gt;There are a few flavors worth knowing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scalar subquery&lt;/strong&gt; - returns a single value, usable anywhere a single value is expected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Row/column subquery&lt;/strong&gt; - returns a set of values, often used with &lt;code&gt;IN&lt;/code&gt; or &lt;code&gt;ANY&lt;/code&gt;/&lt;code&gt;ALL&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Correlated subquery&lt;/strong&gt; - references a column from the outer query, so it re-runs once per row of the outer query rather than just once overall.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What are CTEs?
&lt;/h2&gt;

&lt;p&gt;A CTE (&lt;strong&gt;Common Table Expression&lt;/strong&gt;) is a named, temporary result set defined with a &lt;code&gt;WITH&lt;/code&gt; clause at the start of a query, which you can then reference like a regular table for the rest of that query. It exists only for the duration of that one query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;high_value_orders&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;high_value_orders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Differences between them
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Readability&lt;/strong&gt; - a CTE gives a name to an intermediate result and reads top-to-bottom like a sequence of steps; a deeply nested subquery reads inside-out, which gets hard to follow fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reuse&lt;/strong&gt; - a CTE can be referenced multiple times later in the same query; a subquery has to be rewritten (or the query restructured) if you need that same intermediate result twice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recursion&lt;/strong&gt; - CTEs support &lt;code&gt;WITH RECURSIVE&lt;/code&gt;, which lets a query reference itself - useful for hierarchical data like an org chart or a category tree. Plain subqueries can't do this.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt; - in PostgreSQL, this used to be a bigger differentiator (CTEs were historically an "optimization fence"), but modern Postgres treats simple CTEs and subqueries similarly in most cases. The real reason to reach for one over the other is usually clarity, not speed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Practical examples and use cases
&lt;/h2&gt;

&lt;p&gt;Using the Sunrise Supermarket schema as the example: finding customers whose orders include at least one item with a quantity above 3 - first as a subquery:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;full_name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same logic as a CTE - flatter, and easier to read as a sequence of "first this, then this":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;bulk_items&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;bulk_orders&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;bulk_items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;full_name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;bulk_orders&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A correlated subquery example - products priced above the average price &lt;em&gt;within their own category&lt;/em&gt;, not the overall average:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;product_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;unit_price&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;unit_price&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unit_price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I understood from this
&lt;/h2&gt;

&lt;p&gt;The nested-subquery version and the CTE version return the exact same result - that's the part that took a moment to click. The choice between them isn't about correctness, it's about who has to read the query six months from now. Once a query needs two or three logical steps chained together, I reach for a CTE almost automatically now, because naming each intermediate step (&lt;code&gt;bulk_items&lt;/code&gt;, then &lt;code&gt;bulk_orders&lt;/code&gt;) makes the query's &lt;em&gt;intent&lt;/em&gt; visible, not just its mechanics.&lt;/p&gt;

</description>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>I Built a Supermarket Database in PostgreSQL - Here's What INNER JOIN vs LEFT JOIN Actually Taught Me</title>
      <dc:creator>Emilio Ochieng</dc:creator>
      <pubDate>Sun, 06 Sep 2026 19:43:54 +0000</pubDate>
      <link>https://dev.to/emilio_ochieng_632030149c/i-built-a-supermarket-database-in-postgresql-heres-what-inner-join-vs-left-join-actually-taught-545d</link>
      <guid>https://dev.to/emilio_ochieng_632030149c/i-built-a-supermarket-database-in-postgresql-heres-what-inner-join-vs-left-join-actually-taught-545d</guid>
      <description>&lt;p&gt;Most SQL tutorials hand you a dataset that's already loaded and ask you to query it. That skips the part that actually teaches you something: designing the schema, living with your own constraints, and finding out the hard way when &lt;code&gt;INNER JOIN&lt;/code&gt; and &lt;code&gt;LEFT JOIN&lt;/code&gt; give you &lt;em&gt;different&lt;/em&gt; answers to the same-looking question.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Sunrise Supermarket&lt;/strong&gt; - a small PostgreSQL project modeling customers, products, orders, and order items - to work through that whole arc end to end.&lt;/p&gt;

&lt;h2&gt;
  
  
  The schema
&lt;/h2&gt;

&lt;p&gt;Four tables, in their own schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;SCHEMA&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="n"&gt;Sunrise_Supermarket&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;Sunrise_Supermarket&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;full_name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;loyalty_points&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;product_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;product_name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;unit_price&lt;/span&gt; &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unit_price&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;stock_quantity&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two small things doing real work here: &lt;code&gt;UNIQUE&lt;/code&gt; on email/phone stops duplicate customers, and &lt;code&gt;CHECK (unit_price &amp;gt; 0)&lt;/code&gt; means the database itself refuses a free or negative price - no application code required to catch that.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real design decision: orders vs order_items
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;order_date&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="s1"&gt;'Pending'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;fk_customer&lt;/span&gt; &lt;span class="k"&gt;FOREIGN&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;order_item_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;product_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;CHECK&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;fk_order&lt;/span&gt; &lt;span class="k"&gt;FOREIGN&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;CASCADE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="n"&gt;fk_product&lt;/span&gt; &lt;span class="k"&gt;FOREIGN&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An order by itself can't say &lt;em&gt;what&lt;/em&gt; was bought - that's what &lt;code&gt;order_items&lt;/code&gt; is for, pairing each order with a product and quantity so one order can hold multiple products.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ON DELETE CASCADE&lt;/code&gt; earns its keep almost immediately. After seeding a cancelled order, I just delete it outright:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No manual cleanup of &lt;code&gt;order_items&lt;/code&gt; needed - the cascade handles it.&lt;/p&gt;

&lt;h2&gt;
  
  
  INNER JOIN vs LEFT JOIN, side by side
&lt;/h2&gt;

&lt;p&gt;This is the part that actually clicked for me. First, an inner join between customers and orders:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;full_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This only returns customers who &lt;strong&gt;have&lt;/strong&gt; placed an order. Zero orders = you don't show up in this result at all.&lt;/p&gt;

&lt;p&gt;Now compare that to a left join checking order completeness:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt;
&lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps &lt;strong&gt;every&lt;/strong&gt; order, even one with no matching line items - filling in &lt;code&gt;NULL&lt;/code&gt; where nothing exists. Same join shape, opposite intent. Pick the wrong one and you'll either silently drop rows you needed, or silently include rows you didn't expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pushing it to four tables
&lt;/h2&gt;

&lt;p&gt;Once that clicked, joining across the whole schema wasn't a big leap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;full_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And aggregating across that same join to get total quantity sold per product:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_quantity&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What I'd tell someone doing this next
&lt;/h2&gt;

&lt;p&gt;Don't skip the insert/update/delete step. It's tempting to seed your tables once and go straight to writing &lt;code&gt;SELECT&lt;/code&gt; queries, but running real &lt;code&gt;UPDATE&lt;/code&gt;/&lt;code&gt;DELETE&lt;/code&gt; statements against your own constraints (and watching &lt;code&gt;ON DELETE CASCADE&lt;/code&gt; actually fire) is what proves your schema holds up - not just that it compiles.&lt;/p&gt;

&lt;p&gt;And when you hit your first join, write the &lt;code&gt;INNER&lt;/code&gt; and &lt;code&gt;LEFT&lt;/code&gt; versions of the &lt;em&gt;same&lt;/em&gt; query side by side before moving on. Seeing the row count actually differ is worth more than any explanation of the difference.&lt;/p&gt;

&lt;p&gt;Repo's on &lt;a href="mailto:git@github.com"&gt;git@github.com&lt;/a&gt;:emilioochieng/sql-database-projects.git if you want to see the full thing, including the aggregation queries and the rest of the filtering (&lt;code&gt;BETWEEN&lt;/code&gt;, &lt;code&gt;IN&lt;/code&gt;, &lt;code&gt;LIKE&lt;/code&gt;) .&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Building a CV Builder With Live Preview and Zero-Backend Persistence</title>
      <dc:creator>Emilio Ochieng</dc:creator>
      <pubDate>Fri, 04 Sep 2026 16:00:46 +0000</pubDate>
      <link>https://dev.to/emilio_ochieng_632030149c/building-a-cv-builder-with-live-preview-and-zero-backend-persistence-1kao</link>
      <guid>https://dev.to/emilio_ochieng_632030149c/building-a-cv-builder-with-live-preview-and-zero-backend-persistence-1kao</guid>
      <description>&lt;p&gt;Most resume builders make you sign up before you've even decided if the tool is any good. I wanted the opposite: open a page, start typing, and watch a CV take shape in real time — no account, no paywall.&lt;/p&gt;

&lt;p&gt;That became &lt;strong&gt;CV Builder&lt;/strong&gt; — and it's gone through two clear phases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 1: A dumb-simple live preview
&lt;/h2&gt;

&lt;p&gt;The whole app is built around one function. Every keystroke — name, summary, a bullet point — fires the same render call, which rebuilds the preview from scratch based on whatever's in the form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;renderCV&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;f-name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your Name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// ...read every field...&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cv-page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;div class="cv-header"&amp;gt;
      &amp;lt;div class="cv-name"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;esc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/div&amp;gt;
      ...
    &amp;lt;/div&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No diffing, no state library — just "read the form, redraw the page." It sounds too simple, but that's exactly what makes it feel instant.&lt;/p&gt;

&lt;p&gt;Two other decisions mattered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repeatable sections&lt;/strong&gt; — Experience and Education are dynamically generated blocks you can add/remove, each wired to the same render call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One clean template&lt;/strong&gt; — no tables, no icons, no columns. Just a layout an ATS parser and a human recruiter can both read.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PDF export skips a PDF library entirely — the "Download" button just calls &lt;code&gt;window.print()&lt;/code&gt;, with print-only CSS that hides the form and leaves only the CV page. Zero dependencies, and the output always matches the screen exactly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 2: The obvious problem
&lt;/h2&gt;

&lt;p&gt;Refresh the page, and everything's gone. For a tool you might spend twenty minutes tuning, that's a real cost — and it meant you could only ever work on one CV, in one sitting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding persistence without standing up a backend
&lt;/h2&gt;

&lt;p&gt;Instead of spinning up a server + database + auth, I used a built-in per-user key-value storage layer available directly in the browser context this app runs in. From the app's perspective, it behaves like a small backend: data survives a refresh, survives closing the tab, scoped privately per user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;performSave&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;collectFormData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cv-builder:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;currentId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// update an index of {id, name, updatedAt} so saved CVs are listable&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this unlocked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auto-save&lt;/strong&gt; — once a CV's been saved once, edits save in the background on a debounce, with a status dot + timestamp confirming it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple saved CVs&lt;/strong&gt; — a dropdown lists everything you've saved, most recent first, so you can keep a different version tailored per role.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean delete&lt;/strong&gt; — removes both the stored data and its index entry, with a confirm step.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The honest limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It's personal storage, not multi-tenant — no login system separating one person's data from another's.&lt;/li&gt;
&lt;li&gt;It's tied to the environment it runs in — porting this to a fully independent, self-hosted site would mean swapping this for a real database.&lt;/li&gt;
&lt;li&gt;No version history — saving overwrites the previous draft.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these are hard walls, just the next milestones — real auth + Postgres + a small REST API is the natural v3 if this ever needs to serve more than one person's desk.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;Solve the problem in front of you with the smallest tool that does it honestly. A live-preview editor didn't need a framework. A save feature didn't need a server yet. Build the version that's true to what you actually need right now.&lt;/p&gt;

&lt;p&gt;I f interested you can have  a look and give a feedback on what's need to added &lt;a href="mailto:git@github.com"&gt;git@github.com&lt;/a&gt;:emilioochieng/CV_BUILDER.git&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>showdev</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>Why Python? An Introduction for New Programmers</title>
      <dc:creator>Emilio Ochieng</dc:creator>
      <pubDate>Thu, 03 Sep 2026 12:28:48 +0000</pubDate>
      <link>https://dev.to/emilio_ochieng_632030149c/why-python-an-introduction-for-new-programmers-52n6</link>
      <guid>https://dev.to/emilio_ochieng_632030149c/why-python-an-introduction-for-new-programmers-52n6</guid>
      <description>&lt;p&gt;Python is a language people learn to code in - and for good reason. What starts as a simple &lt;code&gt;print("Hello World")&lt;/code&gt; can grow into a skill used across nearly every industry, from e-commerce and logistics to firmware design and machine learning. This article walks through what makes Python approachable for beginners, and introduces the core building blocks you'll use in almost every Python program you write.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes Python Easy to Learn?
&lt;/h2&gt;

&lt;p&gt;A few things set Python apart as a beginner-friendly language:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simple, readable syntax.&lt;/strong&gt; Python code reads almost like plain English, which makes it easier to understand what a program is doing without memorizing a lot of symbols and rules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A huge ecosystem of libraries.&lt;/strong&gt; Whether you need to do arithmetic, deploy a machine learning model, or build a web application, there's very likely already a Python library for it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A large, active community.&lt;/strong&gt; Thousands of developers build and maintain these libraries, which means help, documentation, and examples are never far away.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Your First Line of Python
&lt;/h2&gt;

&lt;p&gt;The most fundamental piece of code most programmers write first is the &lt;code&gt;print()&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello World&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;print()&lt;/code&gt; function sends data to the standard output device - usually your terminal or console - so you can see the result of your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Variables: Storing Data
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;variable&lt;/strong&gt; is a named storage location in your computer's memory that temporarily holds data while a program runs. Every variable has three key properties:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The name (identifier)&lt;/strong&gt; - the label you use to refer to the data in your code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The value&lt;/strong&gt; - the actual data stored inside it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The data type&lt;/strong&gt; - the category of data being stored.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Python has four basic data types you'll encounter constantly:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Integer (&lt;code&gt;int&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;A whole number&lt;/td&gt;
&lt;td&gt;&lt;code&gt;age = 20&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Float / Double&lt;/td&gt;
&lt;td&gt;A decimal number&lt;/td&gt;
&lt;td&gt;&lt;code&gt;height = 1.93&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;String (&lt;code&gt;str&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Text&lt;/td&gt;
&lt;td&gt;&lt;code&gt;greeting = "Hello World"&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boolean (&lt;code&gt;bool&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;under 18 = false&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In each of these examples, the equal sign (&lt;code&gt;=&lt;/code&gt;) is the &lt;strong&gt;assignment operator&lt;/strong&gt; - it takes the value on the right and stores it in the variable name on the left.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operators: Doing Something With Data
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;operator&lt;/strong&gt; is a symbol or keyword that tells the computer to perform a mathematical, relational, or logical operation on data. Python has four common categories:&lt;/p&gt;

&lt;h3&gt;
  
  
  Arithmetic Operators
&lt;/h3&gt;

&lt;p&gt;Used for basic math: &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;/&lt;/code&gt;, &lt;code&gt;%&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;   &lt;span class="c1"&gt;# 600
&lt;/span&gt;&lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;         &lt;span class="c1"&gt;# 100
&lt;/span&gt;&lt;span class="n"&gt;rem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;           &lt;span class="c1"&gt;# 1
&lt;/span&gt;&lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;           &lt;span class="c1"&gt;# 100
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Assignment Operators
&lt;/h3&gt;

&lt;p&gt;Used to assign or update the value stored in a variable: &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;+=&lt;/code&gt;, &lt;code&gt;-=&lt;/code&gt;, &lt;code&gt;*=&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;   &lt;span class="c1"&gt;# equivalent to: score = score + count
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Comparison / Relational Operators
&lt;/h3&gt;

&lt;p&gt;Used to compare conditions: &lt;code&gt;and&lt;/code&gt;, &lt;code&gt;or&lt;/code&gt;, &lt;code&gt;not&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;id_present&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You can vote&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Loops: Repeating Actions Efficiently
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;loop&lt;/strong&gt; is a control flow structure that executes a block of code repeatedly as long as a condition is met. Loops matter because they:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduce redundancy&lt;/strong&gt; - you don't have to manually repeat the same statement over and over.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Save time and space&lt;/strong&gt; - they keep your codebase short, clean, and efficient.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle dynamic data&lt;/strong&gt; - they let you process lists or user input of any size without rewriting your code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;for&lt;/code&gt; Loop
&lt;/h3&gt;

&lt;p&gt;Use a &lt;code&gt;for&lt;/code&gt; loop when you know exactly how many times - or over exactly what items - you need to repeat an action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Mercedes&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;BMW&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Subaru&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Mazda&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Tesla&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# output
# Mercedes 
# BMW
# Subaru
# Mazda
# Tesla
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The &lt;code&gt;while&lt;/code&gt; Loop
&lt;/h3&gt;

&lt;p&gt;Use a &lt;code&gt;while&lt;/code&gt; loop when the number of repetitions is unknown and depends on a condition remaining true:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Functions: Packaging Reusable Logic
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;function&lt;/strong&gt; is a self-contained, reusable block of code designed to perform one specific task. Instead of repeating the same instructions throughout your program, you package them inside a function, give it a meaningful name, and call it whenever you need it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;              &lt;span class="c1"&gt;# declaration &amp;amp; parameters
&lt;/span&gt;    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;          &lt;span class="c1"&gt;# processing (body)
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;            &lt;span class="c1"&gt;# return value
&lt;/span&gt;
&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;# calling the function -&amp;gt; 150
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Breaking that down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name &amp;amp; parameters (inputs)&lt;/strong&gt; - &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are placeholders for the data you pass into the function.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The body&lt;/strong&gt; - the indented lines below the function name that carry out the actual logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The return value&lt;/strong&gt; - the &lt;code&gt;return&lt;/code&gt; statement sends the final result back to the main program and ends the function.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The function call&lt;/strong&gt; - writing the function's name followed by parentheses, like &lt;code&gt;sum(100, 200)&lt;/code&gt;, tells Python to run that block of code and hand back the result.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Every program starts as an idea. Before you write a single line of code, you can sketch that idea in pseudocode: a plain-language outline of what your program should do, step by step. The real work is turning that outline into code the computer can run, and this is where Python shines.&lt;/p&gt;

&lt;p&gt;Python reads almost like the outline you started with. You need fewer lines and less time to go from "here's what I want to build" to "it works," and you spend your energy solving the problem instead of fighting the syntax. That's what makes it such a great first language.&lt;/p&gt;

&lt;p&gt;So don't wait until you feel ready. Pick a small idea, write it out in plain steps, and translate it into Python. It won't be perfect, and that's fine. Every developer you admire started with a messy first script.&lt;/p&gt;

&lt;p&gt;Now it's your turn: what's the first thing you want to build with Python? A calculator, a to-do list, a simple game? Share your idea in the comments. You might inspire another beginner to start too, and I'd love to hear what you come up with.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>software</category>
      <category>coding</category>
    </item>
    <item>
      <title>Introduction to SQL: Understanding Databases, Data Types, Constraints, and Core SQL Concepts</title>
      <dc:creator>Emilio Ochieng</dc:creator>
      <pubDate>Mon, 20 Jul 2026 16:44:03 +0000</pubDate>
      <link>https://dev.to/emilio_ochieng_632030149c/introduction-to-sql-understanding-databases-data-types-constraints-and-core-sql-concepts-3eoh</link>
      <guid>https://dev.to/emilio_ochieng_632030149c/introduction-to-sql-understanding-databases-data-types-constraints-and-core-sql-concepts-3eoh</guid>
      <description>&lt;p&gt;SQL (Structured Query Language) is one of the most fundamental skills for anyone interested in Data Analytics, Data Engineering, Software Development, or Database Administration. Whether you're building a web application or analyzing business data, SQL enables you to communicate with relational databases efficiently.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is Data?
&lt;/h4&gt;

&lt;p&gt;Data refers to raw, unorganized facts and figures. It can exist in many forms, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Numbers&lt;/li&gt;
&lt;li&gt;Text&lt;/li&gt;
&lt;li&gt;Images&lt;/li&gt;
&lt;li&gt;Audio&lt;/li&gt;
&lt;li&gt;Videos&lt;/li&gt;
&lt;li&gt;Dates and times&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On its own, data has little meaning until it is organized and processed.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is a Database?
&lt;/h4&gt;

&lt;p&gt;A database is an organized collection of data that is structured for easy access, management, and updating.&lt;/p&gt;

&lt;p&gt;Instead of storing information in multiple spreadsheets, databases keep related information together, making it easier to search, retrieve, and maintain.&lt;/p&gt;

&lt;p&gt;For example, a school database may contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Students&lt;/li&gt;
&lt;li&gt;Teachers&lt;/li&gt;
&lt;li&gt;Subjects&lt;/li&gt;
&lt;li&gt;Exam Results&lt;/li&gt;
&lt;li&gt;Understanding Database Architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  A database system is organized into different layers.
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;1. Server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The server is the top-most level.&lt;/p&gt;

&lt;p&gt;It is the actual software process (such as PostgreSQL or MySQL) running on a computer.&lt;/p&gt;

&lt;p&gt;Think of the server as the entire building.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inside a server are one or more databases.&lt;/p&gt;

&lt;p&gt;A database acts like a separate floor within the building, storing data for a specific application or organization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Schema&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A schema organizes database objects inside a database.&lt;/p&gt;

&lt;p&gt;Think of a schema as rooms on a floor, helping separate tables based on their purpose.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Server&lt;br&gt;
   │&lt;br&gt;
   ├── Greenwood Academy Database&lt;br&gt;
   │       ├── Students Schema&lt;br&gt;
   │       ├── Finance Schema&lt;br&gt;
   │       └── Library Schema&lt;/p&gt;

&lt;h4&gt;
  
  
  What is a DBMS?
&lt;/h4&gt;

&lt;p&gt;A Database Management System (DBMS) is software that enables users to create, manage, update, and interact with databases.&lt;/p&gt;

&lt;p&gt;Popular DBMSs include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;Oracle Database&lt;/li&gt;
&lt;li&gt;Microsoft SQL Server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A DBMS provides the tools needed to store, organize, and retrieve information efficiently.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is SQL?
&lt;/h4&gt;

&lt;p&gt;SQL (Structured Query Language) is the standard language used to communicate with relational databases.&lt;/p&gt;

&lt;p&gt;Think of SQL as the language you use to "talk" to your database.&lt;/p&gt;

&lt;p&gt;Using SQL, you can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create databases&lt;/li&gt;
&lt;li&gt;Create tables&lt;/li&gt;
&lt;li&gt;Insert data&lt;/li&gt;
&lt;li&gt;Update records&lt;/li&gt;
&lt;li&gt;Delete records&lt;/li&gt;
&lt;li&gt;Retrieve information&lt;/li&gt;
&lt;li&gt;Manage users and permissions&lt;/li&gt;
&lt;li&gt;Types of SQL Commands&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;SQL is divided into several categories depending on the task being performed.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;1. DDL (Data Definition Language)&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
DDL focuses on creating and modifying database structures.&lt;/p&gt;

&lt;p&gt;Common commands include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CREATE&lt;/li&gt;
&lt;li&gt;ALTER&lt;/li&gt;
&lt;li&gt;DROP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;CREATE TABLE students (&lt;br&gt;
    student_id INT PRIMARY KEY,&lt;br&gt;
    first_name VARCHAR(50)&lt;br&gt;
);&lt;br&gt;
&lt;strong&gt;2. DML (Data Manipulation Language)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;DML works with the data stored inside existing tables.&lt;/p&gt;

&lt;p&gt;Common commands include:&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;INSERT&lt;br&gt;
UPDATE&lt;br&gt;
DELETE&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Example:&lt;/p&gt;

&lt;p&gt;INSERT INTO students&lt;br&gt;
VALUES (1, 'Amina');&lt;br&gt;
*&lt;em&gt;3. DQL (Data Query Language)&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
DQL is used to retrieve information from a database.&lt;/p&gt;

&lt;p&gt;The primary command is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SELECT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;SELECT *&lt;br&gt;
FROM students;&lt;/p&gt;

&lt;p&gt;This is the command you'll use most frequently when analyzing data.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;4. DCL (Data Control Language)&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
**DCL **controls access to the database.&lt;/p&gt;

&lt;p&gt;Examples include granting or revoking user permissions.&lt;/p&gt;

&lt;p&gt;Common commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GRANT&lt;/li&gt;
&lt;li&gt;REVOKE
*&lt;em&gt;5. TCL (Transaction Control Language)
*&lt;/em&gt;
TCL manages database transactions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Common commands include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;COMMIT&lt;/li&gt;
&lt;li&gt;ROLLBACK&lt;/li&gt;
&lt;li&gt;SAVEPOINT
These commands ensure data consistency when multiple operations are performed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Understanding Data Types
&lt;/h4&gt;

&lt;p&gt;Every column in a database must specify the type of data it will store.&lt;/p&gt;

&lt;p&gt;Choosing the correct data type improves performance, accuracy, and storage efficiency.&lt;/p&gt;

&lt;p&gt;Numeric Data Types&lt;br&gt;
&lt;strong&gt;INT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stores whole numbers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;25&lt;br&gt;
100&lt;br&gt;
500&lt;br&gt;
&lt;strong&gt;DECIMAL / NUMERIC&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stores numbers with fixed decimal places.&lt;/p&gt;

&lt;p&gt;Ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prices&lt;/li&gt;
&lt;li&gt;Salaries&lt;/li&gt;
&lt;li&gt;Financial records
Example:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2500.75&lt;br&gt;
99.99&lt;br&gt;
&lt;strong&gt;SERIAL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Automatically generates sequential numbers.&lt;/p&gt;

&lt;p&gt;Commonly used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Primary Keys&lt;/li&gt;
&lt;li&gt;IDs&lt;/li&gt;
&lt;li&gt;Text Data Types&lt;/li&gt;
&lt;li&gt;CHAR(n)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stores text with an exact number of characters.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CHAR(10)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Useful for fixed-length values like codes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VARCHAR(n)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stores text with a maximum length.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VARCHAR(50)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suitable for names and addresses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TEXT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stores large amounts of text without a predefined limit.&lt;/p&gt;

&lt;p&gt;Useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Descriptions&lt;/li&gt;
&lt;li&gt;Articles&lt;/li&gt;
&lt;li&gt;Comments&lt;/li&gt;
&lt;li&gt;Date and Time Data Types&lt;/li&gt;
&lt;li&gt;DATE&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stores only the date.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;2025-07-20&lt;br&gt;
&lt;strong&gt;TIME&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stores only the time.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;14:30:00&lt;br&gt;
&lt;strong&gt;TIMESTAMP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stores both the date and time.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;2025-07-20 14:30:00&lt;br&gt;
&lt;strong&gt;BOOLEAN&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  A Boolean column stores only two possible values:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;TRUE&lt;/li&gt;
&lt;li&gt;FALSE&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;is_active = TRUE&lt;br&gt;
Understanding Constraints&lt;/p&gt;

&lt;p&gt;Constraints are rules applied to tables or columns to ensure data integrity and prevent invalid information from entering the database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOT NULL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ensures a column cannot be left empty.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Every student must have a first name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DEFAULT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Provides a default value when none is supplied.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;status DEFAULT 'Active'&lt;br&gt;
UNIQUE&lt;/p&gt;

&lt;p&gt;Ensures duplicate values are not allowed.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Two users cannot register with the same email address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PRIMARY KEY&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Uniquely identifies each row in a table.&lt;/p&gt;

&lt;p&gt;A Primary Key:&lt;/p&gt;

&lt;p&gt;Cannot be NULL&lt;br&gt;
Must be unique&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;student_id&lt;br&gt;
&lt;strong&gt;FOREIGN KEY&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Links one table to another.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;h2&gt;
  
  
  Students
&lt;/h2&gt;

&lt;p&gt;student_id&lt;/p&gt;

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

&lt;p&gt;student_id&lt;/p&gt;

&lt;p&gt;The student_id in the Exam Results table must already exist in the Students table.&lt;/p&gt;

&lt;p&gt;This relationship prevents invalid references.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CHECK&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Applies custom validation rules.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;CHECK (marks &amp;gt;= 0)&lt;/p&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;p&gt;CHECK (price &amp;gt; 0)&lt;/p&gt;

&lt;p&gt;The database will reject values that violate these conditions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why These Concepts Matter
&lt;/h4&gt;

&lt;p&gt;Before writing complex SQL queries involving joins, aggregations, or window functions, it's essential to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How databases are organized.&lt;/li&gt;
&lt;li&gt;The purpose of schemas and tables.&lt;/li&gt;
&lt;li&gt;Choosing the correct data types.&lt;/li&gt;
&lt;li&gt;Using constraints to maintain clean and reliable data.&lt;/li&gt;
&lt;li&gt;The different categories of SQL commands.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;JOINs – Combining Data from Multiple Tables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a relational database, information is often split across multiple tables to reduce redundancy and improve organization. JOINs allow you to combine related data from these tables into a single result.&lt;/p&gt;

&lt;p&gt;For example, imagine a school database with three tables:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Students&lt;/li&gt;
&lt;li&gt;Subjects&lt;/li&gt;
&lt;li&gt;Exam Results&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead of storing all information in one table, the database links them using keys. &lt;br&gt;
A JOIN lets you answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which subjects is each student taking?&lt;/li&gt;
&lt;li&gt;What marks did each student score?&lt;/li&gt;
&lt;li&gt;Who teaches each subject?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Common types of JOINs include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;INNER JOIN&lt;/strong&gt; – Returns only matching records from both tables.&lt;br&gt;
&lt;strong&gt;LEFT JOIN&lt;/strong&gt; – Returns all records from the left table and matching records from the right table.&lt;br&gt;
&lt;strong&gt;RIGHT JOIN&lt;/strong&gt;– Returns all records from the right table and matching records from the left table.&lt;br&gt;
&lt;strong&gt;FULL OUTER JOIN&lt;/strong&gt; – Returns all records from both tables, whether they match or not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JOINs&lt;/strong&gt; are among the most frequently used SQL operations because real-world databases almost always store information across multiple related tables.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Aggregate Functions – Summarizing Data
&lt;/h4&gt;

&lt;p&gt;Aggregate functions calculate values across multiple rows and return a single result. Instead of viewing individual records, aggregates help summarize and analyze data.&lt;/p&gt;

&lt;p&gt;Some common aggregate functions include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;COUNT()&lt;/strong&gt; – Counts the number of records.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SUM()&lt;/strong&gt; – Calculates the total.&lt;/li&gt;
&lt;li&gt;*&lt;em&gt;AVG() *&lt;/em&gt;– Finds the average.&lt;/li&gt;
&lt;li&gt;*&lt;em&gt;MIN() *&lt;/em&gt;– Returns the smallest value.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MAX()&lt;/strong&gt; – Returns the largest value.
For example, a school administrator might want to know:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;How many students are enrolled?&lt;/li&gt;
&lt;li&gt;What is the average exam score?&lt;/li&gt;
&lt;li&gt;Which student scored the highest mark?&lt;/li&gt;
&lt;li&gt;How many students are in each class?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Aggregate functions are widely used in business intelligence, reporting, and dashboard development.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Subqueries – Queries Within Queries
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;A subquery&lt;/strong&gt; is a SQL query nested inside another SQL query. It allows you to use the result of one query as input for another.&lt;/p&gt;

&lt;p&gt;Subqueries are useful when solving more complex problems, such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Finding students who scored above the class average.&lt;/li&gt;
&lt;li&gt;Identifying products with sales higher than the average.&lt;/li&gt;
&lt;li&gt;Listing employees earning more than their department's average salary.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead of performing multiple separate queries, SQL can handle everything in one statement.&lt;/p&gt;

&lt;p&gt;Subqueries make SQL more flexible and allow you to solve sophisticated analytical problems with minimal code.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Common Table Expressions (CTEs) – Writing Cleaner SQL
&lt;/h4&gt;

&lt;p&gt;As SQL queries become longer, they can become difficult to read and maintain.&lt;/p&gt;

&lt;p&gt;Common Table Expressions (CTEs) help organize complex queries by breaking them into logical sections.&lt;/p&gt;

&lt;p&gt;A CTE acts like a temporary named result set that exists only during the execution of a query.&lt;/p&gt;

&lt;p&gt;Benefits of using CTEs include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improved readability.&lt;/li&gt;
&lt;li&gt;Easier debugging.&lt;/li&gt;
&lt;li&gt;Better organization of complex logic.&lt;/li&gt;
&lt;li&gt;Simplified maintenance.
Instead of writing deeply nested subqueries, you can separate each logical step into its own CTE, making your SQL easier for both you and your teammates to understand.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CTEs are especially useful in reporting, analytics, and data engineering workflows.&lt;/p&gt;

&lt;h4&gt;
  
  
  Window Functions – Performing Advanced Analytics
&lt;/h4&gt;

&lt;p&gt;Window functions are among the most powerful features in SQL. Unlike aggregate functions, which reduce multiple rows into one result, window functions perform calculations across related rows while keeping every individual row in the output.&lt;/p&gt;

&lt;p&gt;This makes them ideal for analytical tasks such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ranking students by exam score.&lt;/li&gt;
&lt;li&gt;Comparing a student's mark to the class average.&lt;/li&gt;
&lt;li&gt;Calculating running totals.&lt;/li&gt;
&lt;li&gt;Finding previous or next values.&lt;/li&gt;
&lt;li&gt;Identifying top-performing products or employees.
.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Common window functions include:&lt;/p&gt;

&lt;p&gt;**-ROW_NUMBER()&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RANK()&lt;/li&gt;
&lt;li&gt;DENSE_RANK()&lt;/li&gt;
&lt;li&gt;LAG()&lt;/li&gt;
&lt;li&gt;LEAD()&lt;/li&gt;
&lt;li&gt;FIRST_VALUE()&lt;/li&gt;
&lt;li&gt;LAST_VALUE()**&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Window functions are heavily used in business intelligence, financial reporting, customer analytics, and machine learning data preparation.&lt;/p&gt;

&lt;p&gt;How These Concepts Work Together&lt;/p&gt;

&lt;p&gt;Consider a school management system.&lt;/p&gt;

&lt;p&gt;You might:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use JOINs to combine student, subject, and exam data.&lt;/li&gt;
&lt;li&gt;Apply aggregate functions to calculate average marks.&lt;/li&gt;
&lt;li&gt;Use a subquery to identify students scoring above average.&lt;/li&gt;
&lt;li&gt;Organize the logic using a CTE for better readability.&lt;/li&gt;
&lt;li&gt;Apply window functions to rank students from highest to lowest.
Each concept builds upon the previous one, enabling increasingly sophisticated analysis.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why Every Data Professional Should Learn Advanced SQL&lt;/p&gt;

&lt;p&gt;Modern organizations rely heavily on data-driven decision-making. Advanced SQL skills enable professionals to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build interactive dashboards.&lt;/li&gt;
&lt;li&gt;Generate business reports.&lt;/li&gt;
&lt;li&gt;Analyze customer behavior.&lt;/li&gt;
&lt;li&gt;Monitor financial performance.&lt;/li&gt;
&lt;li&gt;Prepare datasets for machine learning.&lt;/li&gt;
&lt;li&gt;Design efficient data pipelines.&lt;/li&gt;
&lt;li&gt;Support business intelligence initiatives.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Whether you're working in healthcare, finance, agriculture, education, or e-commerce, these SQL techniques are essential for extracting meaningful insights from data.&lt;/p&gt;

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

&lt;p&gt;Mastering advanced SQL is a natural progression after learning the fundamentals. Concepts like databases, data types, constraints, SQL command categories ,JOINs, aggregate functions, subqueries, Common Table Expressions (CTEs), and window functions enable you to move beyond basic queries and solve complex, real-world data challenges.&lt;/p&gt;

&lt;p&gt;These skills are not only valuable for writing efficient SQL—they are also core competencies for careers in Data Analytics, Data Engineering, Business Intelligence, Database Administration, and Software Development.&lt;/p&gt;

&lt;p&gt;Every advanced SQL expert started with the basics. By practicing these concepts consistently and applying them to real projects, you'll build the confidence and expertise needed to work with large datasets, develop insightful reports, and create data-driven solutions that make a meaningful impact.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
