<?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: Quame Jnr</title>
    <description>The latest articles on DEV Community by Quame Jnr (@quame_jnr1).</description>
    <link>https://dev.to/quame_jnr1</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1009445%2Ffe09feda-7b95-4a8b-ab24-48336d2bed24.jpg</url>
      <title>DEV Community: Quame Jnr</title>
      <link>https://dev.to/quame_jnr1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/quame_jnr1"/>
    <language>en</language>
    <item>
      <title>Binary Search Trees: Why They’re Great in Memory but Terrible on Disk</title>
      <dc:creator>Quame Jnr</dc:creator>
      <pubDate>Thu, 05 Feb 2026 22:05:13 +0000</pubDate>
      <link>https://dev.to/quame_jnr1/binary-search-trees-why-theyre-great-in-memory-but-terrible-on-disk-1fjb</link>
      <guid>https://dev.to/quame_jnr1/binary-search-trees-why-theyre-great-in-memory-but-terrible-on-disk-1fjb</guid>
      <description>&lt;p&gt;Binary search trees (BST) are in-memory sorted data for efficient lookups. They have 2 children nodes, ergo the name binary. For each node, all values of nodes to the left should be less than the node and all values of nodes to the right should be greater than the node.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3297uw96gmro31t6agoa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3297uw96gmro31t6agoa.png" alt="Binary Search Tree" width="576" height="780"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is good because it allows you to do O(log N) search since the tree has O(log N) height. For a tree like ours above with 4 elements, in the worst case you traverse O(log 4) = 2 to find your target since the height is 2. However, BSTs can also be at the mercy of the insertion order, thus we need to constantly rebalance the tree.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tree Balancing
&lt;/h2&gt;

&lt;p&gt;If we insert numbers [1, 2, 3] then without rebalancing, insertions will determine the tree structure leading us to Fig A. This means O(N) searches, thus defeating the purpose of BST. A BST is seen as unbalanced if the difference between the heights of the two subtrees is greater than 1. We can rebalance by doing a rotation pivot to get Fig B.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Why does it Suck as Disk-Based Storage?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Random Insertion Order
&lt;/h3&gt;

&lt;p&gt;Each new node is allocated any free disk space and the pointer from its parent This means a node can be far away from its parent node, thus no benefits of locality.&lt;/p&gt;

&lt;p&gt;So here's the thing: when the OS is loading data into memory, it doesn't just load the target data, it loads in certain sizes, let's say 16KB. This contiguous segment of memory will contain your target data but also neighboring data. Ergo, if the next data the CPU has to operate on is closer to your target data, it might already be loaded in memory. Since BST puts nodes in any free space, it means you don't benefit from this as your child node might be in another segment of the disk.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Fanout of 2
&lt;/h3&gt;

&lt;p&gt;BST having binary nodes means a higher number of elements leads to higher height, and higher height means a higher number of traversals during search. So given 1 million elements, you will have a height of ~20, which means 20 traversals. Coupled with the data being in random disk locations means you have to do a disk seek for each node, read the data to find the pointer to the child node if it's not your target element, and then do another disk seek, another page transfer to read the data, over and over again.&lt;/p&gt;

&lt;p&gt;Also, keep in mind that the tree may rebalance during insertions, thus you can't cache pathways to a node as they may change.&lt;/p&gt;

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

&lt;p&gt;BSTs are elegant for in-memory operations; O(log N) searches with simple pointer-chasing works great when everything's in RAM. But the moment you move to disk, those same properties become liabilities. Random allocation kills locality, binary fanout means excessive tree height, and every pointer dereference potentially triggers a disk seek.&lt;/p&gt;

&lt;p&gt;This is why disk-based databases don't use binary search trees. Instead, they use B-trees and B+ trees with high fanout (hundreds of children per node instead of 2) and nodes sized to match disk pages. A B-tree with the same 1 million elements? Height of ~3 instead of ~20. That's the difference between 3 disk reads and 20.&lt;/p&gt;

&lt;p&gt;Sometimes data structures that work brilliantly in one context can be completely wrong for another.&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>computerscience</category>
      <category>performance</category>
      <category>programming</category>
    </item>
    <item>
      <title>Database Management System (DBMS) Architecture Explained</title>
      <dc:creator>Quame Jnr</dc:creator>
      <pubDate>Mon, 26 Jan 2026 09:56:55 +0000</pubDate>
      <link>https://dev.to/quame_jnr1/database-management-system-dbms-architecture-explained-1ija</link>
      <guid>https://dev.to/quame_jnr1/database-management-system-dbms-architecture-explained-1ija</guid>
      <description>&lt;p&gt;Most modern database management systems follow a &lt;strong&gt;client–server architecture&lt;/strong&gt;. The database acts as the server, responsible for storing, processing, and protecting data, while applications act as clients that send requests, usually SQL queries, over the network.&lt;/p&gt;

&lt;p&gt;At a high level, a DBMS can be broken into four major components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Query Processor&lt;/li&gt;
&lt;li&gt;Query Optimizer&lt;/li&gt;
&lt;li&gt;Execution Engine&lt;/li&gt;
&lt;li&gt;Storage Engine&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Query Processor
&lt;/h2&gt;

&lt;p&gt;The query processor is responsible for understanding and validating incoming SQL queries before any data is touched.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query Parser
&lt;/h3&gt;

&lt;p&gt;When a client sends a SQL query, it is first passed from the transport layer to the query parser. The parser’s job is to ensure that the query is valid and meaningful.&lt;/p&gt;

&lt;p&gt;This happens in several stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Lexical analysis:&lt;/strong&gt; The raw SQL string is broken into tokens such as keywords, identifiers, operators, and literals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Syntax checking:&lt;/strong&gt; The parser verifies that the tokens follow the grammar rules of SQL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic analysis:&lt;/strong&gt; The database checks that referenced tables, columns, functions, and operations actually exist and make sense.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access control checks:&lt;/strong&gt; The system ensures the user has the required permissions on the referenced objects.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If all checks pass, the parser produces an &lt;strong&gt;abstract syntax tree (AST).&lt;/strong&gt; This is then transformed into a &lt;strong&gt;logical query plan&lt;/strong&gt;, which represents the query in relational terms and is passed to the query optimizer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Query Optimizer
&lt;/h2&gt;

&lt;p&gt;The query optimizer’s goal is to find the most efficient way to execute the query.&lt;/p&gt;

&lt;p&gt;Given a logical query plan, the optimizer generates multiple &lt;strong&gt;physical execution plans&lt;/strong&gt;. These plans may differ in join order, join algorithms, index usage, or access paths. Each plan is assigned a cost, and the plan with the lowest estimated cost is chosen.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cost is an estimate of how expensive a query plan is to run. Lower cost usually means faster execution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How Cost Estimation Works
&lt;/h3&gt;

&lt;p&gt;The optimizer relies heavily on database statistics, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Number of rows in a table&lt;/li&gt;
&lt;li&gt;Number of distinct values per column&lt;/li&gt;
&lt;li&gt;Data distribution and histograms&lt;/li&gt;
&lt;li&gt;Index availability&lt;/li&gt;
&lt;li&gt;Percentage of NULL values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using these statistics, the optimizer estimates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;I/O cost&lt;/strong&gt; (disk reads and writes, typically the most expensive)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CPU cost&lt;/strong&gt; (hashing, comparisons, sorting)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory usage&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For very large tables, collecting exact statistics can be expensive. To manage this, many databases sample random data pages and extrapolate statistics from the sample. This balances accuracy with performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Execution Engine
&lt;/h2&gt;

&lt;p&gt;The execution engine is responsible for actually running the chosen execution plan.&lt;/p&gt;

&lt;p&gt;It walks the execution plan tree and executes each operator, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Table scans or index scans&lt;/li&gt;
&lt;li&gt;Filters and projections&lt;/li&gt;
&lt;li&gt;Joins&lt;/li&gt;
&lt;li&gt;Sorting and aggregation&lt;/li&gt;
&lt;li&gt;Set operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During execution, the engine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requests data pages from the storage engine&lt;/li&gt;
&lt;li&gt;Manages memory for operations like sorting and hashing&lt;/li&gt;
&lt;li&gt;Handles set operations and aggregations&lt;/li&gt;
&lt;li&gt;Formats the final result set and returns the result back to the client.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Storage Engine
&lt;/h2&gt;

&lt;p&gt;The storage engine handles how data is physically stored, retrieved, and protected on disk. It has several components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Buffer Manager:&lt;/strong&gt; Caches frequently accessed data pages in memory to reduce disk I/O.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access Methods:&lt;/strong&gt; Define how data is organized and accessed on disk, supporting structures such as sequential files, B-Trees, and LSM Trees.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction Manager:&lt;/strong&gt; Enforces ACID properties, ensuring that transactions are atomic, consistent, isolated, and durable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lock Manager:&lt;/strong&gt; Coordinates concurrent access to data. In many modern systems, this is implemented using &lt;strong&gt;MVCC (Multi-Version Concurrency Control)&lt;/strong&gt; rather than traditional locking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recovery Manager:&lt;/strong&gt; Manages write-ahead logging (WAL) and ensures the database can recover to a consistent state after crashes or failures.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;A &lt;strong&gt;page&lt;/strong&gt; is the fundamental unit of storage in a database. Each page contains multiple rows, with the exact number depending on page size and row layout.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;A DBMS is more than just a place to store data. From parsing SQL into a syntax tree, turning it into a logical plan, optimizing for best execution paths, managing memory, ensuring consistency and recovery from crashes, each layer has a critical role. &lt;/p&gt;

&lt;p&gt;Undertanding this architecture will help you write better queries and give you insights into performance, debugging and designing systems at scale.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>computerscience</category>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>Why Columnar Storage Makes Analytics Faster</title>
      <dc:creator>Quame Jnr</dc:creator>
      <pubDate>Mon, 19 Jan 2026 11:46:50 +0000</pubDate>
      <link>https://dev.to/quame_jnr1/why-columnar-storage-makes-analytics-faster-3mpp</link>
      <guid>https://dev.to/quame_jnr1/why-columnar-storage-makes-analytics-faster-3mpp</guid>
      <description>&lt;p&gt;Traditional databases store data row by row, which works well for many applications. But for analytics, most queries only touch one or two columns. Storing data by column is often much more efficient because each column is stored contiguously in memory, making it faster to load and process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Row storage
