<?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: John Otienoh </title>
    <description>The latest articles on DEV Community by John Otienoh  (@john_otienoh).</description>
    <link>https://dev.to/john_otienoh</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%2F1246073%2F19376601-27b0-4298-acef-43a2b16411ef.jpg</url>
      <title>DEV Community: John Otienoh </title>
      <link>https://dev.to/john_otienoh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/john_otienoh"/>
    <language>en</language>
    <item>
      <title>My AI habit Tracker</title>
      <dc:creator>John Otienoh </dc:creator>
      <pubDate>Mon, 03 Nov 2025 12:12:55 +0000</pubDate>
      <link>https://dev.to/john_otienoh/my-ai-habit-tracker-1l8j</link>
      <guid>https://dev.to/john_otienoh/my-ai-habit-tracker-1l8j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Build an intelligent agent, connect it to Telex.im, and make it do something genuinely useful.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I wanted to create something that combined &lt;strong&gt;productivity and motivation&lt;/strong&gt; — something that helps users stay consistent while adding an element of positivity every time they interact with it. That’s how I came up with the &lt;strong&gt;Motivational Habit Tracker AI Agent&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Concept
&lt;/h2&gt;

&lt;p&gt;The idea is simple but meaningful:&lt;br&gt;
Users can create and manage habits (like “read 10 pages” or “exercise daily”), and each time they check their progress, they receive a &lt;strong&gt;motivational quote&lt;/strong&gt; fetched from the &lt;strong&gt;ZenQuotes API&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The AI assistant doesn’t just track what you do — it reminds you &lt;em&gt;why&lt;/em&gt; you do it.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧩 Architecture Overview
&lt;/h2&gt;

&lt;p&gt;The project is structured as a lightweight &lt;strong&gt;FastAPI&lt;/strong&gt; backend powered by &lt;strong&gt;SQLite&lt;/strong&gt; and connected to &lt;strong&gt;Telex.im&lt;/strong&gt; via a JSON-RPC (A2A) API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FastAPI App
 ┣━━ ai_helper.py         → Fetches motivational quotes (AI agent logic)
 ┣━━ database.py          → Handles SQLite database (habits, timestamps)
 ┣━━ habit_manager.py     → Business logic layer for CRUD + quotes
 ┗━━ main.py              → REST and JSON-RPC endpoints for Telex integration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each component has a focused responsibility — helping keep the project simple, modular, and easy to maintain.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Why I Chose FastAPI
&lt;/h2&gt;

&lt;p&gt;The original version of this project was written in &lt;strong&gt;Flask&lt;/strong&gt;, but I decided to refactor it into &lt;strong&gt;FastAPI&lt;/strong&gt; for several reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Asynchronous Support&lt;/strong&gt; – Perfect for APIs that fetch external data like quotes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic Documentation&lt;/strong&gt; – FastAPI generates Swagger and ReDoc docs instantly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern Syntax&lt;/strong&gt; – Type hints, Pydantic validation, and async endpoints make the code cleaner and more reliable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better Performance&lt;/strong&gt; – FastAPI is built on Starlette and Uvicorn, which are lightweight and fast.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🧠 AI Integration (ZenQuotes API)
&lt;/h2&gt;

&lt;p&gt;For motivation, I integrated the &lt;strong&gt;ZenQuotes API&lt;/strong&gt;, which provides a random inspirational quote on each call.&lt;/p&gt;

&lt;p&gt;Here’s the core logic from &lt;code&gt;ai_helper.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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_motivational_quote&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;try&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;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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://zenquotes.io/api/random&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;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="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;data&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="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; - &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;💡 Keep going — small, consistent steps lead to big change!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the API is unreachable, the system gracefully falls back to a default motivational message.&lt;/p&gt;




&lt;h2&gt;
  
  
  🗃️ Data Model
&lt;/h2&gt;

&lt;p&gt;SQLite was a natural choice for simplicity.&lt;br&gt;
Each user has multiple habits stored in a table with frequency and timestamps:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;username&lt;/th&gt;
&lt;th&gt;habit&lt;/th&gt;
&lt;th&gt;frequency&lt;/th&gt;
&lt;th&gt;created_at&lt;/th&gt;
&lt;th&gt;last_done&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The backend automatically determines when a habit is &lt;em&gt;due&lt;/em&gt; based on frequency (daily, weekly, etc.) and adds reminders accordingly.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧩 Telex Integration (A2A JSON-RPC)
&lt;/h2&gt;

