<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Projects |</title><link>https://ad25aderram.github.io/my-portfolio/projects/</link><atom:link href="https://ad25aderram.github.io/my-portfolio/projects/index.xml" rel="self" type="application/rss+xml"/><description>Projects</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Sun, 19 May 2024 00:00:00 +0000</lastBuildDate><image><url>https://ad25aderram.github.io/my-portfolio/media/icon_hu_b93c5070c370bd46.png</url><title>Projects</title><link>https://ad25aderram.github.io/my-portfolio/projects/</link></image><item><title>Nginx Load Balancer &amp; Reverse Proxy</title><link>https://ad25aderram.github.io/my-portfolio/projects/nginx-load-balancer/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><guid>https://ad25aderram.github.io/my-portfolio/projects/nginx-load-balancer/</guid><description>&lt;p&gt;A hands-on deep-dive into how production traffic actually gets distributed — built from scratch using Nginx as a reverse proxy in front of three Dockerized Node.js app instances.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;The goal was to understand load balancing not just in theory but by building and operating it. The result is a fully containerized system where Nginx round-robins incoming HTTPS requests across three identical Node.js instances, each running in its own Docker container — with health checks, SSL termination, and a live dashboard that makes the load balancing visible in real time.&lt;/p&gt;
&lt;h2 id="approach"&gt;Approach&lt;/h2&gt;
&lt;p&gt;Each app instance is a lightweight Express server, containerized with Docker and orchestrated via Docker Compose. Nginx sits in front of all three, handling SSL termination and distributing requests using round-robin by default.&lt;/p&gt;
&lt;p&gt;Key areas explored:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reverse proxying&lt;/strong&gt; — configuring Nginx to forward requests to upstream containers by service name over Docker&amp;rsquo;s internal network&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Load balancing algorithms&lt;/strong&gt; — round-robin as the default, with awareness of alternatives like &lt;code&gt;least_conn&lt;/code&gt; and &lt;code&gt;ip_hash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSL/TLS&lt;/strong&gt; — terminating HTTPS at the Nginx layer so upstream apps only deal with plain HTTP internally&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker health checks&lt;/strong&gt; — using &lt;code&gt;wget&lt;/code&gt; to probe each container&amp;rsquo;s &lt;code&gt;/health&lt;/code&gt; endpoint, with configurable interval, timeout, retries, and start period&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Container networking&lt;/strong&gt; — understanding the difference between host-mapped ports and internal container ports, and why health checks use port &lt;code&gt;3000&lt;/code&gt; not &lt;code&gt;3001/3002/3003&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Server-side templating&lt;/strong&gt; — injecting the &lt;code&gt;APP_NAME&lt;/code&gt; environment variable into HTML at request time so the dashboard shows which instance is serving&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="architecture"&gt;Architecture&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[Client / Browser]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [Nginx :443] ← SSL termination + round-robin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; / | \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;App1 App2 App3 ← Node.js containers on internal port 3000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;:3001 :3002 :3003 ← host-mapped for direct debug access
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;Each reload through Nginx cycles to the next upstream instance — visible live on the dashboard.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="health-check-setup"&gt;Health Check Setup&lt;/h2&gt;
&lt;p&gt;Every container runs a health check via Docker Compose:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;healthcheck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;CMD&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;wget&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-qO-&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;http://localhost:3000/health&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;30s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;5s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;start_period&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;/health&lt;/code&gt; endpoint on each app logs every probe hit in memory, which the frontend fetches every 15 seconds via &lt;code&gt;/api/info&lt;/code&gt; to populate the live request log.&lt;/p&gt;
&lt;h2 id="tech-stack"&gt;Tech Stack&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reverse Proxy&lt;/strong&gt;: Nginx 1.28&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;App Runtime&lt;/strong&gt;: Node.js 20 (Alpine)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Framework&lt;/strong&gt;: Express&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Containerization&lt;/strong&gt;: Docker + Docker Compose&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security&lt;/strong&gt;: SSL/TLS with certificate termination at Nginx&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OS&lt;/strong&gt;: Windows + Docker Desktop&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="key-takeaways"&gt;Key Takeaways&lt;/h2&gt;
&lt;p&gt;Building this made abstract networking concepts concrete. Understanding why a health check uses port &lt;code&gt;3000&lt;/code&gt; instead of &lt;code&gt;3001&lt;/code&gt;, why &lt;code&gt;__APP_NAME__&lt;/code&gt; needs server-side injection rather than client-side JS, and why a self-signed cert behaves inconsistently across round-robin rotations — these are the kinds of details that only surface when you actually operate the system yourself.&lt;/p&gt;</description></item><item><title>Personal Portfolio Website</title><link>https://ad25aderram.github.io/my-portfolio/projects/portfolio-website/</link><pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate><guid>https://ad25aderram.github.io/my-portfolio/projects/portfolio-website/</guid><description>&lt;p&gt;A personal portfolio site built from scratch — and a hands-on introduction to the modern developer workflow, from static site generation to automated deployment.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;The goal was simple: have a live portfolio to showcase projects. The outcome was something more valuable — a practical understanding of how modern deployment pipelines actually work, gained by building one myself.&lt;/p&gt;
&lt;h2 id="approach"&gt;Approach&lt;/h2&gt;
&lt;p&gt;The stack centres on &lt;strong&gt;Hugo&lt;/strong&gt; as the static site generator, with &lt;strong&gt;HugoBlox&lt;/strong&gt; for theming and layout configuration. Content is written in Markdown with YAML front matter, and every push to the main branch triggers an automated deployment via &lt;strong&gt;GitHub Actions&lt;/strong&gt; to &lt;strong&gt;GitHub Pages&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Key learning areas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;YAML&lt;/strong&gt; — understanding the syntax, structure, and role of &lt;code&gt;.yml&lt;/code&gt; files in configuring GitHub Actions workflows&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Markdown customisation&lt;/strong&gt; — using front matter to configure pages, projects, and metadata within a static site generator&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Actions&lt;/strong&gt; — writing and reading CI/CD workflows that automate build and deploy steps&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Linux environment&lt;/strong&gt; — setting up and managing the entire development workflow on Arch Linux for the first time&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="architecture"&gt;Architecture&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[Push to main] → [GitHub Actions Trigger]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [Hugo Build Step]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [Deploy to GitHub Pages]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;Every commit kicks off the full build-and-deploy cycle automatically — no manual steps.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="tech-stack"&gt;Tech Stack&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Static Site Generator&lt;/strong&gt;: Hugo + HugoBlox&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deployment&lt;/strong&gt;: GitHub Pages&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automation&lt;/strong&gt;: GitHub Actions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configuration&lt;/strong&gt;: YAML, Markdown&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Environment&lt;/strong&gt;: Arch Linux&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="key-takeaways"&gt;Key Takeaways&lt;/h2&gt;
&lt;p&gt;Sometimes the side-quests are the real learning. Setting up this portfolio introduced version-controlled deployments, declarative configuration, and Linux-native development workflows — all in the context of a project that was genuinely mine to own end to end.&lt;/p&gt;</description></item><item><title>RESTful Task Management API</title><link>https://ad25aderram.github.io/my-portfolio/projects/todo-api/</link><pubDate>Sun, 01 Mar 2026 00:00:00 +0000</pubDate><guid>https://ad25aderram.github.io/my-portfolio/projects/todo-api/</guid><description>&lt;p&gt;A robust backend API for a task management application, designed around clean REST architecture and built to integrate seamlessly with any modern frontend.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;The goal was to build a backend that any frontend — web or mobile — could consume without friction. That means consistent response shapes, clear error messages, and a database schema that won&amp;rsquo;t need restructuring as the app scales.&lt;/p&gt;
&lt;h2 id="key-features"&gt;Key features&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Full CRUD&lt;/strong&gt; — complete HTTP method coverage for task resource lifecycle management&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimised schema&lt;/strong&gt; — PostgreSQL with normalisation and integrity constraints from the start&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Standardised JSON&lt;/strong&gt; — consistent response structure across all endpoints, including errors&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clean code&lt;/strong&gt; — leverages Laravel 12 and PHP 8.4 features for concise, maintainable logic&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="architecture"&gt;Architecture&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Client (Web/Mobile)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Laravel 12 Routes
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Controllers → Form Requests (validation)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Eloquent Models
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PostgreSQL
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="tech-stack"&gt;Tech stack&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Backend&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Laravel 12 (PHP 8.4)&lt;/li&gt;
&lt;li&gt;PostgreSQL (migrations, constraints, normalisation)&lt;/li&gt;
&lt;li&gt;Composer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Tooling&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Postman (endpoint testing &amp;amp; documentation)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="key-takeaways"&gt;Key takeaways&lt;/h2&gt;
&lt;p&gt;This project deepened my understanding of API design — particularly around response consistency, error handling, and building backends that are easy to consume regardless of the frontend technology used.&lt;/p&gt;</description></item><item><title>Pipeline Optimisation with Operations Research</title><link>https://ad25aderram.github.io/my-portfolio/projects/cicd-optimisation/</link><pubDate>Mon, 01 Dec 2025 00:00:00 +0000</pubDate><guid>https://ad25aderram.github.io/my-portfolio/projects/cicd-optimisation/</guid><description>&lt;p&gt;An operations research project that treats a real-world DevOps pipeline as a scheduling problem — applying classical OR methods to reduce deployment time for a critical banking application.&lt;/p&gt;
&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;CI/CD pipelines in high-stakes environments like banking have strict reliability and performance requirements. The challenge was to model the pipeline mathematically and find the minimum possible deployment duration while respecting task dependencies and enabling parallelism where possible.&lt;/p&gt;
&lt;h2 id="approach"&gt;Approach&lt;/h2&gt;
&lt;p&gt;The pipeline was modelled as a &lt;strong&gt;directed acyclic graph (DAG)&lt;/strong&gt; where each node is a pipeline stage and edges represent precedence constraints.&lt;/p&gt;
&lt;p&gt;Methods applied:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kahn&amp;rsquo;s topological sort&lt;/strong&gt; — to establish a valid execution order&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PERT/CPM&lt;/strong&gt; — to compute earliest and latest start dates for each task&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Critical path analysis&lt;/strong&gt; — to identify zero-slack tasks that directly determine total duration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Slack analysis&lt;/strong&gt; — to find where parallelisation opportunities exist&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="results"&gt;Results&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Critical path: 64 minutes&lt;/strong&gt; — the theoretical minimum for a full deployment cycle&lt;/li&gt;
&lt;li&gt;Identified which pipeline stages offered the most optimisation potential&lt;/li&gt;
&lt;li&gt;Produced concrete managerial recommendations for resource prioritisation and risk mitigation&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="architecture-diagram"&gt;Architecture diagram&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[Checkout] → [Build] → [Unit Tests] ─────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↘ ▼
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [Integration Tests] → [Security Scan] → [Deploy]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↗
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [Docker Build] ──────
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;Stages on the critical path have zero slack — any delay directly increases total deployment time.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="tech-stack"&gt;Tech stack&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Language&lt;/strong&gt;: Python&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Methods&lt;/strong&gt;: PERT/CPM, topological sort (Kahn&amp;rsquo;s algorithm), critical path analysis, graph theory&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="key-takeaways"&gt;Key takeaways&lt;/h2&gt;
&lt;p&gt;Operations research techniques that seem purely theoretical deliver actionable insights in modern software engineering — especially where reliability and time-to-market are critical. This project changed how I think about pipeline design.&lt;/p&gt;</description></item><item><title>Advanced Algorithms &amp; Data Structures</title><link>https://ad25aderram.github.io/my-portfolio/projects/advanced-algorithms/</link><pubDate>Sat, 01 Nov 2025 00:00:00 +0000</pubDate><guid>https://ad25aderram.github.io/my-portfolio/projects/advanced-algorithms/</guid><description>&lt;p&gt;A series of algorithm implementations focused on understanding performance trade-offs through experimental analysis. Rather than relying on theoretical Big-O alone, every implementation is benchmarked and visualised against real data.&lt;/p&gt;
&lt;h2 id="sorting--search-complexity"&gt;Sorting &amp;amp; search complexity&lt;/h2&gt;
&lt;p&gt;Seven sorting algorithms benchmarked across four data distributions — random, ascending, descending, and identical values:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Algorithm&lt;/th&gt;
&lt;th&gt;Complexity&lt;/th&gt;
&lt;th&gt;Best case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Quick sort (dual-pivot)&lt;/td&gt;
&lt;td&gt;O(n log n) avg&lt;/td&gt;
&lt;td&gt;Random data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge sort&lt;/td&gt;
&lt;td&gt;O(n log n)&lt;/td&gt;
&lt;td&gt;Consistent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heap sort&lt;/td&gt;
&lt;td&gt;O(n log n)&lt;/td&gt;
&lt;td&gt;Consistent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insertion sort&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;td&gt;Nearly-sorted data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Selection sort&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bubble sort&lt;/td&gt;
&lt;td&gt;O(n²)&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Binary search&lt;/td&gt;
&lt;td&gt;O(log n)&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Runtime was normalised against T(n)/n, T(n)/(n log n), and T(n)/n² to empirically verify complexity classes. Key finding: insertion sort consistently outperforms O(n log n) algorithms on nearly-sorted data — a result that only becomes intuitive when you see it in a plot.&lt;/p&gt;
&lt;h2 id="hash-tables"&gt;Hash tables&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Chaining with linked lists for collision handling&lt;/li&gt;
&lt;li&gt;Open addressing: linear probing, quadratic probing, double hashing&lt;/li&gt;
&lt;li&gt;Benchmarked on datasets up to 100,000 elements — collision rates and lookup times compared across all strategies&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="probabilistic-filters"&gt;Probabilistic filters&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bloom filter&lt;/strong&gt; with k = 2, 3, 4 hash functions — false positive rate vs. memory trade-off&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Count-Min Sketch&lt;/strong&gt; for frequency estimation — precision vs. hash function count&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="string-pattern-matching"&gt;String pattern matching&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Naïve search vs. &lt;strong&gt;deterministic finite automaton (DFA)&lt;/strong&gt; — transition function computation and pattern recognition on randomly generated text&lt;/li&gt;
&lt;li&gt;Performance comparison shows DFA&amp;rsquo;s advantage grows with text length&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="dynamic-programming"&gt;Dynamic programming&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Fibonacci: naïve recursion vs. memoisation — exponential-to-linear improvement demonstrated empirically&lt;/li&gt;
&lt;li&gt;Coin change: minimum coin count with full optimal solution reconstruction&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tech-stack"&gt;Tech stack&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Language&lt;/strong&gt;: Python&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Libraries&lt;/strong&gt;: Matplotlib, NumPy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Focus&lt;/strong&gt;: Algorithm design, complexity analysis, experimental benchmarking&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>COVID-19 Epidemic Modelling (SIRD)</title><link>https://ad25aderram.github.io/my-portfolio/projects/covid-sird/</link><pubDate>Sat, 01 Mar 2025 00:00:00 +0000</pubDate><guid>https://ad25aderram.github.io/my-portfolio/projects/covid-sird/</guid><description>&lt;p&gt;An epidemiological modelling project simulating the spread of COVID-19 in Morocco using the SIRD compartmental model — applied mathematics meeting a real-world public health problem.&lt;/p&gt;
&lt;h2 id="the-model"&gt;The model&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;SIRD model&lt;/strong&gt; divides a population into four compartments evolving over time:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Compartment&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;S&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Susceptible — not yet infected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;I&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Infected — currently infectious&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;R&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Recovered&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;D&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Deceased&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The dynamics are governed by a system of ordinary differential equations:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dS/dt = -β·S·I/N
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dI/dt = β·S·I/N - γ·I - μ·I
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dR/dt = γ·I
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dD/dt = μ·I
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Where β is the transmission rate, γ the recovery rate, and μ the mortality rate.&lt;/p&gt;
&lt;h2 id="my-contribution"&gt;My contribution&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Analysed and implemented the SIRD ODE system&lt;/li&gt;
&lt;li&gt;Solved numerically using SciPy to simulate population evolution over time&lt;/li&gt;
&lt;li&gt;Tuned β, γ, and μ parameters against observed Moroccan COVID-19 data&lt;/li&gt;
&lt;li&gt;Visualised S, I, R, D curves and interpreted dynamics — peak infection timing, convergence behaviour, and sensitivity to β changes&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="key-finding"&gt;Key finding&lt;/h2&gt;
&lt;p&gt;A small change in the transmission rate β shifts the infection peak by weeks — a concrete illustration of why epidemic modelling matters for policy decisions, and why early intervention has outsized impact.&lt;/p&gt;
&lt;h2 id="tech-stack"&gt;Tech stack&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Language&lt;/strong&gt;: Python&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Libraries&lt;/strong&gt;: NumPy, SciPy (ODE solving), Matplotlib (visualisation)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Focus&lt;/strong&gt;: Applied mathematics, numerical methods, data visualisation&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>