Row 0: [1, "Alice", "Engineering", 95000]
Row 1: [2, "Bob", "Sales", 87000]
Row 2: [3, "Carol", "Engineering", 102000]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Columnar storage
ids:         [1, 2, 3]
names:       ["Alice", "Bob", "Carol"]
departments: ["Engineering", "Sales", "Engineering"]
salaries:    [95000, 87000, 102000]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A query like the one below becomes much faster since only the relevant columns are loaded and processed:&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;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salary&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;employees&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Engineering'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Queries Are Faster with Columns
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory &amp;amp; cache efficiency&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Each column is stored contiguously, so loading a single column is fast.&lt;/li&gt;
&lt;li&gt;Smaller memory footprint means only the data you need is loaded. This also fits better in CPU caches.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Compression &amp;amp; storage&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Columns contain the same data type, often with repeated values, making them ideal for compression. For example, a column storing categories, gender or nationality will have low cardinality&lt;/li&gt;
&lt;li&gt;Algorithms like run-length encoding (RLE) or dictionary encoding handle this repetitive data extremely efficiently.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Vectorized processing (SIMD)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;CPUs can apply the same operation to multiple values in a column at once, speeding up aggregation and analytics.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This is one reason OLAP systems handle large-scale analytics much more efficiently than OLTP systems.&lt;/p&gt;

</description>
      <category>analytics</category>
      <category>database</category>
      <category>dataengineering</category>
      <category>performance</category>
    </item>
    <item>
      <title>Understanding Prometheus Storage: From Scrape to Disk</title>
      <dc:creator>Quame Jnr</dc:creator>
      <pubDate>Sun, 23 Nov 2025 18:32:05 +0000</pubDate>
      <link>https://dev.to/quame_jnr1/understanding-prometheus-storage-from-scrape-to-disk-1bhe</link>
      <guid>https://dev.to/quame_jnr1/understanding-prometheus-storage-from-scrape-to-disk-1bhe</guid>
      <description>&lt;p&gt;Prometheus is a time series monitoring system built for metrics and alerting. For people curious about how Prometheus works under the hood, this post will guide you through how Prometheus scrapes data, accumulates it in memory, and eventually persists it to disk.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Data Flow: From Metrics to Disk
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────┐
│ Scrape   │  (Pull metrics from targets)
└────┬─────┘
     │
     ↓
┌──────────┐
│  Parse   │  (Parse response, create series)
└────┬─────┘
     │
     ↓
┌──────────────┐
│   Batch      │  (Temporary, request-scoped buffer)
└────┬─────────┘
     │
     ├──→ [WAL] (Write to durability log)
     │
     ↓
┌─────────────────────┐
│ Head (In-Memory)    │  (Mutable chunks, queryable)
│ 2-hour window       │
└────┬────────────────┘
     │ (after 2 hours)
     ↓
┌──────────────────────┐
│  Block (On Disk)     │  (Immutable, compressed)
│ - metadata           │
│ - index              │
│ - chunks (512MB)     │
└──────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This entire cycle (scrape → parse → batch → WAL → Head) repeats every 15 seconds by default (configurable via the &lt;code&gt;scrape_interval&lt;/code&gt; setting). This means the Head continuously accumulates samples, with 240 scrapes per hour appending to series chunks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Scraping &amp;amp; Parsing
&lt;/h2&gt;

&lt;p&gt;Prometheus queries the &lt;code&gt;/metrics&lt;/code&gt; endpoint of target systems, receiving responses in a text-based format. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http_requests_total{job="api", instance="server1"} 100
http_requests_total{job="api", instance="server2"} 200
http_requests_total{job="web", instance="server1"} 50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prometheus parses this response line by line. Each unique combination of &lt;strong&gt;metric name&lt;/strong&gt; + &lt;strong&gt;label key-value pairs&lt;/strong&gt; becomes a &lt;strong&gt;series&lt;/strong&gt;. In this example, we have one metric (&lt;code&gt;http_requests_total&lt;/code&gt;) but three different series because the labels differ.&lt;/p&gt;

&lt;p&gt;This series-based organization allows Prometheus to track and query metrics independently by their labels. Now that we have series, they're temporarily collected into a &lt;strong&gt;batch&lt;/strong&gt; before being processed further.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Batch
&lt;/h2&gt;

&lt;p&gt;The batch is a temporary buffer that holds all the samples from a single scrape cycle. Once the scrape completes, &lt;code&gt;Commit()&lt;/code&gt; is called on the batch, triggering two operations: first, the data is written to a &lt;strong&gt;Write-Ahead Log (WAL)&lt;/strong&gt; for durability, then it's appended to the in-memory &lt;strong&gt;Head&lt;/strong&gt; for querying.&lt;/p&gt;

&lt;p&gt;Batching is more efficient than writing samples individually, all samples are written together in one operation, reducing I/O overhead. It's also atomic: either all samples from a batch succeed or none do, ensuring consistency.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Write-Ahead Log (WAL)
&lt;/h2&gt;

&lt;p&gt;Before any data is stored in memory or on disk, Prometheus writes it to a &lt;strong&gt;Write-Ahead Log (WAL)&lt;/strong&gt; file. Think of the WAL as a journal: it records encoded data structures (called &lt;strong&gt;records&lt;/strong&gt;) sequentially on disk. These records include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Series records (metric names and labels)&lt;/li&gt;
&lt;li&gt;Sample records (sample values and timestamps)&lt;/li&gt;
&lt;li&gt;Metadata records (metric metadata and exemplars)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why is the WAL critical?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If Prometheus crashes (power outage, Out of Memory (OOM), restart), unsaved data in memory is lost. The WAL acts as a safety net. When Prometheus restarts, it replays these records from the WAL to recover all uncommitted samples and rebuild the in-memory state. This ensures &lt;strong&gt;durability&lt;/strong&gt;: no data loss.&lt;/p&gt;

&lt;p&gt;The WAL typically uses segments of ~128MB each (configurable). These files are stored on disk and can be replayed if needed. After records are written to the WAL successfully, it's safe to update the in-memory Head, knowing that even if the system crashes next second, that data can be recovered.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Head (In-Memory)
&lt;/h2&gt;

&lt;p&gt;The Head is Prometheus's in-memory mutable storage. It contains multiple series, and each series tracks its own list of &lt;strong&gt;chunks&lt;/strong&gt;: compressed, time-ordered collections of samples. New samples are constantly appended to existing series, growing the chunks until they fill up, at which point new chunks are created.&lt;/p&gt;

&lt;p&gt;The Head keeps data in memory for a configurable time window (default: 2 hours). This design has tradeoffs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Benefit:&lt;/strong&gt; In-memory storage enables fast writes and queries. Answering questions like "What was the CPU usage 5 minutes ago?" is immediate since data is already in RAM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; More unique series means more memory usage. This is why Prometheus can suffer from high memory consumption with &lt;strong&gt;high-cardinality metrics&lt;/strong&gt; (thousands or millions of unique series due to many label combinations).&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why does cardinality matter?&lt;/strong&gt; Each series stores its labels (metric name + key-value pairs), a unique ID, and its list of chunks. When you have many unique series, each one consumes memory for storing label strings and chunk metadata. For example, a single metric with 1,000 unique label combinations = 1,000 separate series, each with its own label data and chunk pointers. This is why high-cardinality metrics can quickly exhaust memory.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After 2 hours of data accumulation, the Head is sealed and flushed to disk as an immutable &lt;strong&gt;block&lt;/strong&gt;. This move from memory to disk is critical for long-term storage and frees up memory for new incoming data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blocks (On Disk)
&lt;/h2&gt;