&lt;p&gt;Telex.im uses a &lt;strong&gt;JSON-RPC 2.0&lt;/strong&gt; protocol for agents.&lt;br&gt;
I implemented an &lt;code&gt;/a2a/habits&lt;/code&gt; endpoint that accepts structured messages like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jsonrpc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"habits/get"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&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="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"john"&lt;/span&gt;&lt;span class="w"&gt; &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="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent responds with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jsonrpc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"result"&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="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"habits"&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="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"motivational_quote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Action is the foundational key to all success.&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; - Pablo Picasso"&lt;/span&gt;&lt;span class="w"&gt;
  &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="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;habits/get&lt;/code&gt; → View habits&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;habits/add&lt;/code&gt; → Add a new habit&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;habits/mark_done&lt;/code&gt; → Mark a habit as complete&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes the agent easy to integrate with Telex.im or any client that supports JSON-RPC.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 Thought Process &amp;amp; Design Decisions
&lt;/h2&gt;

&lt;p&gt;Here’s how I approached the project step by step:&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Simplicity First
&lt;/h3&gt;

&lt;p&gt;I started with a small, clear goal — track habits and return motivational quotes. The simpler the core logic, the easier it is to expand later.&lt;/p&gt;

&lt;h3&gt;
  
  
  2️⃣ Separation of Concerns
&lt;/h3&gt;

&lt;p&gt;I divided the code into modules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;database.py&lt;/code&gt; for persistence&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;habit_manager.py&lt;/code&gt; for core logic&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ai_helper.py&lt;/code&gt; for AI tasks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;main.py&lt;/code&gt; for API routes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This made debugging and testing straightforward.&lt;/p&gt;

&lt;h3&gt;
  
  
  3️⃣ User Experience as a Priority
&lt;/h3&gt;

&lt;p&gt;Each API response includes a motivational quote, even when users just check their habits.&lt;br&gt;
This transforms the backend into something &lt;em&gt;encouraging&lt;/em&gt; — not just functional.&lt;/p&gt;
&lt;h3&gt;
  
  
  4️⃣ Error Handling and Validation
&lt;/h3&gt;

&lt;p&gt;All endpoints validate JSON-RPC format, parameters, and catch exceptions gracefully.&lt;br&gt;
Invalid requests return clear error messages instead of crashing the service.&lt;/p&gt;


&lt;h2&gt;
  
  
  ⚡ Example Usage
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;POST&lt;/strong&gt; &lt;code&gt;/habits/john&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"habit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Exercise"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"frequency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"daily"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;GET&lt;/strong&gt; &lt;code&gt;/habits/john&lt;/code&gt;&lt;br&gt;
Returns all habits with reminders and a motivational quote.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;POST&lt;/strong&gt; &lt;code&gt;/a2a/habits&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"jsonrpc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"habits/mark_done"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&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="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"john"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"habit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Exercise"&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="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🌍 Deployment
&lt;/h2&gt;

&lt;p&gt;The app runs seamlessly on &lt;strong&gt;Railway&lt;/strong&gt;, &lt;strong&gt;Render&lt;/strong&gt;, or &lt;strong&gt;Fly.io&lt;/strong&gt; using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;web: uvicorn main:app &lt;span class="nt"&gt;--host&lt;/span&gt; 0.0.0.0 &lt;span class="nt"&gt;--port&lt;/span&gt; &lt;span class="nv"&gt;$PORT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  💭 Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Building an “AI Agent” isn’t just about complex models — even a motivational quote generator can add emotional intelligence.&lt;/li&gt;
&lt;li&gt;FastAPI made development fast, intuitive, and well-documented.&lt;/li&gt;
&lt;li&gt;Clean architecture (small, focused modules) saved time debugging and made testing easier.&lt;/li&gt;
&lt;li&gt;Integrating JSON-RPC taught me how structured communication between agents works.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 What’s Next
&lt;/h2&gt;

&lt;p&gt;Future improvements could include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User authentication (JWT)&lt;/li&gt;
&lt;li&gt;Tracking streaks or progress percentage&lt;/li&gt;
&lt;li&gt;A web dashboard built with Vue or React&lt;/li&gt;
&lt;li&gt;Integration with a real AI model for personalized motivational feedback&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏁 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This project was a great exercise in &lt;strong&gt;combining backend logic, AI integration, and human-centered design&lt;/strong&gt;.&lt;br&gt;
It reminded me that small touches — like a random quote — can make digital tools feel alive and supportive.&lt;/p&gt;

&lt;p&gt;If you’d like to try it or explore the source, check out the GitHub repo and connect with me on Telex.im!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Discipline is choosing between what you want now and what you want most.”&lt;/em&gt;&lt;br&gt;
— Abraham Lincoln&lt;/p&gt;
&lt;/blockquote&gt;




</description>
      <category>showdev</category>
      <category>ai</category>
      <category>productivity</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Me-API</title>
      <dc:creator>John Otienoh </dc:creator>
      <pubDate>Fri, 17 Oct 2025 13:04:10 +0000</pubDate>
      <link>https://dev.to/john_otienoh/me-api-13mk</link>
      <guid>https://dev.to/john_otienoh/me-api-13mk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Simple RESTful API endpoint that returns your profile information along with a dynamic cat fact fetched from an external API.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;As part of the HNG Internship Backend track Stage 0 Task, I was challenged to build a simple yet dynamic RESTful API that returns my profile details along with a live cat fact fetched from the Cat Facts API.&lt;br&gt;
This task has helped me sharpen key backend development concepts — from API integration, response structuring, time formatting, to error handling and deployment.&lt;/p&gt;
&lt;h2&gt;
  
  
  Task Requirements
&lt;/h2&gt;

&lt;p&gt;The goal was to create a &lt;code&gt;GET /me&lt;/code&gt; endpoint that returns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"user"&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="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"johndoe@gmail.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"stack"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Python/FastAPI"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-10-17T12:34:56.789Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fact"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Cats sleep for 70% of their lives."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;p&gt;The cat fact must come dynamically from the &lt;a href="https://catfact.ninja/fact" rel="noopener noreferrer"&gt;public API&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools &amp;amp; Technologies
&lt;/h2&gt;

&lt;p&gt;Framework: FastAPI&lt;br&gt;
Language: Python 3&lt;br&gt;
Deployment Platform: Railway&lt;/p&gt;
&lt;h2&gt;
  
  
  My Implementation Process
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;- Project Setup&lt;/strong&gt;&lt;br&gt;
I created a new FastAPI project and installed dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install fastapi uvicorn requests python-dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;- Defined Schema with Pydantic.&lt;/strong&gt;&lt;br&gt;
To maintain clean and validated responses, I created a schema.py:&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EmailStr&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Model for the response&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EmailStr&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&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="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
    &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;
    &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;- Get cat facts&lt;/strong&gt;&lt;br&gt;
To get the cat facts from the &lt;a href="https://catfact.ninja/fact" rel="noopener noreferrer"&gt;Cat Fact API&lt;/a&gt;, i created the catfact.py&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="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;cat_fact&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="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;try&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;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;timeout&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raise_for_status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;response_dict&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="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;fact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response_dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fact&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Could not fetch cat fact at this time.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;-  Built the &lt;code&gt;/me&lt;/code&gt; Endpoint&lt;/strong&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="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi.middleware.cors&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CORSMiddleware&lt;/span&gt; 

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;app.schema&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Profile&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;app.catfact&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cat_fact&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&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://catfact.ninja/fact&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;origins&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;*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;CORSMiddleware&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;allow_origins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;origins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;allow_credentials&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;allow_methods&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;*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;allow_headers&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;*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;