&lt;p&gt;A block is a directory containing all the time-series data from a 2-hour window in a compressed, queryable format. Once sealed, blocks are immutable and stored on disk for long-term retention.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Block Structure:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;metadata file:&lt;/strong&gt; Contains metadata about the block (time range, number of series, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;index file:&lt;/strong&gt; Maps metric names and labels to their corresponding series, enabling fast lookups during queries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;chunks directory:&lt;/strong&gt; Contains the actual time-series data. While each chunk belongs to a single series, multiple chunks from different series are packed together into segment files (512MB each by default) for efficient storage and retrieval.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why are blocks immutable?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Immutability is key to Prometheus's design. Once a block is written to disk, it never changes. This enables &lt;strong&gt;compaction&lt;/strong&gt;: the process of merging multiple blocks together. For example, you might merge 30 blocks from 30 days into fewer, larger blocks, reducing disk usage and improving query performance. Immutability ensures compaction is safe: no concurrent writes can conflict with the merge operation.&lt;/p&gt;

&lt;p&gt;This immutable-block architecture is one reason Prometheus is so efficient: old data is read-only, allowing aggressive optimization without worrying about concurrent modifications.&lt;/p&gt;

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

&lt;p&gt;Now you understand the journey of data in Prometheus. Every 15 seconds, metrics are scraped, parsed into series, collected into a batch, written to the WAL for durability, appended to the in-memory Head for fast queries, and then sealed to disk as immutable blocks after 2 hours.&lt;/p&gt;

&lt;p&gt;This architecture is elegant: it balances speed, durability, and long-term storage. The in-memory Head enables sub-millisecond query responses for recent data. The WAL ensures no data loss on crashes. Immutable blocks on disk enable efficient compaction and long-term retention without sacrificing query performance.&lt;/p&gt;

&lt;p&gt;The tradeoff? Memory usage scales with cardinality. Understanding this design helps you make better decisions when monitoring with Prometheus, whether it's designing your metric labels, configuring retention, or troubleshooting performance.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>database</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Prometheus: The Essential Guide to Monitoring Systems</title>
      <dc:creator>Quame Jnr</dc:creator>
      <pubDate>Thu, 06 Nov 2025 08:22:39 +0000</pubDate>
      <link>https://dev.to/quame_jnr1/prometheus-the-essential-guide-to-monitoring-systems-48od</link>
      <guid>https://dev.to/quame_jnr1/prometheus-the-essential-guide-to-monitoring-systems-48od</guid>
      <description>&lt;h2&gt;
  
  
  What is Prometheus?
&lt;/h2&gt;

&lt;p&gt;Prometheus is an open-source systems monitoring and alerting toolkit originally built at SoundCloud. It collects metrics as time series data, numerical measurements stored with timestamps and optional key-value pairs called labels. Since joining the Cloud Native Computing Foundation in 2016, it has become a standalone project with an active community.&lt;/p&gt;

&lt;h2&gt;
  
  
  History and Relevance Compared to Older Tools
&lt;/h2&gt;

&lt;p&gt;When monitoring tools like Nagios (1999), Zabbix (2004), and Graphite emerged, they were designed for stable, on-premises environments with fixed servers. As cloud computing and microservices grew popular with containers and services scaling dynamically these tools faced challenges.&lt;/p&gt;

&lt;p&gt;Their limitations included push-based architectures, where agents sent data to a central system, leading to configuration issues in changing setups and missed data from short-lived jobs. They lacked multi-dimensional labels for flexible data analysis, and querying was limited. Storage was often absent or added separately.&lt;/p&gt;

&lt;p&gt;Prometheus addressed these by using a pull model to retrieve metrics, enabling auto-discovery. Its labels and PromQL query language allowed rich data exploration, while self-contained storage ensured reliability. Joining the CNCF in 2016, it became key for Kubernetes and modern infrastructures, offering better adaptability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use Prometheus?
&lt;/h2&gt;

&lt;p&gt;Prometheus helps monitor system and application performance, such as CPU usage, RAM usage, network traffic, and request counts. It alerts you to issues like sudden RAM or CPU surges, memory leaks, or high error rates. This is especially useful for dynamic, service-oriented architectures where traditional monitoring falls short.&lt;/p&gt;

&lt;p&gt;It excels in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Machine-centric monitoring&lt;/strong&gt;: Tracking hardware metrics like CPU, memory, and disk usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application monitoring&lt;/strong&gt;: Measuring request latency, error rates, and throughput.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microservices architectures&lt;/strong&gt;: Handling dynamic environments with multi-dimensional data (e.g., labeling by service, version).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alerting&lt;/strong&gt;: Triggering notifications for thresholds (e.g., "RAM usage &amp;gt; 90%").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability during outages&lt;/strong&gt;: Standalone design allows diagnosis when other systems fail.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, it's not ideal for 100% accurate billing data, as it prioritizes reliability over completeness in failure scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does It Work?
&lt;/h2&gt;

&lt;p&gt;Prometheus performs three main functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Retrieves data&lt;/strong&gt;: Uses a pull model over HTTP to scrape metrics from endpoints (typically &lt;code&gt;/metrics&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stores data&lt;/strong&gt;: Saves metrics in a time series database with timestamps and labels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Queries data&lt;/strong&gt;: Provides an HTTP API for querying via PromQL, a flexible query language.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To expose metrics, applications use client libraries or exporters like the Node Exporter for system data. For short-lived jobs, a push gateway allows pushing metrics that Prometheus then scrapes. The Alertmanager handles alerts by routing them to channels like Slack or email.&lt;/p&gt;

&lt;h3&gt;
  
  
  Metric Types in Prometheus
&lt;/h3&gt;

&lt;p&gt;Prometheus uses four metric types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Counter&lt;/strong&gt;: How many times something happened (e.g., number of requests).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gauge&lt;/strong&gt;: The current value of something that can go up or down (e.g., CPU or memory usage).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Histogram&lt;/strong&gt;: How long or big something is (e.g., request latency).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Summary&lt;/strong&gt;: Pre-computed percentiles for distributions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;Prometheus scrapes metrics from instrumented jobs directly or via the push gateway. It stores samples locally and runs rules for aggregation or alerting. Visualization tools like Grafana query the data via the API.&lt;/p&gt;

&lt;p&gt;At its core, Prometheus handles three key functions: retrieving metrics (scraping), saving metrics (storing in TSDB), and querying metrics (via HTTP API).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
┌─────────────────┐          ┌──────────────────────────────┐          ┌─────────────┐
│                 │          │     PROMETHEUS SERVER        │          │             │
│  Instrumented   │─ Pull ──▶│                              │◀─ Query ─│   Grafana   │
│      Jobs       │          │  ┌────────────────────────┐  │          │             │
│   (/metrics)    │          │  │   1. Retrieval         │  │          └─────────────┘
└─────────────────┘          │  │      (Scrape)          │  │
                             │  └──────────┬─────────────┘  │
┌─────────────────┐          │             │                │          ┌─────────────┐
│                 │          │             ▼                │          │             │
│  Push Gateway   │─ Pull ──▶│  ┌────────────────────────┐  │─ Alert  ─│ Alertmanager│
│  (short-lived)  │          │  │   2. Storage (TSDB)    │  │          │             │
└─────────────────┘          │  └──────────┬─────────────┘  │          └──────┬──────┘
        ▲                    │             │                │                 │
        │ Push               │             ▼                │                 │
┌─────────────────┐          │  ┌────────────────────────┐  │                 ▼
│  Short-lived    │          │  │   3. Query (HTTP API)  │  │          ┌─────────────┐
│     Jobs        │          │  │      PromQL            │  │          │ Slack/Email │
└─────────────────┘          │  └────────────────────────┘  │          └─────────────┘
                             │                              │
┌─────────────────┐          │  ┌────────────────────────┐  │
│                 │          │  │   Rules Engine         │  │
│    Exporters    │─ Pull ──▶│  │   (Aggregation +       │  │
│  (Node, etc.)   │          │  │    Alerting)           │  │
└─────────────────┘          │  └────────────────────────┘  │
                             └──────────────────────────────┘


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Components
&lt;/h2&gt;

&lt;p&gt;The Prometheus ecosystem includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prometheus server&lt;/strong&gt;: The core engine that scrapes, stores, and queries metrics using a time series database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client libraries&lt;/strong&gt;: SDKs for languages like Go, Python, or Java to instrument application code and expose custom metrics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Push gateway&lt;/strong&gt;: An intermediary for short-lived jobs (e.g., batch scripts) to push metrics, which Prometheus then scrapes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exporters&lt;/strong&gt;: Specialized tools that collect metrics from external systems (e.g., Node Exporter for OS stats, HAProxy for load balancers) and expose them in Prometheus format.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alertmanager&lt;/strong&gt;: Handles alert routing, deduplication, and notifications to channels like Slack or email.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Support tools&lt;/strong&gt;: Utilities for tasks like configuration validation, data migration, or federation with other Prometheus instances.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Prometheus is a powerful, flexible tool for modern monitoring, especially in dynamic environments like microservices and Kubernetes. It addresses many limitations of older tools through its pull model, labels, and query language.&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>monitoring</category>
      <category>opensource</category>
      <category>devops</category>
    </item>
    <item>
      <title>Virtual Machines: How One Computer Becomes Many</title>
      <dc:creator>Quame Jnr</dc:creator>
      <pubDate>Mon, 08 Sep 2025 15:20:24 +0000</pubDate>
      <link>https://dev.to/quame_jnr1/virtual-machines-how-one-computer-becomes-many-25k7</link>
      <guid>https://dev.to/quame_jnr1/virtual-machines-how-one-computer-becomes-many-25k7</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Virtual machines (VM) virtualize the hardware of a physical computer (like CPU, RAM, storage) to allow multiple isolated operating systems (OS) on the physical computer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Brief History
&lt;/h2&gt;

&lt;p&gt;Before the age of personal computing, computers used to be these large mainframes that were being used in big organizations and schools like MIT. These mainframes had relatively a lot of resources at that time and thus to use resources efficiently and reduce idle time, Compatible Time Sharing System (CTSS) was introduced&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the early 1960s, researchers on MIT's Project MAC introduced &lt;strong&gt;CTSS&lt;/strong&gt;. CTSS allowed multiple users to use the same computer at the same time giving them the illusion that they are the only ones who had access to the computer at the time. It provided some form of isolation protecting your personal files but you still used the same applications and OS on the machine.&lt;/li&gt;
&lt;li&gt;In the 1960s, IBM introduced the &lt;strong&gt;CP-40&lt;/strong&gt;, an experimental time sharing project that laid the groundwork for VMs. It took CTSS a step further by using virtualization to give users the illusion that they had their own dedicated machine. Users could run multiple isolated computing sessions on the machine giving them greater control, flexibility and isolation.&lt;/li&gt;
&lt;li&gt;Building on the CP-40 experiment, IBM released &lt;strong&gt;VM/370&lt;/strong&gt; in August 1972, which became the first commercial virtual machine system. This marked the true beginning of virtualization as we know it today.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This early virtualization concept from VM/370 evolved over decades, eventually becoming the foundation for today's hypervisor technology.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it work
&lt;/h2&gt;

&lt;p&gt;Virtual machines use what we call a hypervisor to create virtualized hardware that allows operating systems to run in isolation over a physical computer's hardware. This allows different operating systems to run on top of the computer hardware unaware it is not directly on the physical machine. The process involves 3 components.&lt;/p&gt;

&lt;h3&gt;
  
  
  Components
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The host machine:&lt;/strong&gt; This is the physical computer that provides the hardware resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The guest machine:&lt;/strong&gt; This is the virtual machine that will be running on top of the host machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hypervisor:&lt;/strong&gt; This sits between the host and guest machine and acts as a translator. It acts as a translator managing host's resources to the guest VMs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Process
&lt;/h3&gt;

&lt;p&gt;Assuming the guest operating system wants to write to a file in the virtual hard disk, it will issue a syscall to perform the action just as it would on a physical machine.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Intercepting requests:&lt;/strong&gt; The hypervisor will intercept the request coming from the guest machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Translating requests:&lt;/strong&gt; The hypervisor will translate the request to the host machine. In this case, it ensures the file the guest machine is trying to write into maps to the specific folder on the physical drive. This is because virtual machines, its configs and applications all exist in a specific folder on your drive. It also translates the commands into instructions the host computer can understand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource allocation:&lt;/strong&gt; The hypervisor will manage and allocate resources to the guest VM from the host's pool and ensure each VM is isolated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Returning Results:&lt;/strong&gt; Once the physical machine is done performing the action, the hypervisor translates back to the format the guest OS can understand.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Types of Hypervisors
&lt;/h2&gt;

&lt;p&gt;Hypervisors are of two different types based on where they sit on the stack.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type 1:&lt;/strong&gt; In type 1, the hypervisor runs directly on the bare metal hardware without a traditional host OS underneath it. This makes it fast and efficient. This is mostly used in enterprise data centers and cloud environments. Eg. VMware ESXi.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type 2:&lt;/strong&gt; Type 2 hypervisors are installed as an application on the host machine's OS. This adds an extra layer as the hypervisor has to translate requests through the host OS instead of directly to the hardware. This is simple to install and mostly used by developers for testing in a different OS and playing around safely in a different OS. Eg. VirtualBox&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why should you care?
&lt;/h2&gt;

&lt;p&gt;VMs are incredibly useful, they provide isolation, flexibility and portability and these are some of the reasons I think you should care;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sandboxing
&lt;/h3&gt;

&lt;p&gt;VMs create the ultimate sandbox if you're a developer or curious. You can use it to;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;test untrusted software&lt;/li&gt;
&lt;li&gt;mess around with system configs&lt;/li&gt;
&lt;li&gt;test your program on multiple operating systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Running Multiple Operating Systems
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;if you are Mac user, curious about linux, you can install it on a VM without having to partition your disks&lt;/li&gt;
&lt;li&gt;you can try out platform specific applications without having to switch your host OS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Virtual machines are ubiquitous albeit abstracted. When you create an instance on AWS, you are creating a virtual machine on one of Amazon's big machines and you are not alone. Virtual machines give you the illusion that you have a dedicated machine. This VM technology has also paved the way for containers, another virtualization approach that's become essential in modern software deployment.&lt;/p&gt;

</description>
      <category>virtualmachine</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>Why 0.1 + 0.2 != 0.3: Understanding Floating Point Arithmetic in Computers</title>
      <dc:creator>Quame Jnr</dc:creator>
      <pubDate>Mon, 09 Sep 2024 11:56:05 +0000</pubDate>
      <link>https://dev.to/quame_jnr1/why-01-02-03-understanding-floating-point-arithmetic-4pcm</link>
      <guid>https://dev.to/quame_jnr1/why-01-02-03-understanding-floating-point-arithmetic-4pcm</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;
Normalization and Representation

&lt;ul&gt;
&lt;li&gt;Explicit Normalization&lt;/li&gt;
&lt;li&gt;Implicit Normalization&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Converting Floating Point Decimal to Binary&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;If you have worked with floating-point numbers in computers, you'll notice they sometimes exhibit certain weird behavior. For example, if you type &lt;code&gt;0.1 + 0.2&lt;/code&gt; in the Python console, you're going to get &lt;code&gt;0.30000000000000004&lt;/code&gt; instead of &lt;code&gt;0.3&lt;/code&gt;. This behavior is mainly due to how computers store floating-point numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Normalization and Representation
&lt;/h2&gt;

&lt;p&gt;For us, &lt;code&gt;0.1&lt;/code&gt; is just &lt;code&gt;0.1&lt;/code&gt;, but that is in decimal, and computers know nothing about decimals. All they know is binary. Computers store floating-point numbers by first converting them from floating-point decimal into binary, which we'll take a look at shortly. Then they do what we call normalization.&lt;/p&gt;

&lt;p&gt;The idea behind normalization is to create some form of standard. This is because floating-point numbers can be represented in different ways. Take, for example, &lt;code&gt;0.123&lt;/code&gt;. We can represent this as 

&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;1.23×10−11.23 \times 10^{-1}&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1.23&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 or 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;12.3×10−212.3 \times 10^{-2}&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;12.3&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
. These are all valid ways of representing floating-point numbers. To make it standardized, we first came up with what is now known as &lt;strong&gt;explicit normalization&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Explicit Normalization
&lt;/h3&gt;

&lt;p&gt;With explicit normalization, we move the radix point of a floating-point binary number to the left-hand side of its most significant 1. For example, given the binary number &lt;code&gt;10.100&lt;/code&gt;, we'll move the radix point to the left-hand side of the most significant 1, giving &lt;code&gt;0.10100&lt;/code&gt;. Since we moved the radix point 2 times to the left, we will multiply by 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;222^2 &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, thus 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;10.100=0.10100×2210.100 = 0.10100 \times 2^2 &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10.100&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.10100&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is binary, thus we're multiplying by &lt;code&gt;2&lt;/code&gt; and not &lt;code&gt;10&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This allows us to save only the fractional part, &lt;code&gt;10100&lt;/code&gt;, which is also known as the mantissa, and the exponent, &lt;code&gt;2&lt;/code&gt;. The values are laid out in memory in the form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;________________________
|sign|exponent|mantissa|
------------------------
sign: represents the sign of the floating-point number, with 0 being positive and 1 being negative
exponent: represents the exponent of 2 after normalization
mantissa: represents the fractional value after the radix point
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For simplicity's sake, let's assume we have an 8-bit computer, so we're going to store our floating-point number in 8 bits. We use &lt;code&gt;1&lt;/code&gt; bit to represent our sign, &lt;code&gt;4&lt;/code&gt; bits to represent our exponent, and &lt;code&gt;3&lt;/code&gt; bits to represent our mantissa.&lt;/p&gt;

&lt;p&gt;The sign is &lt;code&gt;0&lt;/code&gt; since the value is positive, and the mantissa will be &lt;code&gt;10100&lt;/code&gt;. The exponent will be a bit tricky as we can't just convert &lt;code&gt;2&lt;/code&gt; into binary and save it. This is because the exponent can be a negative number, thus we need to add a bias. We get the bias using 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;2k−1−12^{k-1} - 1 &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;k&lt;/span&gt;&lt;span class="mbin mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 where &lt;code&gt;k&lt;/code&gt; is the number of bits representing the exponent, which for our 8-bit computer is 4. Thus, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;24−1−1=72^{4-1} - 1 = 7 &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;4&lt;/span&gt;&lt;span class="mbin mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;7&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, so our exponent will be 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;2+7=92 + 7 = 9 &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;7&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;9&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, whose binary is &lt;code&gt;1001&lt;/code&gt;. A representation of &lt;code&gt;0.10100&lt;/code&gt; in an 8-bit computer will be:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;____________
|0|1001|101|
------------
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;We only store &lt;code&gt;101&lt;/code&gt; instead of &lt;code&gt;10100&lt;/code&gt; because we only have 3 bits to save our number.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can then convert this back with the formula:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;v=−1s×0.M×2e
v = -1^s \times 0.M \times 2^e
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;s&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.&lt;/span&gt;&lt;span class="mord mathnormal"&gt;M&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;e&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;−1s-1^s &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;s&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 allows us to get the right sign of the value. &lt;code&gt;s&lt;/code&gt; is the sign, and thus if &lt;code&gt;s&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt;, then the expression will evaluate to 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;−10=1-1^0 = 1 &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, but if &lt;code&gt;s&lt;/code&gt; is &lt;code&gt;1&lt;/code&gt;, then the expression will evaluate to 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;−11=−1-1^1 = -1 &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;0.M&lt;/code&gt; evaluates to &lt;code&gt;0.101&lt;/code&gt; as &lt;code&gt;M&lt;/code&gt; represents the mantissa.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;2e2^e &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;e&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 evaluates to the exponent, but before saving the exponent, we added a bias, thus we need to subtract the bias: 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;e=exponent−bias=9−7=2e = \text{exponent} - \text{bias} = 9 - 7 = 2 &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;exponent&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord text"&gt;&lt;span class="mord"&gt;bias&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;9&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;7&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
. Thus, the formula becomes &lt;br&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;v=−1s×0.M×2e=1×0.101×22=0.101×22=10.1
v = -1^s \times 0.M \times 2^e = 1 \times 0.101 \times 2^2 = 0.101 \times 2^2 = 10.1 &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;s&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.&lt;/span&gt;&lt;span class="mord mathnormal"&gt;M&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;e&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.101&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.101&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10.1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Implicit Normalization
&lt;/h3&gt;

&lt;p&gt;The problem with explicit normalization is the same problem that leads to the sum of &lt;code&gt;0.1&lt;/code&gt; and &lt;code&gt;0.2&lt;/code&gt; not being exactly &lt;code&gt;0.3&lt;/code&gt;. The problem is precision. With floating-point numbers, the more bits we can store, the more precise our floating-point representation. With our 8-bit computer described earlier, we had 3 bits representing the mantissa. This means if we had more than 3 bits, as we did, we could still only save 3 bits, thus losing the remaining bits. However, if instead of moving the radix point to the left-hand side of the most significant 1 bit, we move it to the right-hand side of it, we can save an extra fractional bit.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;10.100&lt;/code&gt; will become 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;1.0100×211.0100 \times 2^1 &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1.0100&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 and will be represented as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;____________
|0|1000|010|
------------
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We can then, during conversion, change the expression &lt;code&gt;0.M&lt;/code&gt; to &lt;code&gt;1.M&lt;/code&gt;.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;v=−1s×1.M×2e=1×0.1010×22=0.1010×22=10.10
v = -1^s \times 1.M \times 2^e = 1 \times 0.1010 \times 2^2 = 0.1010 \times 2^2 = 10.10
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;s&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1.&lt;/span&gt;&lt;span class="mord mathnormal"&gt;M&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;e&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.1010&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.1010&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;10.10&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The last bit is 0 so it’s irrelevant in this case but would be important if it was 1.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thus, implicit normalization allows us to imply there is a &lt;code&gt;1&lt;/code&gt; and saves an extra bit. One bit may not seem like a lot, but it's the difference between ASCII and UTF-8, it's the difference between 127 and 256, so yeah, for computers, it's a lot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Converting Floating Point Decimal to Binary
&lt;/h2&gt;

&lt;p&gt;Now that we have some basic understanding of how computers store floating-point numbers, let's try to understand why 0.1 + 0.2 is not particularly equal to 0.3. First, let's convert 0.1 and 0.2 to binary. To convert floating-point numbers to binary, we first convert the value before the radix point to binary and then multiply the fractional part by 2, keeping the value of the integer before the radix point until the value becomes 1. Yeah, that may not have been the best explanation, so let's see an example.&lt;/p&gt;

&lt;p&gt;Let's say we want to convert &lt;code&gt;2.25&lt;/code&gt; to binary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Convert the integer before the radix point, which is &lt;code&gt;2&lt;/code&gt;, to binary: &lt;code&gt;10&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Convert the fractional part by multiplying it by 2 and keep whatever integer is before the radix point until we get &lt;code&gt;1&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0.25 × 2 = 0.5 → 0
0.5 × 2 = 1.0 → 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then put the integer values you got from top down behind the radix point. The floating-point &lt;code&gt;2.25&lt;/code&gt; will be &lt;code&gt;10.01&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now let's convert &lt;code&gt;0.1&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The integer before the radix point is 0, which is the same in binary&lt;/li&gt;
&lt;li&gt;Convert the remaining fraction:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0.1 × 2 = 0.2 → 0
0.2 × 2 = 0.4 → 0
0.4 × 2 = 0.8 → 0
0.8 × 2 = 1.6 → 1
0.6 × 2 = 1.2 → 1
0.2 × 2 = 0.4 → 0
0.4 × 2 = 0.8 → 0
0.8 × 2 = 1.6 → 1
0.6 × 2 = 1.2 → 1
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We can see this goes on and on. This is a recurring binary number, thus &lt;code&gt;0.1&lt;/code&gt; in binary is &lt;code&gt;0.0001100110011...&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can also do the same for &lt;code&gt;0.2&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0.2 × 2 = 0.4 → 0
0.4 × 2 = 0.8 → 0
0.8 × 2 = 1.6 → 1
0.6 × 2 = 1.2 → 1
0.2 × 2 = 0.4 → 0
0.4 × 2 = 0.8 → 0
0.8 × 2 = 1.6 → 1
0.6 × 2 = 1.2 → 1
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Thus, &lt;code&gt;0.2&lt;/code&gt; in binary is &lt;code&gt;0.001100110011...&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now before adding these two numbers, we're first going to store them in our 8-bit computer:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Normalize using implicit normalization:

&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;0.1=0.000110011...=1.100110011...×2−40.1 = 0.000110011... = 1.100110011... × 2^{-4}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.000110011...&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1.100110011...&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;

&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;0.2=0.00110011...=1.100110011...×2−30.2 = 0.00110011... = 1.100110011... × 2^{-3} 
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.2&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.00110011...&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1.100110011...&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;/li&gt;

&lt;li&gt;Add bias to our exponents:

&lt;ul&gt;
&lt;li&gt;for 0.1: &lt;code&gt;-4 + 7 = 3&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;for 0.2: &lt;code&gt;-3 + 7 = 4&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Store in our 8-bit computer. We only have 3 bits for the fractional part, so we can only store 3 values after the radix point, meaning we lose all the remaining bits:
&lt;/li&gt;

&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For 0.1
____________
|0|0011|100|
------------

For 0.2
____________
|0|0100|100|
------------
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Convert them back to their floating-point representations using our formula earlier 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;v=−1s×1.M×2ev = -1^s \times 1.M \times 2^e &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;v&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;s&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1.&lt;/span&gt;&lt;span class="mord mathnormal"&gt;M&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;e&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
:

&lt;ul&gt;
&lt;li&gt;0.1: 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;1.100×2−4=0.00011001.100 \times 2^{-4} = 0.0001100 &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1.100&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.0001100&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/li&gt;
&lt;li&gt;0.2: 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;1.100×2−3=0.0011001.100 \times 2^{-3} = 0.001100 &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1.100&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.001100&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Add them:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  0.0001100
+ 0.001100
-----------
  0.0100100   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Convert back to decimal. Values before the radix point will be converted as normal, while values after the radix point will have exponents with decreasing values of negative numbers, i.e., 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;2−1,2−22^{-1}, 2^{-2} &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, etc.:

&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;0.0100100→(0×20)+(0×2−1)+(1×2−2)+(0×2−3)+(0×2−4)+(1×2−5)+0=0+0+0.25+0+0+0.03125=0.281250.0100100 →
(0 × 2^0) + (0 × 2^{-1}) + (1 × 2^{-2}) + (0 × 2^{-3}) + (0 × 2^{-4}) + (1 × 2^{-5}) + 0
= 0 + 0 + 0.25 + 0 + 0 + 0.03125
= 0.28125
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.0100100&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;→&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;−&lt;/span&gt;&lt;span class="mord mtight"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.25&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.03125&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;0.28125&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;

&lt;p&gt;In our 8-bit computer,&lt;code&gt;0.1 + 0.2 = 0.28125&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

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

&lt;p&gt;We started this article trying to understand why 0.1 + 0.2 sometimes does not give us 0.3. Using our 8-bit computer for illustration purposes, we've been able to come to that conclusion. This weird behavior, we came to understand, was a result of how computers normalize and represent floating-point numbers, which leads to loss of bits, ergo leading to loss of precision.&lt;/p&gt;

&lt;p&gt;Luckily for us, we have 32-bit and 64-bit computers now. The Institute of Electrical and Electronics Engineers (IEEE) has standards for how these representations should be done. Thus, 32-bit systems allow 8 bits for the exponent and 23 bits for the mantissa, while 64-bit systems use 11 bits for the exponent and 52 bits for the mantissa. They both still use 1 bit for the sign. This means 64-bit systems have more bits to store the fractional parts, hence more precision. This is why 64-bit systems are known as double-precision and 32-bit systems are known as single-precision. The more bits we're able to store, the closer our approximation to the actual value.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Go Test Coverage: Visualizing Profiles</title>
      <dc:creator>Quame Jnr</dc:creator>
      <pubDate>Mon, 22 Jul 2024 13:54:27 +0000</pubDate>
      <link>https://dev.to/quame_jnr1/go-test-coverage-b42</link>
      <guid>https://dev.to/quame_jnr1/go-test-coverage-b42</guid>
      <description>&lt;h2&gt;
  
  
  Table of Content
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Go Tests&lt;/li&gt;
&lt;li&gt;Go Tests Coverage&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Go has incredible tooling out of the box. It has tools for testing, benchmarking, profiling etc. I want to discuss an interesting one that impressed me: go test coverage and the different visualization options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go Tests
&lt;/h2&gt;

&lt;p&gt;To help us understand these concepts, we will be writing some functions to do basic calculations.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Let's first write a function that adds two numbers
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num1&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;num2&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Let's write some tests for it
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"testing"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestAddition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"wanted %d got %d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Let's run our tests to see if everything is ok
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ok      github.com/quamejnr/go-cover    0.687s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything looks good. &lt;br&gt;
We can also see how much of our code written is covered by tests and this is where the excitement begins.&lt;/p&gt;
&lt;h2&gt;
  
  
  Go Tests Coverage
&lt;/h2&gt;

&lt;p&gt;To see the test coverage, we can add a &lt;code&gt;-cover&lt;/code&gt; flag to our &lt;code&gt;go test&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ok      github.com/quamejnr/go-cover    &lt;span class="o"&gt;(&lt;/span&gt;cached&lt;span class="o"&gt;)&lt;/span&gt;        coverage: 100.0% of statements
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Currently we are 100% covered as we have written tests for all our code.&lt;br&gt;
Now let's add a division function and see what happens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Div&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;denom&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&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;denom&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"invalid division error"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;denom&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can rerun our test coverage command and see our response.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ok      github.com/quamejnr/go-cover    &lt;span class="o"&gt;(&lt;/span&gt;cached&lt;span class="o"&gt;)&lt;/span&gt;        coverage: 50.0% of statements
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we've covered only 50% of our coverage as we are yet to write tests for our division function. &lt;br&gt;
For a simple case like this, it's obvious what we need to test but in a larger codebase it's not so apparent and this is where coverage can be very powerful.&lt;br&gt;
Go gives us tools to visualize where exactly in our code have not been tested. &lt;br&gt;
We can do this by passing in some flags to our go test command: &lt;code&gt;go test -coverprofile=c.out&lt;/code&gt;. &lt;code&gt;coverprofile&lt;/code&gt; generates a coverage profile with the value being the name of the output file, in this case &lt;code&gt;c.out&lt;/code&gt;.&lt;br&gt;
Once you have the profile &lt;code&gt;c.out&lt;/code&gt;, you can examine it to know more about your code coverage using the go's tool command.&lt;br&gt;
We can check it out on our terminal using the command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go tool cover &lt;span class="nt"&gt;-func&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;c.out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;github.com/quamejnr/go-cover/main.go:3: Add             100.0%
github.com/quamejnr/go-cover/main.go:7: Div             0.0%
total:                                  &lt;span class="o"&gt;(&lt;/span&gt;statements&lt;span class="o"&gt;)&lt;/span&gt;    50.0%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows our &lt;code&gt;Div&lt;/code&gt; function is yet to have any test coverage so let's add test coverage to our &lt;code&gt;Div&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestDivison&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Test division"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Div&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"wanted %d got %d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we should have covered everything. Let's run our coverage again and see&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ok      github.com/quamejnr/go-cover    0.213s  coverage: 75.0% of statements
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It says we have covered only 75% of our test coverage.&lt;br&gt;
And if we generate our cover profile again and inspect it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go &lt;span class="nb"&gt;test&lt;/span&gt; ./... &lt;span class="nt"&gt;-coverprofile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;c.out
go tool cover &lt;span class="nt"&gt;-func&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;c.out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;github.com/quamejnr/go-cover/main.go:3: Add             100.0%
github.com/quamejnr/go-cover/main.go:7: Div             66.7%
total:                                  &lt;span class="o"&gt;(&lt;/span&gt;statements&lt;span class="o"&gt;)&lt;/span&gt;    75.0%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see we have covered only &lt;code&gt;66.7%&lt;/code&gt; of our &lt;code&gt;Div&lt;/code&gt; code but this doesn't give us much info on what we're missing out.&lt;br&gt;
This is where another useful visualization tool of the coverprofile comes in. &lt;br&gt;
Go gives us the ability to look at our code in our browser to see which parts are yet to be tested. All we need to do is change our &lt;code&gt;-func&lt;/code&gt; flag to &lt;code&gt;-html&lt;/code&gt; flag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go tool cover &lt;span class="nt"&gt;-html&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;c.out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffa3dg4idx7lxc9ohvgw2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffa3dg4idx7lxc9ohvgw2.png" alt="Browser visualization of Go test coverage" width="800" height="271"&gt;&lt;/a&gt;&lt;br&gt;
This screenshot shows us that we're yet to test our path when &lt;code&gt;denom&lt;/code&gt; is 0.&lt;br&gt;
Let's update our &lt;code&gt;TestDivison&lt;/code&gt; function to handle that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestDivison&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Test division"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Div&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"wanted %d got %d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Test division with 0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;recover&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"zero divsion did not panic"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}()&lt;/span&gt;
        &lt;span class="n"&gt;Div&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if we run our go test coverage command, we should have 100% coverage.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ok      github.com/quamejnr/go-cover    0.649s  coverage: 100.0% of statements
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;In this article, we examined how we can use go's coverage tools to help us with our testing coverage&lt;br&gt;
We learnt how to;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;create coverage profiles&lt;/li&gt;
&lt;li&gt;examine them in our terminal &lt;/li&gt;
&lt;li&gt;visualize them in our browsers.
All code can be found here &lt;a href="https://github.com/quamejnr/go-cover" rel="noopener noreferrer"&gt;https://github.com/quamejnr/go-cover&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=HfCsfuVqpcM&amp;amp;list=PLoILbKo9rG3skRCj37Kn5Zj803hhiuRK6&amp;amp;index=39" rel="noopener noreferrer"&gt;Go Class: 39 Code Coverage by Matt Holiday&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>testing</category>
    </item>
    <item>
      <title>Understanding XOR-based-value Swapping</title>
      <dc:creator>Quame Jnr</dc:creator>
      <pubDate>Sat, 04 May 2024 09:05:49 +0000</pubDate>
      <link>https://dev.to/quame_jnr1/understanding-xor-based-value-swapping-15nj</link>
      <guid>https://dev.to/quame_jnr1/understanding-xor-based-value-swapping-15nj</guid>
      <description>&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Objectives&lt;/li&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Understanding XOR&lt;/li&gt;
&lt;li&gt;Proof of the 3 XOR operations&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Objectives
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Understanding XOR operations&lt;/li&gt;
&lt;li&gt;Understanding why the 3 special XOR operations swap two numbers in place&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Given two numbers &lt;code&gt;x=5&lt;/code&gt; and &lt;code&gt;y=10&lt;/code&gt;, we can switch these two numbers in place by using a temporary variable as the C code below;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&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;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Before reassignment&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"x: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"y: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-----------------------&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Assign y to a temporay variable&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"After reassignment&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"x: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"y: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&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;There is also another way to do this by using Exclusive OR (XOR). This does not need a temporary variable and will switch the values in place.&lt;br&gt;
It involves 3 XOR operations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&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;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Before reassignment&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"x: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"y: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-----------------------&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// XOR is represented by ^&lt;/span&gt;
    &lt;span class="c1"&gt;// The 3 XOR operations&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"After reassignment&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"x: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"y: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&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 above code changes the two variables without using a temporary variable. When you do those 3 XOR operations, the variables will switch places but why?&lt;br&gt;
To understand that, let's first understand what Exclusive OR (XOR) is.&lt;/p&gt;
&lt;h2&gt;
  
  
  Understanding XOR
&lt;/h2&gt;

&lt;p&gt;XOR is a logical operator that returns True only if one of its inputs is True. For example: Given two inputs if both input &lt;code&gt;A&lt;/code&gt; and input &lt;code&gt;B&lt;/code&gt; are True then the XOR of both will be False.&lt;br&gt;
If both are False then the XOR will also be False. XOR will only be True if one of them is True and the other is False. &lt;br&gt;
To use 0s and 1s to represent our inputs, we can say True is 1 and False is 0. Thus, an XOR operation between the two inputs will give us the table below;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input A&lt;/th&gt;
&lt;th&gt;Input B&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  XOR between binary numbers
&lt;/h2&gt;

&lt;p&gt;This means if we XOR two binary numbers, A(1011) and B(0110), we are going to get 1101.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   A:    1 0 1 1
   B:    0 1 1 0
----------------
Result:  1 1 0 1

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we also XOR two binary numbers, A(1011) and B(1011), we are going to get 0000&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   A:    1 0 1 1
   B:    1 0 1 1
----------------
Result:  0 0 0 0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see both binary numbers are the same and we know XOR outputs 0 if both inputs are the same, ergo &lt;code&gt;A ^ A = 0&lt;/code&gt;.&lt;br&gt;
We can also also establish that XOR between A and B where A=0 will output B.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   A:    0 0 0 0
   B:    0 1 1 0
----------------
Result:  0 1 1 0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means &lt;code&gt;0 ^ B = B&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Given:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A ^ A = 0 and 
0 ^ B = B
We can say;
(A ^ A) ^ B = B
This is associative and can also be written as;
A ^ A ^ B = B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Proof of the 3 XOR operations
&lt;/h2&gt;

&lt;p&gt;Let's go back to our 3 operations that change x and y in place;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y = x ^ y
x = x ^ y
y = x ^ y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's use the various rules we've established so far to see if we can prove that after these 3 operations &lt;code&gt;x=y&lt;/code&gt; and &lt;code&gt;y=x&lt;/code&gt;.&lt;br&gt;
We have the first 2 operations;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y = x ^ y and 
x = x ^ y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can replace y in the 2nd operation with its value in the first: &lt;code&gt;x ^ y&lt;/code&gt;, ergo our second operation can be expanded to;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x = x ^ y
x = x ^ (x ^ y) 
x = x ^ x ^ y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have already established that &lt;code&gt;A ^ A ^ B = B&lt;/code&gt; thus,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x = x ^ x ^ y = y
x = y

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So x is now y on the 2nd operation.&lt;/p&gt;

&lt;p&gt;We can now represent our 3 operations as;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y = x ^ y
x = y
y = x ^ y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then proceed to expand our 3rd operation by replacing x whose current value is now y and y whose current value is x ^ y;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y = x ^ y
Replacing x with y and y with x ^ y;
y = y ^ (x ^ y) 
y = y ^ x ^ y 
y = y ^ y ^ x
y = x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the 3 operations, we have x = y and y = x.&lt;/p&gt;

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

&lt;p&gt;We've been able to prove why 3 special XOR operations lead to the swapping of two values without using a temporary variable.&lt;br&gt;
Although this algorithm does not offer any significant improvement over swapping two values using a temporary variable, understanding it gives us a better understanding of bit operations and their properties.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Mocking Return Values in Python</title>
      <dc:creator>Quame Jnr</dc:creator>
      <pubDate>Tue, 19 Dec 2023 17:52:13 +0000</pubDate>
      <link>https://dev.to/quame_jnr1/mocking-requests-in-python-2anc</link>
      <guid>https://dev.to/quame_jnr1/mocking-requests-in-python-2anc</guid>
      <description>&lt;p&gt;Unit tests are easier to write when given a set of inputs you know you're always going to get an expected response. It becomes a bit difficult when the same set of inputs can lead to varying responses.&lt;br&gt;
When you work on programs where sometimes you have to make a request to an external API or making requests to other services in your microservices, you can't be sure you're going to get &lt;code&gt;200&lt;/code&gt; status code on each request.&lt;br&gt;
You'll mostly put in measures to handle when your requests fail but how do you write unit tests to ensure your system works as expected.&lt;/p&gt;
&lt;h2&gt;
  
  
  Writing Program
&lt;/h2&gt;

&lt;p&gt;Let's build a program that a pings a url and returns &lt;code&gt;True&lt;/code&gt; if the status code is &lt;code&gt;200&lt;/code&gt; and &lt;code&gt;False&lt;/code&gt; when it is not.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a file called &lt;code&gt;client.py&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Write the following code
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# client.py
&lt;/span&gt;
&lt;span class="c1"&gt;# Make sure you have requests installed.
# If not, you can install with `pip3 install requests` 
# or `pip install requests`.
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;retun&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&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;ping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://google.com&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;ol&gt;
&lt;li&gt;Run &lt;code&gt;python3 client.py&lt;/code&gt; in your terminal in the directory where &lt;code&gt;client.py&lt;/code&gt; resides. The below should be your response;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ python3 client.py
True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Writing Tests
&lt;/h2&gt;

&lt;p&gt;Our program works as expected. It's time to write tests to ensure that we return &lt;code&gt;True&lt;/code&gt; when our request is &lt;code&gt;200&lt;/code&gt; and &lt;code&gt;False&lt;/code&gt; when the status code is not &lt;code&gt;200&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a file called &lt;code&gt;test_client.py&lt;/code&gt; in the same directory as &lt;code&gt;client.py&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Write the following code;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# test_client.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;unittest&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ping&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://google.com&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;test_ping_returns_200&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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="nf"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&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;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;python3 test_client.py&lt;/code&gt;. You should get a response like below;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ python3 test_client.py
&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="nt"&gt;---------------------------------------------------------&lt;/span&gt;
Ran 1 &lt;span class="nb"&gt;test &lt;/span&gt;&lt;span class="k"&gt;in &lt;/span&gt;1.113s

OK

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;All our tests are passing but now let's test for the case when the status code is not &lt;code&gt;200&lt;/code&gt;. Let's add another test to our test&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="c1"&gt;# test_client.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;unittest&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ping&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://google.com&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;test_ping_returns_200&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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="nf"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# New
&lt;/span&gt;     &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_ping_returns_500&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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="nf"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&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;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we rerun &lt;code&gt;python3 test_client.py&lt;/code&gt;, our new test fails.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
❯ python3 test_client.py
.F
&lt;span class="o"&gt;==========================================================&lt;/span&gt;
FAIL: test_ping_returns_500 &lt;span class="o"&gt;(&lt;/span&gt;__main__.TestClient.test_ping_returns_500&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;----------------------------------------------------------&lt;/span&gt;
Traceback &lt;span class="o"&gt;(&lt;/span&gt;most recent call last&lt;span class="o"&gt;)&lt;/span&gt;:
  File &lt;span class="s2"&gt;"/Users/mock/test_client.py"&lt;/span&gt;, line 46, &lt;span class="k"&gt;in &lt;/span&gt;test_ping_returns_500
    self.assertFalse&lt;span class="o"&gt;(&lt;/span&gt;result&lt;span class="o"&gt;)&lt;/span&gt;
AssertionError: True is not &lt;span class="nb"&gt;false&lt;/span&gt;

&lt;span class="nt"&gt;-----------------------------------------------------------&lt;/span&gt;
Ran 2 tests &lt;span class="k"&gt;in &lt;/span&gt;2.076s

FAILED &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;failures&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is because for now our request returns &lt;code&gt;200&lt;/code&gt;, so we are unable to test for when our &lt;code&gt;ping&lt;/code&gt; fails.&lt;br&gt;
To be able to do this we are going to mock our requests and responses. This gives us the ability to determine what response we should get.&lt;br&gt;
This way we can manipulate our requests to return &lt;code&gt;500&lt;/code&gt; response status code instead of the actual status code.&lt;/p&gt;
&lt;h2&gt;
  
  
  Mocking requests and responses
&lt;/h2&gt;

&lt;p&gt;First we're going to import the &lt;code&gt;patch&lt;/code&gt; decorator and &lt;code&gt;MagicMock&lt;/code&gt; object from &lt;code&gt;unittest.mock&lt;/code&gt;.&lt;br&gt;
The &lt;code&gt;patch&lt;/code&gt; decorator allows us to edit our &lt;code&gt;requests&lt;/code&gt;, it takes a target which will be the requests we want to change, which in this case is the one in &lt;code&gt;client.py&lt;/code&gt;. &lt;br&gt;
The &lt;code&gt;MagicMock&lt;/code&gt; object allows us to create the response we want so we can pass it to requests. &lt;br&gt;
We have add an additional parameter which can be named anyway we want. I'll name it &lt;code&gt;mock_requests&lt;/code&gt;. This is the object we can attach our response to.&lt;br&gt;
Let's add these changes to our &lt;code&gt;test_client.py&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="c1"&gt;# test_client.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;unittest&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;unittest.mock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MagicMock&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ping&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://google.com&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;test_ping_returns_200&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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="nf"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


    &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client.requests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# New
&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_ping_returns_500&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_requests&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;    &lt;span class="c1"&gt;# New
&lt;/span&gt;
        &lt;span class="c1"&gt;# New
&lt;/span&gt;        &lt;span class="n"&gt;mock_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MagicMock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;mock_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
        &lt;span class="n"&gt;mock_requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mock_response&lt;/span&gt;

        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&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;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's dive into what we've done so far.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;By adding the decorator &lt;code&gt;@patch("client.requests")&lt;/code&gt;, we're saying we want to modify the &lt;code&gt;requests&lt;/code&gt; function that we imported in &lt;code&gt;client.py&lt;/code&gt;. 
It can be any function, we could have targeted &lt;code&gt;ping&lt;/code&gt; itself. You can try that on your own after this.
The &lt;code&gt;patch&lt;/code&gt; decorator modifies our test method and passes in a second argument to our &lt;code&gt;test_ping_returns_500&lt;/code&gt; method. Thus, we add &lt;code&gt;mock_requests&lt;/code&gt; as a parameter to our method. This &lt;code&gt;mock_requests&lt;/code&gt; is a mock variant of &lt;code&gt;requests&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We instantiate our &lt;code&gt;MagicMock&lt;/code&gt; object and assign to &lt;code&gt;mock_response&lt;/code&gt;. Our &lt;code&gt;MagicMock&lt;/code&gt; object allows us to take the form of any class we want and in this case a &lt;code&gt;Response&lt;/code&gt; object.&lt;/li&gt;
&lt;li&gt;We add a &lt;code&gt;status_code&lt;/code&gt; attribute to our &lt;code&gt;mock_response&lt;/code&gt; and assign it the value of &lt;code&gt;500&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;We proceed to assign our &lt;code&gt;mock_response&lt;/code&gt; to &lt;code&gt;mock_requests.get.return_value&lt;/code&gt;. 
We have now modified our requests in that, we're saying, when the &lt;code&gt;requests&lt;/code&gt; in &lt;code&gt;client.py&lt;/code&gt; calls it's &lt;code&gt;get&lt;/code&gt; function, we want the value returned to be that of our &lt;code&gt;mock_response&lt;/code&gt;. 
Thus when &lt;code&gt;requests.get()&lt;/code&gt; is called, the value returned is going to be the &lt;code&gt;mock_response&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If we run our test again, we see everything passes now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
❯ python3 test_client.py
..
&lt;span class="nt"&gt;----------------------------------------------------------------------&lt;/span&gt;
Ran 2 tests &lt;span class="k"&gt;in &lt;/span&gt;1.609s

OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can proceed to do the same for &lt;code&gt;test_ping_returns_200&lt;/code&gt; method but make the status_code &lt;code&gt;200&lt;/code&gt; so we can add a fake url instead of making requests to &lt;code&gt;https://google.com&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="c1"&gt;# test_client.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;unittest&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;unittest.mock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MagicMock&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ping&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.service.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;    &lt;span class="c1"&gt;# New
&lt;/span&gt;
    &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client.requests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# New
&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_ping_returns_200&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_requests&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;    &lt;span class="c1"&gt;# New
&lt;/span&gt;
        &lt;span class="c1"&gt;# New
&lt;/span&gt;        &lt;span class="n"&gt;mock_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MagicMock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;mock_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&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;mock_requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mock_response&lt;/span&gt;


        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


    &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client.requests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_ping_returns_500&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_requests&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

        &lt;span class="n"&gt;mock_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MagicMock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;mock_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
        &lt;span class="n"&gt;mock_requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mock_response&lt;/span&gt;

        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&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;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can run our tests again to ensure everything works well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
❯ python3 test_client.py
..
&lt;span class="nt"&gt;----------------------------------------------------------------------&lt;/span&gt;
Ran 2 tests &lt;span class="k"&gt;in &lt;/span&gt;1.609s

OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mocking response body
&lt;/h3&gt;

&lt;p&gt;We can also add response body to our &lt;code&gt;mock_response&lt;/code&gt;. Assuming, the 3rd party API we're pinging returns a json response with an attribute &lt;code&gt;{"status": "ok"}&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Let's modify our function in &lt;code&gt;client.py&lt;/code&gt; to return the json response too when the status_code is &lt;code&gt;200&lt;/code&gt; and &lt;code&gt;None&lt;/code&gt; when it is not.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# client.py
&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# New
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;We modify our &lt;code&gt;test_client.py&lt;/code&gt; to this;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# test_client.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;unittest&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;unittest.mock&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MagicMock&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ping&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setUp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.service.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client.requests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_ping_returns_200&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_requests&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

        &lt;span class="n"&gt;mock_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MagicMock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;mock_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&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;mock_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&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;status&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;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;# New
&lt;/span&gt;        &lt;span class="n"&gt;mock_requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mock_response&lt;/span&gt;


        &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# New
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&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;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


    &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client.requests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_ping_returns_500&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_requests&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

        &lt;span class="n"&gt;mock_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MagicMock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;mock_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
        &lt;span class="n"&gt;mock_requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mock_response&lt;/span&gt;

        &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# New
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&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;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding &lt;code&gt;mock_response.json.return_value&lt;/code&gt;, we're saying when we call the &lt;code&gt;json&lt;/code&gt; function on our &lt;code&gt;mock_response&lt;/code&gt; we should get &lt;code&gt;{"status": "ok"}&lt;/code&gt;. &lt;br&gt;
Thus, &lt;code&gt;{"status": "ok"}&lt;/code&gt; is the value we get when we call &lt;code&gt;res.json()&lt;/code&gt; in &lt;code&gt;client.py&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;Mocking requests make testing easier especially when you have to deal with 3rd party APIs and even other services in your microservices.&lt;br&gt;
Let's say, you have an API that first makes a request to your auth service to confirm if a user has certain permissions before allowing them access to certain resources.&lt;br&gt;
You can mock the response you have to test that only users with the needed permissions are allowed to access the resource.&lt;/p&gt;

&lt;p&gt;Code for this tutorial can be found here &lt;a href="https://github.com/quamejnr/python-mock-requests" rel="noopener noreferrer"&gt;https://github.com/quamejnr/python-mock-requests&lt;/a&gt; &lt;/p&gt;

</description>
      <category>python</category>
      <category>testing</category>
    </item>
    <item>
      <title>Introduction to Caches</title>
      <dc:creator>Quame Jnr</dc:creator>
      <pubDate>Thu, 07 Dec 2023 09:46:56 +0000</pubDate>
      <link>https://dev.to/quame_jnr1/introduction-to-caches-1h66</link>
      <guid>https://dev.to/quame_jnr1/introduction-to-caches-1h66</guid>
      <description>&lt;h2&gt;
  
  
  Objectives
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Understand what caching is?&lt;/li&gt;
&lt;li&gt;Understand how caching is done?&lt;/li&gt;
&lt;li&gt;Understand the difference between cache hit and cache miss?&lt;/li&gt;
&lt;li&gt;What data inconsistency is and how we can minimize it in our cache services?&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;I'm going to ask you to do a couple of computations and I'll want you to bear with me. You can use a calculator if you want.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is 30 x 25? Got the answer?&lt;/li&gt;
&lt;li&gt;Ok What is 2 x 3?&lt;/li&gt;
&lt;li&gt;Great, what is 30 x 25 again?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you observed, the first time you answered what 30 x 25 was, it took you a while to compute the answer which is 750 by the way but the second time I asked the question, you most likely didn't have to recompute the answer, you just remembered the answer because you had just made the computation not long ago. This is what caching is about. A &lt;a href="https://aws.amazon.com/caching/"&gt;cache service&lt;/a&gt; stores part of your data(mostly recently accessed data) so it can serve data faster. Caches happen from the low level of computer architecture with pages, L-series caches and RAM to the application layer using tools like &lt;a href="https://www.memcached.org/"&gt;memcached&lt;/a&gt; and &lt;a href="https://redis.io/"&gt;redis&lt;/a&gt;. This article will focus more on the application level.&lt;/p&gt;

&lt;h2&gt;
  
  
  How is caching done?
&lt;/h2&gt;

&lt;p&gt;Sometimes, the requests coming to your system will need a lot of computing process before a response. Sometimes, you have high number of requests coming in your services which will put your database under heavy pressure leading to high &lt;a href="https://aws.amazon.com/what-is/latency/"&gt;latency&lt;/a&gt;. Caches allow you to serve data faster by not having to hit your datastore on each request. It improves your read performance thus increasing your overall throughput. Adding a caching&lt;br&gt;
layer to your system means anytime a read request comes in;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your system checks your cache service and if the data exists in the cache service, the request is served.&lt;/li&gt;
&lt;li&gt;If the data is not in the cache service, the request is sent to your database to get the data so it's served. The data is also written to your cache service.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The more the data being requested are found in the cache the faster you can serve responses and this is known as cache hit. Cache hit is the rate at which data being requested are found in your cache. The opposite is cache miss, which defines the rate at which data being requested are not found in the cache. The goal is to increase your cache hit as the higher your cache hit the faster you serve your responses. When your caches don't have a lot of data in them, they are said to be cold and when they do have a lot of data in them they are said to be warm.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This was the cause of the &lt;a href="https://slack.engineering/slacks-incident-on-3-22-22/"&gt;Slack's incident on 0-22-22&lt;/a&gt;. They had an issue that led to their cache layers being flushed thus becoming cold leading to high cache misses that overloaded their databases. Databases couldn't keep up with all the requests and kept timing out which also hampered their cache service from filling up with data thus leading to higher requests on database. They had to throttle their system so they can fail some requests and be able to serve some requests to gradually build their cache system to a level of normalcy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Data Inconsistency
&lt;/h2&gt;

&lt;p&gt;Caches as good as they are are also tricky to deal with. One of the biggest issues is data inconsistency. Data inconsistency is as a result of data in your database being different from data in your cache. This can be as a result of&lt;br&gt;
updates on data not yet synchronised to your cache service. There are different ways to resolve this and they all have their pros and cons.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Write through.&lt;/strong&gt; Data will first be written to your cache and then written to your datastore synchronously. This is expensive as two writes have to be done simultaneously, one to the database and one to the cache.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write behind.&lt;/strong&gt; Data will first be written to your cache and later be written to your database asynchronously.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;They both shine in different situations. Let's say, you are building a caching layer that serve the &lt;code&gt;likes&lt;/code&gt; feature on your products in your e-commerce store. If someone likes a product, it's not integral to show them the right number of&lt;br&gt;
likes at the moment, the consequences are inconsequential thus you can update the cache and update your database later. However, let's say you caching the &lt;code&gt;quantity&lt;/code&gt; of the products. It's very important to show the latest updated&lt;br&gt;
quantity, otherwise you'll end up with more orders than products. You want to use a write through approach in such cases even though it's computationally expensive.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Data invalidation.&lt;/strong&gt; We can also update data on the cache when the data has been updated or we can invalidate the data and create a new data that the requests will be pointed to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time to Live (TTL).&lt;/strong&gt; We can also set a TTL, in which we give data a limited amount of time like 60 seconds, after which the data becomes obsolete. You want to set your TTL to a range +/- 10s of your chosen time. So for 60s, that will be range 50s-70s. This ensures all your cache data don't go cold at the same time thus overloading your database with requests.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why don't we use cache everywhere?
&lt;/h2&gt;

&lt;p&gt;If caches are so good then why don't we use them all the time?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Because caches contain temporary data, the data are saved in your RAM thus when your system goes down or restarts, you lose your cache data. Due to continuous deployments, errors, autoscaling etc. containers restart and rebalance quite frequently. This means when you have your cache services baked in your applications, your cache will go cold frequently. This is why caches are recommended as standalone services (We will discuss this in another article).&lt;/li&gt;
&lt;li&gt;Apart from the transient nature of RAM, they are also very expensive. You need databases to write your data to disks not only to save your data but also to save you cost.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;In the current climate where everything is supposed to be blazingly fast. You want to increase your system response times using cache. However, you want to be&lt;br&gt;
also aware of the extra complexity it introduces and how to mitigate its pitfalls.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://redis.com/blog/three-ways-to-maintain-cache-consistency/"&gt;Maintaining Cache Consistency&lt;/a&gt;&lt;/p&gt;

</description>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Optimizing API Endpoint (Real World Case Study)</title>
      <dc:creator>Quame Jnr</dc:creator>
      <pubDate>Thu, 10 Aug 2023 16:03:17 +0000</pubDate>
      <link>https://dev.to/quame_jnr1/increasing-response-time-of-orders-4pe3</link>
      <guid>https://dev.to/quame_jnr1/increasing-response-time-of-orders-4pe3</guid>
      <description>&lt;h2&gt;
  
  
  Situation
&lt;/h2&gt;

&lt;p&gt;I had to work on a task where we wanted to show payment information of orders to users which meant as the backend engineer, I had to add payment information to the data being sent to the client.&lt;br&gt;
The payment data is on another service so had to make a request to that service so I can add it to the order information. The task itself was pretty easy, however prior to doing the task, I realised the endpoint was already taking about &lt;code&gt;3s&lt;/code&gt; to return a response. &lt;code&gt;3s&lt;/code&gt; may not seem like a lot but in the age of TikTok, It was too long. The endpoint was doing two things under the hood when the client makes a request.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make a request to orders service for orders.&lt;/li&gt;
&lt;li&gt;Make a request to product service product images to update order items with current product images.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I didn't think these processes warranted the response time especially when the response was paginated so investigated the implementation details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Multiple Calls
&lt;/h3&gt;

&lt;p&gt;When we make a request to get orders from our order service we make another request to the products service to get an updated image of the order items in each order. Each order item is a product and we needed to get images of those products from another service to include it in the order item when returning orders data to the client. Our proxy service which from here will be regarded as bff (backend for frontend) is the one making these calls. The implementation was in this manner;&lt;br&gt;
&lt;strong&gt;In bff&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We loop through orders &lt;/li&gt;
&lt;li&gt;Then loop through the order items in each order&lt;/li&gt;
&lt;li&gt;Get the product id of each order item, put them in a list then make a request to the product service for the current image of the order items.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;All Code snippets have been modified to represent the logic of the implementation. This simplifies the code so the reader can easily understand without having to worry about other unnecessary details.&lt;/em&gt;&lt;/p&gt;


&lt;/blockquote&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;get_images_for_orders&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="ow"&gt;in&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;product_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="n"&gt;order_items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"order_items"&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;order_item&lt;/span&gt; &lt;span class="ow"&gt;in&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;order_item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"product_id"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;product_ids&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_request_for_product_images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"results"&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;add_images_to_orders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;images&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A request was being made to the products service to get product images on each iteration of order thus leading a network for each order. This was done this way because the images were needed in certain order to be able to easily match each order item to image. So first product image in the list had to belong to the first order item.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In products service&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Receive the request for images, get the product uuids&lt;/li&gt;
&lt;li&gt;Loop through the product ids and query the database for product image on each iteration.
&lt;/li&gt;
&lt;/ol&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;get_product_images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_ids&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;product_images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;prod_id&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;product_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;## The first product image is being retrieved because a product can
&lt;/span&gt;        &lt;span class="c1"&gt;## have multiple images
&lt;/span&gt;        &lt;span class="n"&gt;product_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ProductImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;filter&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;prod_id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;product_images&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;product_images&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Doing this meant, we make a db call on every single product id. &lt;br&gt;
This meant if our request for orders returns 20 orders per page and each order had 2 order items. We are going to make 20 network calls in the bff and 40 database queries in the products service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;To increase the response time, there were two solutions I had to implement.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make one network call in the bff.&lt;/li&gt;
&lt;li&gt;Make one db call in the products service.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;The first solution was implemented by putting all the product ids of order items into one list before making the network call.&lt;/li&gt;
&lt;li&gt;The second solution was implemented by modifying the db call so we can get distinct product images.&lt;/li&gt;
&lt;li&gt;Implementing the first two posed another challenge. We needed to find a way to match each image to its respective order item. That was resolved using a dictionary (hash table).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Refactoring
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Make one network call
&lt;strong&gt;In bff&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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;get_images_for_orders&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_items_dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="ow"&gt;in&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_items&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="s"&gt;"order_items"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;order_items_dict&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;order_item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"product_id"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;order_item&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;order_item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;order_items&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;product_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_items_dict&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_request_for_product_images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"results"&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;add_images_to_orders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order_items_dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Putting &lt;code&gt;order_items&lt;/code&gt; in a dictionary &lt;code&gt;order_items_dict&lt;/code&gt; with &lt;code&gt;product_id&lt;/code&gt; as key and the &lt;code&gt;order_item&lt;/code&gt; as value, meant we don't have to worry about the order the product images come in, we can just match them to their product ids in &lt;code&gt;order_items_dict&lt;/code&gt; thus resolving our challenge of matching the images to the order.&lt;br&gt;
We can then get all the keys which will now be the list of the &lt;code&gt;product_ids&lt;/code&gt; and use them for our request.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make one database call
&lt;strong&gt;In products service&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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;get_product_images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_ids&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;product_images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;ProductImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;product_id__in&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;product_ids&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_by&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"product_id"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;distinct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"product_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;return&lt;/span&gt; &lt;span class="n"&gt;product_images&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query ensures we only get one product image per &lt;code&gt;product_id&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;These little changes reduced the response time of our calls from &lt;code&gt;3s&lt;/code&gt; to &lt;code&gt;1s&lt;/code&gt;. Also, these changes ensures only one network call and only one db call is made no matter the number of orders, thus changing our time complexity from &lt;code&gt;O(n)&lt;/code&gt; to &lt;code&gt;O(1)&lt;/code&gt;. Last but not least, this endpoint is widely used by a number of teams in the company and getting orders went from being noticeably delayed to almost instant thus saving a lot of time.&lt;/p&gt;

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