&lt;span class="n"&gt;my_info&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;Success&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;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&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;johnteclaire@gmail.com&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;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;John Charles Otienoh&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;stack&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;Python/fastAPI&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;timestamp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fact&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="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/me&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response_model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Profile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_my_info&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Retreive Basic information&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;my_info&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;fact&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cat_fact&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;my_info&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;- Tested the API&lt;/strong&gt;&lt;br&gt;
I used cURL to test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8000/me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API returned a live cat fact and a real-time timestamp every request!&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;How to consume external APIs safely using requests&lt;/li&gt;
&lt;li&gt;How to handle timeouts, errors, and fallbacks&lt;/li&gt;
&lt;li&gt;How to return structured JSON with Pydantic models&lt;/li&gt;
&lt;li&gt;The importance of clean documentation and response validation&lt;/li&gt;
&lt;li&gt;How to think about API reliability and best practices (timeouts, CORS, content-type headers, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Repo: &lt;a href="https://github.com/john-otienoh/Me_API" rel="noopener noreferrer"&gt;https://github.com/john-otienoh/Me_API&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Live API: &lt;a href="https://meapi-production.up.railway.app/me" rel="noopener noreferrer"&gt;https://meapi-production.up.railway.app/me&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Contact: &lt;a href="mailto:johnteclaire@gmail.com"&gt;johnteclaire@gmail.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>fastapi</category>
      <category>backend</category>
      <category>api</category>
      <category>python</category>
    </item>
    <item>
      <title>Recursion</title>
      <dc:creator>John Otienoh </dc:creator>
      <pubDate>Fri, 17 Oct 2025 12:37:13 +0000</pubDate>
      <link>https://dev.to/john_otienoh/recursion-61l</link>
      <guid>https://dev.to/john_otienoh/recursion-61l</guid>
      <description>&lt;p&gt;What is Recursion?&lt;br&gt;
Any function which calls itself is called recursive. A recursive method solves a problem by calling a copy of itself to work on a smaller problem. This is called the recursion step.The recursion step can result in many more such recursive calls.&lt;br&gt;
It is useful in sort, search, and traversal problems that often have simple recursive solutions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Syntax
&lt;/h4&gt;

</description>
      <category>datastructures</category>
      <category>recursion</category>
      <category>algorithms</category>
      <category>programming</category>
    </item>
    <item>
      <title>A beginner's guide to data engineering concepts, tools, and responsibilities.</title>
      <dc:creator>John Otienoh </dc:creator>
      <pubDate>Mon, 05 Aug 2024 11:34:31 +0000</pubDate>
      <link>https://dev.to/john_otienoh/a-beginners-guide-to-data-engineering-concepts-tools-and-responsibilities-3pd</link>
      <guid>https://dev.to/john_otienoh/a-beginners-guide-to-data-engineering-concepts-tools-and-responsibilities-3pd</guid>
      <description>&lt;h2&gt;
  
  
  Data Engineering Concepts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqbiuh1bhd7vsto7mdclc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqbiuh1bhd7vsto7mdclc.png" alt="Image description" width="720" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Data engineering is the process of designing, building, and maintaining the infrastructure for storing, processing, and retrieving large datasets. It involves creating systems that efficiently collect, transform, and store data, making it usable for analysis and decision-making.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools for data engineers.
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Scripting and programming language:&lt;/em&gt; python is the commonly used language in data engineering due to its simplicity and extensive libraries , which is used in transformation and data cleaning. There are other languages that are used such as ruby, Scala among others.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Databases&lt;/em&gt;: data engineers use various databases like MySQL to store and manage structured data for analytics and reporting.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Data visualization tools:&lt;/em&gt; to gain insights and patterns from data, a data engineer should be familiar with various tools used in visualization such as tableau and Power BI.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Data warehousing and storage tools:&lt;/em&gt; the commonly used tool in managing data is snowflake, snowflake is a cloud data warehouse that allow one to store and manage data, snowflake is very flexible since it works with some programming languages such as python&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Responsibilities:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Designing data pipelines to collect and process data from various sources&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Developing data warehouses and lakes to store structured and unstructured data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensuring data quality, integrity, and security.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Building scalable and high-performance data processing systems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Collaborating with data scientists and analysts to understand their data needs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implementing data governance policies and metadata management.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dataengineering</category>
      <category>data</category>
      <category>datascience</category>
    </item>
    <item>
      <title>POST-MORTEM</title>
      <dc:creator>John Otienoh </dc:creator>
      <pubDate>Fri, 28 Jun 2024 20:05:58 +0000</pubDate>
      <link>https://dev.to/john_otienoh/post-mortem-3838</link>
      <guid>https://dev.to/john_otienoh/post-mortem-3838</guid>
      <description>&lt;h1&gt;
  
  
  Database Connection
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia1.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExeXNlenIwa291dTBtd3p4ZTZpaDEzbXdxMnd6NmkzdXF3dnJwM2RoMiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2F6boXVnFugfXzY3wWPU%2Fgiphy.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia1.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExeXNlenIwa291dTBtd3p4ZTZpaDEzbXdxMnd6NmkzdXF3dnJwM2RoMiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2F6boXVnFugfXzY3wWPU%2Fgiphy.webp" alt="worried"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Issue Summary
&lt;/h2&gt;

&lt;p&gt;Duration: 2 hours 55 minutes (14:55 UTC - 17:50 UTC).&lt;br&gt;
The affected service was the website's search functionality leading to  20% of users experienced slow load times, with average page load times increasing by 7 seconds.&lt;br&gt;
The root Cause was a misconfigured database connection pooling leading to connection timeouts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Timeline
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;14:55 UTC: Monitoring alerts triggered for high response times on the search functionality.&lt;/li&gt;
&lt;li&gt;15:00 UTC: Engineer on call investigates and notices high CPU usage on the database server.&lt;/li&gt;
&lt;li&gt;15:10 UTC: Initial assumption is that the issue is related to a recent code deployment, and the team begins reviewing code changes.&lt;/li&gt;
&lt;li&gt;15:20 UTC: Investigation reveals no issues with the code deployment, and attention turns to the database server.&lt;/li&gt;
&lt;li&gt;15:40 UTC: Misleading investigation path: The team explores the possibility of a database query optimization issue.&lt;/li&gt;
&lt;li&gt;16:00 UTC: Escalation to the database administration team.&lt;/li&gt;
&lt;li&gt;16:20 UTC: Root cause identified: misconfigured database connection pooling.&lt;/li&gt;
&lt;li&gt;16:55 UTC: Configuration changes made to the database connection pooling.&lt;/li&gt;
&lt;li&gt;17:50 UTC: Issue resolved, page load times return to normal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjohn-otienoh%2Falx-system_engineering-devops%2Fassets%2F125456275%2F3f92baad-5abc-40d0-a118-13c2bb3485c7" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjohn-otienoh%2Falx-system_engineering-devops%2Fassets%2F125456275%2F3f92baad-5abc-40d0-a118-13c2bb3485c7" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Root Cause and Resolution
&lt;/h2&gt;

&lt;p&gt;The root cause of the issue was a misconfigured database connection pooling setting, which led to connection timeouts and increased CPU usage on the database server. This caused slow load times for 20% of users, affecting the website's search functionality.&lt;br&gt;
The issue was resolved by adjusting the database connection pooling settings to optimize connection reuse and reduce timeouts. This change was made in collaboration with the database administration team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Corrective and Preventative Measures
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Improve database connection pooling configuration and monitoring.&lt;/li&gt;
&lt;li&gt;Implement automated testing for database connection pooling settings.&lt;/li&gt;
&lt;li&gt;Enhance monitoring for CPU usage on the database server.&lt;/li&gt;
&lt;li&gt;Conduct regular reviews of database server performance and configuration.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fjohn-otienoh%2Falx-system_engineering-devops%2Fassets%2F125456275%2Fae541613-59b1-4f5d-a49d-4fcace75e5b2" alt="image"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  TODO List
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Patch database connection pooling configuration to optimize connection reuse.&lt;/li&gt;
&lt;li&gt;Add monitoring for database connection timeouts.&lt;/li&gt;
&lt;li&gt;Implement automated testing for database connection pooling settings.&lt;/li&gt;
&lt;li&gt;Schedule regular database server performance reviews.&lt;/li&gt;
&lt;li&gt;Develop a playbook for troubleshooting database connection issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This postmortem highlights the importance of thorough investigation and collaboration between teams to resolve complex issues. By identifying and addressing the root cause of the problem, we can prevent similar issues from occurring in the future and improve the overall reliability of our services.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>0x00. Shell, navigation</title>
      <dc:creator>John Otienoh </dc:creator>
      <pubDate>Sat, 08 Jun 2024 22:42:29 +0000</pubDate>
      <link>https://dev.to/john_otienoh/0x00-shell-navigation-3jpb</link>
      <guid>https://dev.to/john_otienoh/0x00-shell-navigation-3jpb</guid>
      <description>&lt;h2&gt;
  
  
  File System Organization
&lt;/h2&gt;

&lt;p&gt;Like Windows, the files on a Linux system are arranged in what is called a hierarchical directory structure. This means that they are organized in a tree-like pattern of directories (called folders in other systems), which may contain files and subdirectories. The first directory in the file system is called the root directory. The root directory contains files and subdirectories, which contain more files and subdirectories and so on and so on.&lt;br&gt;
The basic three commands include: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;pwd&lt;/strong&gt; (print working directory)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;cd&lt;/strong&gt; (change directory)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ls&lt;/strong&gt; (list files and directories).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  pwd
&lt;/h3&gt;

&lt;p&gt;The directory we are standing in is called the working directory. To see the name of the working directory, we use the pwd command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[me@linuxbox me]$ pwd
/home/me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we first log on to our Linux system, the working directory is set to our home directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  cd
&lt;/h3&gt;

&lt;p&gt;To change the working directory (where we are standing in the maze) we use the cd command. To do this, we type cd followed by the pathname of the desired working directory. A pathname is the route we take along the branches of the tree to get to the directory we want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;me@linuxbox me]$ cd /usr/bin
me@linuxbox bin]$ pwd
/usr/bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we type &lt;code&gt;cd&lt;/code&gt; followed by nothing, cd will change the working directory to our home directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;me@linuxbox me]$ cd
me@linuxbox bin]$ pwd
/home/me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A related shortcut is to type &lt;code&gt;cd ~user_name&lt;/code&gt;. In this case, cd will change the working directory to the home directory of the specified user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;me@linuxbox me]$ cd ~me
me@linuxbox bin]$ pwd
/home/me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Typing &lt;code&gt;cd -&lt;/code&gt; or &lt;code&gt;cd ..&lt;/code&gt; changes the working directory to the previous one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;me@linuxbox me]$ cd /usr/bin
me@linuxbox bin]$ pwd
/usr/bin
me@linuxbox me]$ cd ..
me@linuxbox bin]$ pwd
/usr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ls
&lt;/h3&gt;

&lt;p&gt;It is used to list the files in the current working directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[me@linuxbox me]$ ls
Desktop   Download  Pictures  Music  Templates  Documents examples.desktop    Public  Videos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;File names that begin with a period character are hidden. This only means that ls will not list them unless we say &lt;code&gt;ls -a&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;[me@linuxbox me]$ ls -la
.git/    .ssh/   .ipython/ Desktop   Download  Pictures  Music  Templates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ls -l&lt;/code&gt;List the files in the working directory in long format&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[me@linuxbox me]$ ls -l
drwxr-xr-x 1 me 197121  0 Oct 17  2023  OneDrive/
drwxr-xr-x 1 me 197121  0 Jan 17  2023  Pictures/
drwxr-xr-x 1 me 197121  0 Mar  3  2023  Saved Games/
drwxr-xr-x 1 me 197121  0 Apr 27  2023  Searches/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Displaying file contents
&lt;/h3&gt;

&lt;p&gt;There are several commands to display the content of a file in Linux.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using &lt;code&gt;cat&lt;/code&gt; command
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cat filename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Using &lt;code&gt;head&lt;/code&gt; and &lt;code&gt;tail&lt;/code&gt; commands&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;head&lt;/code&gt; command displays the first 10 lines of a file, while the &lt;code&gt;tail&lt;/code&gt; command displays the last 10 lines of a file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ head filename   # displays the first 10 lines of a file
$ tail filename   # displays the last 10 lines of a file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can modify the number of lines displayed by using the &lt;code&gt;-n&lt;/code&gt; option, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ head -n 5 filename   # displays the first 5 lines of a file
$ tail -n 5 filename   # displays the last 5 lines of a file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Using &lt;code&gt;less&lt;/code&gt; command&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;less&lt;/code&gt; command allows you to view a file one page at a time. It allows you navigate through the file using the arrow keys or page up/down keys.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ less filename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Using &lt;code&gt;awk&lt;/code&gt; command&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This command uses &lt;code&gt;awk&lt;/code&gt; to print each line of the file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ awk '1' filename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating files and directories
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Create a file:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using the &lt;code&gt;touch&lt;/code&gt; command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ touch filename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a new empty file with the specified name.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using a text editor:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ nano filename # using the nano editor.
$ vi filename # using vim editor.
$ code filename # using vscode editor.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will open a text editor where you can create and edit the file. Once you're done, save and exit the editor.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using the &lt;code&gt;echo&lt;/code&gt; command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ echo "Hello World!" &amp;gt; filename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a new file with the specified name and add the text "Hello World!" to it.&lt;br&gt;
&lt;strong&gt;Create a directory:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using the &lt;code&gt;mkdir&lt;/code&gt; command:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir directoryname
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will create a new directory with the specified name.&lt;/p&gt;
&lt;h3&gt;
  
  
  Removing a file or directory
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Removing a file:&lt;/strong&gt;&lt;br&gt;
To remove a file, use the &lt;code&gt;rm&lt;/code&gt; command followed by the name of the file you want to remove:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rm filename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the file is write-protected, &lt;code&gt;rm&lt;/code&gt; will ask you to confirm the deletion. To remove the file without prompting, use the &lt;code&gt;-f&lt;/code&gt; option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rm -f filename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Removing a directory:&lt;/strong&gt;&lt;br&gt;
To remove an empty directory, use the &lt;code&gt;rmdir&lt;/code&gt; command followed by the name of the directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rmdir directoryname
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the directory is not empty, you will get an error message. To remove a non-empty directory and all its contents, use the &lt;code&gt;rm&lt;/code&gt; command with the &lt;code&gt;-r&lt;/code&gt; option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rm -r directoryname
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Moving or Copying a file or directory
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Moving a file or directory:&lt;/strong&gt;&lt;br&gt;
To move a file or directory, use the &lt;code&gt;mv&lt;/code&gt; command followed by the source file or directory and the destination:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mv source destination
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Renaming a file or directory:&lt;/strong&gt;&lt;br&gt;
To rename a file or directory, use the &lt;code&gt;mv&lt;/code&gt; command with the source file or directory and the new name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mv oldname newname
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Copying a file or directory:&lt;/strong&gt;&lt;br&gt;
To copy a file or directory, use the cp command followed by the source file or directory and the destination:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cp source destination
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To copy a directory and all its contents, use the &lt;code&gt;-r&lt;/code&gt; option with the cp command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cp -r source destination
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will copy the entire directory source and all its contents to destination.&lt;br&gt;
&lt;strong&gt;Using &lt;code&gt;rsync&lt;/code&gt; command:&lt;/strong&gt;&lt;br&gt;
The &lt;code&gt;rsync&lt;/code&gt; command is a powerful tool for copying and synchronizing files and directories. It can be used to copy files and directories while preserving permissions, timestamps, and other attributes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rsync -avz sourceDir destinationDir
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will copy the entire directory sourceDir and all its contents to the specified destination, preserving permissions, timestamps, and other attributes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for your time! Please leave a comment and any suggestions are welcome. Follow me to get updates.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>shell</category>
      <category>bash</category>
      <category>softwareengineering</category>
      <category>alxsoftwareengineering</category>
    </item>
    <item>
      <title>Variables in Python</title>
      <dc:creator>John Otienoh </dc:creator>
      <pubDate>Mon, 01 Jan 2024 20:04:50 +0000</pubDate>
      <link>https://dev.to/john_otienoh/variables-in-python-4n3l</link>
      <guid>https://dev.to/john_otienoh/variables-in-python-4n3l</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Variables&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I have a value where do i store it in my computer?&lt;br&gt;
Well that's where variables come handy.&lt;br&gt;
Variables refer to&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A location in the memory that are reserved to store the values of my code&lt;/li&gt;
&lt;li&gt;A container that holds one value and has a label on it.
From our definition we can visualise a variable as a gift box with similar characteristics like a container-like, has a label, stores something etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Syntax for declaring a variable in python is:&lt;br&gt;
'variable_name' 'assignment operator' 'value'&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="n"&gt;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;john&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
    &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Variables in python have a specific naming convention.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use snake_case or CamelCase naming convention. 
e.g my_name, MyName.&lt;/li&gt;
&lt;li&gt;Variable name can only contain alphanumeric character and underscores [A - Z, 0 - 9 and _].&lt;/li&gt;
&lt;li&gt;Variable name starts with a letter or the underscore character.
e.g _name = 'john' or name = 'john'&lt;/li&gt;
&lt;li&gt;Variable name should not be a keyword.
e.g in, for, while etc.&lt;/li&gt;
&lt;li&gt;Variable names should meaningful.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If a variable is defined(assigned a value) , trying to use it will give us specifically a NameError.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiple assignment in a single line
&lt;/h2&gt;

&lt;p&gt;Supposed we want to define numerous variables using single line of code, we can do it by separating variable names and values with commas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alphabet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The line above is similar to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alphabet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Variables are key components for any programming language.&lt;/p&gt;

</description>
      <category>python</category>
      <category>codenewbie</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
