<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Daniel Hashmi on Medium]]></title>
        <description><![CDATA[Stories by Daniel Hashmi on Medium]]></description>
        <link>https://medium.com/@danielhashmi?source=rss-54f99fe76131------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*9viyCfpOTGASQozJRJsY1A.png</url>
            <title>Stories by Daniel Hashmi on Medium</title>
            <link>https://medium.com/@danielhashmi?source=rss-54f99fe76131------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 27 May 2026 04:17:03 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@danielhashmi/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[ Building AI-Powered APIs with FastAPI and OpenAI Agents SDK: Deployment on Hugging Face]]></title>
            <link>https://blog.devgenius.io/building-ai-powered-apis-with-fastapi-and-openai-agents-sdk-deployment-on-hugging-face-2ce34d3eb766?source=rss-54f99fe76131------2</link>
            <guid isPermaLink="false">https://medium.com/p/2ce34d3eb766</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[fastapi]]></category>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[hugging-face]]></category>
            <category><![CDATA[openai-agents-sdk]]></category>
            <dc:creator><![CDATA[Daniel Hashmi]]></dc:creator>
            <pubDate>Mon, 19 Jan 2026 15:09:46 GMT</pubDate>
            <atom:updated>2026-01-21T06:58:46.711Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HUq9JZO3JB4sx9QL8mP8ZA.png" /><figcaption>Fast API Deployment on Hugging Face</figcaption></figure><h3>What We’re Building</h3><p>This project is a ready FastAPI server that integrates OpenAI’s Agents SDK with Groq’s free high-performance models.</p><p>Here’s what you’ll get:</p><p>✅ AI-Powered Chat Endpoint — Send messages and get intelligent responses<br>✅ Multiple Tools — Weather lookup and mathematical calculations<br>✅ Streaming Support — Real-time response streaming for better UX<br>✅ Docker Ready — Containerized for instant cloud deployment<br>✅ CORS Enabled — Works seamlessly with any frontend<br>✅ Health Checks — Built-in monitoring endpoints</p><h3>Part 1: Prerequisites &amp; Setup</h3><p>Before we start, gather these three essentials:</p><h3>1. Create a Hugging Face Account</h3><p>Head to <a href="https://huggingface.co/join">huggingface.co/join</a> and sign up. This is where we’ll deploy our Space (basically a free container for our app).</p><h3>2. Get a Groq API Key</h3><p>Visit <a href="https://console.groq.com/keys">console.groq.com/keys</a> and create an API key. Groq provides fast, free access to LLMs like LLAMA 3 and GPT OSS. Copy this key, you’ll need it later.</p><h3>3. Generate a Hugging Face Access Token</h3><p>This is crucial for pushing code to Hugging Face Spaces:</p><ul><li>Go to Settings → <a href="https://huggingface.co/settings/tokens">Access Tokens</a></li><li>Click “Create new token”</li><li>Name it spaces-deploy</li><li>Select “Write” permissions</li><li>Click “Create token” and copy it immediately (you’ll use it as your password)</li></ul><blockquote><em>⚠️ Important: Never use your Hugging Face login password for Git authentication. Always use the Access Token.</em></blockquote><h3>Part 2: Creating Your Hugging Face Space</h3><h3>Step 1: Initialize Your Space</h3><ol><li>Navigate to <a href="https://huggingface.co/new-space">huggingface.co/new-space</a></li><li>Fill in the form:</li></ol><ul><li>Space Name: fastapi-agents (or your preferred name)</li><li>License: MIT</li><li>SDK: Select Docker (important!)</li><li>Space Hardware: CPU Basic (free tier is perfect for this)</li><li>Click “Create Space”</li></ul><p>You’ll be redirected to your new Space page, which initially is empty. That’s fine, we’ll populate it next.</p><h3>Part 3: Deploying Your Code</h3><p>You have two options: CLI (recommended for developers) or Web UI (easiest).</p><h3>Option A: Command Line (Recommended)</h3><p>This is the developer-friendly approach. Open your terminal and run these commands in the project folder:</p><p>Initialize Git:</p><pre>git init<br>git checkout -B main<br>git add .<br>git config --global user.email &quot;you@example.com&quot;<br>git config --global user.name &quot;Your Name&quot;<br>git commit -m &quot;Initial deploy&quot;</pre><p>Add the Hugging Face Remote:</p><p>Look at your Space’s URL. It should look like:</p><p><a href="https://huggingface.co/spaces/YOUR_USERNAME/fastapi-agents">https://huggingface.co/spaces/YOUR_USERNAME/fastapi-agents</a></p><p>Now run:</p><p>git remote add space <a href="https://huggingface.co/spaces/YOUR_USERNAME/fastapi-agents">https://huggingface.co/spaces/YOUR_USERNAME/fastapi-agents</a></p><p>Push Your Code:</p><p>git push --force space main</p><p>When prompted:</p><ul><li>Username: Your Hugging Face username</li><li>Password: Paste the Access Token you created earlier (NOT your password)</li></ul><p>That’s it! Your code is now in Hugging Face Spaces.</p><h3>Option B: Web UI (No Git Required)</h3><p>If you’re not comfortable with Git:</p><ol><li>Go to your Space’s “Files” tab</li><li>Click “Add file” → “Upload files”</li><li>Drag and drop these files:</li></ol><ul><li>Dockerfile</li><li>main.py</li><li>pyproject.toml</li><li>uv.lock</li><li>.env.example</li><li>In the commit message, type “Initial deploy”</li><li>Click “Commit changes to main”</li></ul><blockquote><em>Note: Skip </em><em>.env, </em><em>.git, and </em><em>__pycache__ folders.</em></blockquote><h3>Part 4: Configuring Environment Variables</h3><p>Your app needs the Groq API key to run.</p><p>Here’s how to add it:</p><ol><li>Go to your Space’s “Settings” tab</li><li>Scroll down to “Variables and secrets”</li><li>Click “New secret” (top-right of that section)</li><li>Enter:</li></ol><ul><li>Name: GROQ_API_KEY</li><li>Value: Your Groq API key (starts with gsk_... )</li><li>Click “Save”</li></ul><p>Your Space will automatically restart and rebuild. This usually takes 2–3 minutes.</p><h3>Part 5: Verifying Your Deployment</h3><p>Once the build completes:</p><ol><li>Click the “App” tab</li><li>You should see this JSON response:</li></ol><pre>{<br>  &quot;name&quot;: &quot;FastAPI + OpenAI Agents SDK&quot;,<br>  &quot;version&quot;: &quot;1.0.0&quot;,<br>  &quot;endpoints&quot;: {<br>    &quot;POST /chat&quot;: &quot;Send a message to the agent&quot;,<br>    &quot;GET /health&quot;: &quot;Health check&quot;<br>  }<br>}</pre><p>If something went wrong:</p><ul><li>Click the “Logs” button to see error messages</li><li>Most common issue: Missing or invalid GROQ_API_KEY</li></ul><h3>Part 6: Using Your API</h3><p>Once deployed, your API is live at:</p><p>https://YOUR_USERNAME-fastapi-agents.hf. space</p><h3>Testing with Swagger UI</h3><p>The easiest way to test:</p><ol><li>Visit: <a href="https://YOUR_USERNAME-fastapi-agents.hf.space/docs">https://YOUR_USERNAME-fastapi-agents.hf.space/docs</a></li><li>You’ll see an interactive API explorer</li><li>Click on the /chat endpoint</li><li>Click “Try it out”</li><li>Enter a message: &quot;What is 25 * 4? &quot;</li><li>Click “Execute”</li></ol><p>The agent will use its calculator tool and respond with the answer.</p><h3>Testing with cURL</h3><pre>curl -X POST https://YOUR_USERNAME-fastapi-agents.hf.space/chat \<br>  -H &quot;Content-Type: application/json&quot; \<br>  -d &#39;{&quot;message&quot;: &quot;What is the weather in San Francisco?&quot;}&#39;</pre><h3>Available Agent Tools</h3><p>Your agent comes with two built-in tools:</p><p>1. Calculator</p><p>Message: &quot;What is 144 / 12?&quot; Response: &quot;12&quot;</p><p>2. Weather Lookup</p><p>Message: &quot;What&#39;s the weather in London?&quot; Response: &quot;Weather information for London retrieved...&quot;</p><h3>Streaming Responses</h3><p>For real-time responses, use the streaming endpoint:</p><pre>curl -X POST https://YOUR_USERNAME-fastapi-agents.hf.space/chat/stream \<br>  -H &quot;Content-Type: application/json&quot; \<br>  -d &#39;{&quot;message&quot;:  &quot;Explain machine learning&quot;}&#39; \<br>  -N  # Unbuffered output for real-time streaming</pre><h3>Part 7: Understanding the Architecture</h3><p>Let’s peek under the hood:</p><h3>Core Components</h3><p>main.py: — The Heart of the Application</p><pre># Initialize the Groq client (OpenAI-compatible)<br>external_client = AsyncOpenAI(<br>    api_key=groq_api_key,<br>    base_url=&quot;https://api.groq.com/openai/v1&quot;,<br>)<br><br># Create the AI agent with tools<br>assistant_agent = Agent(<br>    name=&quot;Assistant&quot;,<br>    instructions=&quot;You are a helpful assistant.. .&quot;,<br>    model=groq_model,<br>    tools=[get_weather, calculate],<br>)</pre><p>Dockerfile — Production Containerization</p><p>The Dockerfile uses a multi-stage build for efficiency:</p><ul><li>Stage 1: Installs dependencies using uv (a fast Python package manager)</li><li>Stage 2: Creates a minimal production image with just the essentials</li></ul><p>This results in a small, fast container that deploys instantly.</p><h3>The Agent Pattern</h3><p>The OpenAI Agents SDK uses an agentic pattern:</p><ol><li>User sends a message</li><li>Agent decides which tool(s) to use</li><li>Tools execute and return results</li><li>Agent formulates a response</li><li>Response sent back to user</li></ol><p>This is similar to how ChatGPT plugins work — intelligent tool selection!</p><h3>Part 8: Customizing Your Agent</h3><p>Want to add your own tools? Here’s how:</p><h3>Adding a New Tool</h3><pre>from agents import function_tool<br><br>@function_tool<br>def get_stock_price(symbol: str) -&gt; str:<br>    &quot;&quot;&quot;Get the current stock price for a symbol.&quot;&quot;&quot;<br>    # Your implementation here<br>    return f&quot;Stock price for {symbol}&quot;<br><br># Add to agent<br>assistant_agent = Agent(<br>    name=&quot;Assistant&quot;,<br>    instructions=&quot;You are a financial advisor...&quot;,<br>    model=groq_model,<br>    tools=[get_weather, calculate, get_stock_price],  # Add your tool<br>)</pre><h3>Modifying Agent Instructions</h3><p>Customize the agent’s personality and behavior:</p><pre>assistant_agent = Agent(<br>    name=&quot;Assistant&quot;,<br>    instructions=&quot;&quot;&quot;You are a helpful Python coding assistant.  You can help with:<br>- Writing Python code<br>- Explaining concepts<br>- Performing calculations<br>- Answering questions<br><br>Always provide clear, concise explanations.&quot;&quot;&quot;,<br>    model=groq_model,<br>    tools=[calculate],<br>)</pre><h3>Part 9: Local Development (Optional)</h3><p>Want to test locally before deploying?</p><h3>Prerequisites</h3><ul><li>Python 3.12+</li><li>uv package manager: curl -LsSf https://astral. sh/uv/install.sh | sh</li></ul><h3>Setup</h3><pre># Install dependencies<br>uv sync<br><br># Copy the example env file<br>cp .env.example .env<br><br># Edit .env and add your GROQ_API_KEY<br># Then run:<br>uv run main.py</pre><p>Your API will be available at <a href="http://localhost:7860">http://localhost:7860</a></p><h3>Part 10: Troubleshooting</h3><pre>| Issue | Solution |<br>|-------|----------|<br>| **Build fails** | Check Space logs; usually missing `GROQ_API_KEY` |<br>| **API returns 500 error** | Verify `GROQ_API_KEY` is valid and not expired |<br>| **Swagger UI shows 503** | Space is still building; wait 2-3 minutes |<br>| **Tools not working** | Check agent instructions include tool names |<br>| **Slow responses** | Groq servers may be under load; retry in 30 seconds |</pre><h3>Advanced Features</h3><h3>CORS Configuration</h3><p>The app includes CORS middleware, allowing requests from any origin:</p><pre>app.add_middleware(<br>    CORSMiddleware,<br>    allow_origins=[&quot;*&quot;],<br>    allow_credentials=True,<br>    allow_methods=[&quot;*&quot;],<br>    allow_headers=[&quot;*&quot;],<br>)</pre><h3>Health Checks</h3><p>Built-in monitoring endpoint:</p><pre>curl https://YOUR_USERNAME-fastapi-agents.hf. space/health<br># Returns: {&quot;status&quot;: &quot;ok&quot;, &quot;model&quot;: &quot;openai/gpt-oss-20b&quot;, &quot;provider&quot;: &quot;groq&quot;}</pre><h3>Error Handling</h3><p>All endpoints include proper exception handling and return meaningful error messages.</p><h3>Conclusion</h3><p>You’ve successfully deployed a production-ready AI API!</p><p>Here’s what we accomplished:</p><p>✅ Created a Hugging Face Space<br>✅ Deployed FastAPI with OpenAI Agents SDK<br>✅ Configured Groq for free LLM inference<br>✅ Tested the API with multiple tools<br>✅ Understood the underlying architecture</p><h3>Resources</h3><ul><li>📦 Repository: <a href="https://github.com/DanielHashmi/fastapi-openai-agents-sdk">github.com/DanielHashmi/fastapi-openai-agents-sdk</a></li><li>🚀 Hugging Face Spaces: <a href="https://huggingface.co/spaces">huggingface. co/spaces</a></li><li>🔑 Groq Console: <a href="https://console.groq.com/">console.groq.com</a></li><li>📚 FastAPI Docs: <a href="https://fastapi.tiangolo.com/">fastapi.tiangolo.com</a></li><li>🤖 OpenAI Agents SDK: <a href="https://platform.openai.com/docs/guides/agents">platform.openai.com/docs/guides/agents</a></li></ul><p>Happy coding! 🎉</p><p>If you have questions or run into issues, feel free to open an issue on the GitHub repository or reach out on <a href="https://www.linkedin.com/in/daniel-hashmi/">social media</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2ce34d3eb766" width="1" height="1" alt=""><hr><p><a href="https://blog.devgenius.io/building-ai-powered-apis-with-fastapi-and-openai-agents-sdk-deployment-on-hugging-face-2ce34d3eb766">🤖 Building AI-Powered APIs with FastAPI and OpenAI Agents SDK: Deployment on Hugging Face</a> was originally published in <a href="https://blog.devgenius.io">Dev Genius</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Use Claude Code with Qwen models for Free on PowerShell (Windows)]]></title>
            <link>https://danielhashmi.medium.com/how-to-use-claude-code-with-qwen-models-for-free-on-powershell-windows-74061f59b8e4?source=rss-54f99fe76131------2</link>
            <guid isPermaLink="false">https://medium.com/p/74061f59b8e4</guid>
            <category><![CDATA[claude]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[qwen]]></category>
            <category><![CDATA[claude-code]]></category>
            <category><![CDATA[qwen3-coder]]></category>
            <dc:creator><![CDATA[Daniel Hashmi]]></dc:creator>
            <pubDate>Sat, 06 Dec 2025 04:58:10 GMT</pubDate>
            <atom:updated>2025-12-07T13:44:49.294Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lDwE_zN2Cla8508qT-cfcA.png" /></figure><h3>Prerequisites</h3><ul><li>Qwen CLI installed and authenticated</li><li>Node.js v18+ installed</li></ul><h3>Step 1: Install Claude, Claude Code Router and Qwen Code</h3><pre>npm install -g @qwen-code/qwen-code@latest</pre><pre>npm install -g @anthropic-ai/claude-code @musistudio/claude-code-router</pre><h3>Step 2: Extract Your Access Token</h3><p>Replace PC_USER with your Windows username.</p><p>Open C:\Users\PC_USER\.qwen\oauth_creds.json:</p><p>It should look something like this:</p><pre>{<br>  &quot;access_token&quot;: &quot;YOUR_QWEN_ACCESS_TOKEN_HERE&quot;,<br>  &quot;token_type&quot;: &quot;Bearer&quot;,<br>  &quot;refresh_token&quot;: &quot;YOUR_QWEN_REFRESH_TOKEN_HERE&quot;,<br>  &quot;resource_url&quot;: &quot;portal.qwen.ai&quot;,<br>  &quot;expiry_date&quot;: 1764876220290<br>}</pre><p>Copy the access_token value.</p><h3>Step 3: Create the Folders</h3><p>Paste this into PowerShell:</p><pre>New-Item -ItemType Directory -Force -Path &quot;$env:USERPROFILE\.claude-code-router&quot;, &quot;$env:USERPROFILE\.claude&quot;</pre><h3>Step 4: Create the Config File</h3><p>Paste this command to create and populate the config file:</p><pre>@&quot;<br>{  <br>  &quot;LOG&quot;: true,  <br>  &quot;LOG_LEVEL&quot;: &quot;info&quot;,  <br>  &quot;HOST&quot;: &quot;127.0.0.1&quot;,  <br>  &quot;PORT&quot;: 3456,  <br>  &quot;API_TIMEOUT_MS&quot;: 600000,  <br>  &quot;Providers&quot;: [  <br>    {  <br>      &quot;name&quot;: &quot;qwen&quot;,  <br>      &quot;api_base_url&quot;: &quot;https://portal.qwen.ai/v1/chat/completions&quot;,  <br>      &quot;api_key&quot;: &quot;YOUR_QWEN_ACCESS_TOKEN_HERE&quot;,  <br>      &quot;models&quot;: [  <br>        &quot;qwen3-coder-plus&quot;,  <br>        &quot;qwen3-coder-plus&quot;,  <br>        &quot;qwen3-coder-plus&quot;  <br>      ]  <br>    }  <br>  ],  <br>  &quot;Router&quot;: {  <br>    &quot;default&quot;: &quot;qwen,qwen3-coder-plus&quot;,  <br>    &quot;background&quot;: &quot;qwen,qwen3-coder-plus&quot;,  <br>    &quot;think&quot;: &quot;qwen,qwen3-coder-plus&quot;,  <br>    &quot;longContext&quot;: &quot;qwen,qwen3-coder-plus&quot;,  <br>    &quot;longContextThreshold&quot;: 60000,  <br>    &quot;webSearch&quot;: &quot;qwen,qwen3-coder-plus&quot;  <br>  }  <br>}<br>&quot;@ | Out-File -FilePath &quot;$env:USERPROFILE\.claude-code-router\config.json&quot; -Encoding UTF8</pre><p>To open the config file, use the following command:</p><pre>notepad &quot;$env:USERPROFILE\.claude-code-router\config.json&quot;</pre><p>Replace YOUR_QWEN_ACCESS_TOKEN_HERE with your actual access token from Step 2:</p><h3>Step 5: Start Using</h3><p>Restart the router server:</p><pre>ccr restart</pre><p>Run Claude Code with Qwen models:</p><pre>ccr code</pre><p>Test with:</p><pre>&gt; hi</pre><h3>Token Refresh (When you get 401 errors)</h3><p>Your OAuth token expires. Refresh it by:</p><ol><li>Re-authenticating your QWEN CODE CLI: If already logged in and the access_token matches in both config.json and oauth_creds.json, delete the oauth_creds.json file and run qwen to initiate re-authentication.</li><li>Update the api_key in your config.json with the new access_token:</li></ol><ul><li>notepad “$env:USERPROFILE\.claude-code-router\config.json”</li></ul><p>3. Restart: ccr restart</p><p>If using WSL: <a href="https://github.com/DanielHashmi/Q4_learning/blob/main/spec-driven-development/tutorials/How%20to%20Use%20Claude%20Code%20with%20Qwen%20models%20for%20Free%20on%20Linux%20and%20macOS%20(sh%20and%20bash).md">wsl setup</a></p><p><strong>Hopefully </strong>this will help you learn claude code for <strong>Free</strong>💖</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=74061f59b8e4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Python Lists, Tuples, and Dictionaries MCQs]]></title>
            <link>https://danielhashmi.medium.com/python-lists-tuples-and-dictionaries-mcqs-10a3fad6c91d?source=rss-54f99fe76131------2</link>
            <guid isPermaLink="false">https://medium.com/p/10a3fad6c91d</guid>
            <category><![CDATA[lists-in-python]]></category>
            <category><![CDATA[tuples-in-python]]></category>
            <category><![CDATA[dictionaries-in-python]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[python-mcq]]></category>
            <dc:creator><![CDATA[Daniel Hashmi]]></dc:creator>
            <pubDate>Thu, 17 Apr 2025 10:51:35 GMT</pubDate>
            <atom:updated>2025-04-17T10:54:44.792Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1LtDQt22vIbIWuYkE6qAyA.png" /></figure><p>Below are 60 multiple-choice questions (MCQs) designed to be challenging</p><ol><li><strong>What is a key characteristic of a Python list?</strong><br>a) Immutable<br>b) Unordered<br>c) Mutable<br>d) Hashable<br><strong>Answer</strong>: c) Mutable</li><li><strong>How can you correctly create a list with mixed data types?</strong><br>a) [“apple”, 42, 3.14, True]<br>b) (“apple”, 42, 3.14, True)<br>c) {“apple”: 42, “value”: 3.14}<br>d) set([“apple”, 42])<br><strong>Answer</strong>: a) [“apple”, 42, 3.14, True]</li><li><strong>What is the output of</strong> fruits = [“apple”, “banana”, “cherry”]; print(fruits[-1])<strong>?</strong><br>a) apple<br>b) banana<br>c) cherry<br>d) TypeError<br><strong>Answer</strong>: c) cherry</li><li><strong>What happens when you try to modify a list element at an invalid index?</strong><br>a) The list is extended<br>b) An IndexError is raised<br>c) The element is appended<br>d) Nothing happens<br><strong>Answer</strong>: b) An IndexError is raised</li><li><strong>What is the result of</strong> numbers = [1, 2, 3]; numbers.append(4); print(numbers)<strong>?</strong><br>a) [1, 2, 3]<br>b) [1, 2, 3, 4]<br>c) [4, 1, 2, 3]<br>d) TypeError<br><strong>Answer</strong>: b) [1, 2, 3, 4]</li><li><strong>What does the</strong> remove() <strong>method do if the specified value is not in the list?</strong><br>a) Removes the last element<br>b) Raises a ValueError<br>c) Does nothing<br>d) Clears the list<br><strong>Answer</strong>: b) Raises a ValueError</li><li><strong>What is the output of</strong> fruits = [“apple”, “banana”]; fruits.pop(); print(fruits)<strong>?</strong><br>a) [“apple”]<br>b) [“banana”]<br>c) []<br>d) TypeError<br><strong>Answer</strong>: a) [“apple”]</li><li><strong>What does</strong> numbers = [3, 1, 4]; numbers.sort(); print(numbers) <strong>output?</strong><br>a) [4, 3, 1]<br>b) [1, 3, 4]<br>c) [3, 1, 4]<br>d) TypeError<br><strong>Answer</strong>: b) [1, 3, 4]</li><li><strong>What is the result of</strong> words = [“cat”, “dog”, “bird”]; words.sort(key=len); print(words)<strong>?</strong><br>a) [“cat”, “dog”, “bird”]<br>b) [“bird”, “cat”, “dog”]<br>c) [“dog”, “cat”, “bird”]<br>d) TypeError<br><strong>Answer</strong>: a) [“cat”, “dog”, “bird”]</li><li><strong>What does the</strong> reverse() <strong>method do to a list?</strong><br>a) Sorts it in ascending order<br>b) Reverses the order of elements<br>c) Removes duplicates<br>d) Clears the list<br><strong>Answer</strong>: b) Reverses the order of elements</li><li><strong>What is the output of</strong> [x*2 for x in [1, 2, 3]]<strong>?</strong><br>a) [1, 2, 3]<br>b) [2, 4, 6]<br>c) [1, 4, 9]<br>d) TypeError<br><strong>Answer</strong>: b) [2, 4, 6]</li><li><strong>What does</strong> [x for x in [1, 2, 3, 4] if x &gt; 2] <strong>produce?</strong><br>a) [1, 2]<br>b) [3, 4]<br>c) [1, 2, 3, 4]<br>d) []<br><strong>Answer</strong>: b) [3, 4]</li><li><strong>What is a key characteristic of a Python tuple?</strong><br>a) Mutable<br>b) Unordered<br>c) Immutable<br>d) Dynamic size<br><strong>Answer</strong>: c) Immutable</li><li><strong>Why can a tuple be used as a dictionary key?</strong><br>a) It is mutable<br>b) It is hashable<br>c) It is unordered<br>d) It allows duplicates<br><strong>Answer</strong>: b) It is hashable</li><li><strong>What happens when you try to modify a tuple element?</strong><br>a) The element is updated<br>b) A TypeError is raised<br>c) Nothing happens<br>d) The tuple is cleared<br><strong>Answer</strong>: b) A TypeError is raised</li><li><strong>What is the output of</strong> tuple1 = (“apple”, “banana”); print(tuple1.count(“apple”))<strong>?</strong><br>a) 0<br>b) 1<br>c) 2<br>d) TypeError<br><strong>Answer</strong>: b) 1</li><li><strong>What does</strong> tuple1 = (1, 2, 3); print(tuple1.index(2)) <strong>return?</strong><br>a) 0<br>b) 1<br>c) 2<br>d) TypeError<br><strong>Answer</strong>: b) 1</li><li><strong>What is the result of</strong> tuple1 = (1, 2); tuple2 = (3, 4); print(tuple1 + tuple2)<strong>?</strong><br>a) (1, 2, 3, 4)<br>b) (1, 2)<br>c) (3, 4)<br>d) TypeError<br><strong>Answer</strong>: a) (1, 2, 3, 4)</li><li><strong>What is the output of</strong> tuple1 = (1, 2); print(tuple1 * 2)<strong>?</strong><br>a) (1, 2)<br>b) (1, 2, 1, 2)<br>c) (2, 4)<br>d) TypeError<br><strong>Answer</strong>: b) (1, 2, 1, 2)</li><li><strong>What does</strong> a, b = (1, 2) <strong>do?</strong><br>a) Raises a TypeError<br>b) Unpacks the tuple into variables a and b<br>c) Creates a new tuple<br>d) Modifies the tuple<br><strong>Answer</strong>: b) Unpacks the tuple into variables a and b</li><li><strong>What is a key characteristic of a Python dictionary?</strong><br>a) Indexed by position<br>b) Immutable<br>c) Ordered (since Python 3.7)<br>d) Allows duplicate keys<br><strong>Answer</strong>: c) Ordered (since Python 3.7)</li><li><strong>How can you create a dictionary using the</strong> dict() <strong>constructor?</strong><br>a) dict(name=”John”, age=30)<br>b) {“name”: “John”, “age”: 30}<br>c) [(“name”, “John”), (“age”, 30)]<br>d) dict([“name”, “John”])<br><strong>Answer</strong>: a) dict(name=”John”, age=30)</li><li><strong>What does</strong> person = {“name”: “Alice”}; print(person.get(“age”, 25)) <strong>output?</strong><br>a) None<br>b) 25<br>c) KeyError<br>d) “Alice”<br><strong>Answer</strong>: b) 25</li><li><strong>What happens when you access a non-existent key with</strong> person[“age”]<strong>?</strong><br>a) Returns None<br>b) Raises a KeyError<br>c) Returns a default value<br>d) Creates the key<br><strong>Answer</strong>: b) Raises a KeyError</li><li><strong>What is the output of</strong> person = {“name”: “Alice”}; person[“name”] = “Bob”; print(person)<strong>?</strong><br>a) {“name”: “Alice”}<br>b) {“name”: “Bob”}<br>c) {“name”: “Alice”, “name”: “Bob”}<br>d) TypeError<br><strong>Answer</strong>: b) {“name”: “Bob”}</li><li><strong>What does</strong> person = {“name”: “Alice”}; del person[“name”]; print(person) <strong>output?</strong><br>a) {“name”: “Alice”}<br>b) {}<br>c) None<br>d) KeyError<br><strong>Answer</strong>: b) {}</li><li><strong>What is the result of</strong> person = {“name”: “Alice”}; person.pop(“name”); print(person)<strong>?</strong><br>a) {“name”: “Alice”}<br>b) {}<br>c) None<br>d) KeyError<br><strong>Answer</strong>: b) {}</li><li><strong>What does</strong> person = {“name”: “Alice”, “age”: 25}; print(person.keys()) <strong>return?</strong><br>a) [“name”, “age”]<br>b) dict_keys([“name”, “age”])<br>c) (“name”, “age”)<br>d) TypeError<br><strong>Answer</strong>: b) dict_keys([“name”, “age”])</li><li><strong>What is the output of</strong> person = {“name”: “Alice”}; person.update({“age”: 25}); print(person)<strong>?</strong><br>a) {“name”: “Alice”}<br>b) {“name”: “Alice”, “age”: 25}<br>c) {“age”: 25}<br>d) TypeError<br><strong>Answer</strong>: b) {“name”: “Alice”, “age”: 25}</li><li><strong>What does</strong> person = {“name”: “Alice”}; person.clear(); print(person) <strong>output?</strong><br>a) {“name”: “Alice”}<br>b) {}<br>c) None<br>d) TypeError<br><strong>Answer</strong>: b) {}</li><li><strong>What is the output of</strong> my_dict = {“a”: 1, “b”: 2}; print({k: v*2 for k, v in my_dict.items()})<strong>?</strong><br>a) {“a”: 1, “b”: 2}<br>b) {“a”: 2, “b”: 4}<br>c) {“a”: 1, “b”: 4}<br>d) TypeError<br><strong>Answer</strong>: b) {“a”: 2, “b”: 4}</li><li><strong>What is the result of</strong> celsius = [0, 10]; print({c: (c * 9/5) + 32 for c in celsius})<strong>?</strong><br>a) {0: 32.0, 10: 50.0}<br>b) {0: 0, 10: 10}<br>c) {0: 32, 10: 50}<br>d) TypeError<br><strong>Answer</strong>: a) {0: 32.0, 10: 50.0}</li><li><strong>Why are tuples thread-safe?</strong><br>a) They are mutable<br>b) They are immutable<br>c) They are ordered<br>d) They allow duplicates<br><strong>Answer</strong>: b) They are immutable</li><li><strong>What is the output of</strong> numbers = [1, 2, 3]; print(numbers[1:3])<strong>?</strong><br>a) [1, 2]<br>b) [2, 3]<br>c) [1, 2, 3]<br>d) TypeError<br><strong>Answer</strong>: b) [2, 3]</li><li><strong>What does</strong> fruits = [“apple”, “banana”]; fruits.extend([“cherry”]); print(fruits) <strong>output?</strong><br>a) [“apple”, “banana”]<br>b) [“apple”, “banana”, “cherry”]<br>c) [“cherry”, “apple”, “banana”]<br>d) TypeError<br><strong>Answer</strong>: b) [“apple”, “banana”, “cherry”]</li><li><strong>What is the output of</strong> words = [“apple”, “banana”]; words.sort(key=lambda x: x[-1]); print(words)<strong>?</strong><br>a) [“banana”, “apple”]<br>b) [“apple”, “banana”]<br>c) [“banana”, “apple”]<br>d) TypeError<br><strong>Answer</strong>: a) [“banana”, “apple”]</li><li><strong>What happens when you try to call</strong> tuple1 = (1, 2); tuple1.append(3)<strong>?</strong><br>a) (1, 2, 3) is created<br>b) An AttributeError is raised<br>c) Nothing happens<br>d) The tuple is cleared<br><strong>Answer</strong>: b) An AttributeError is raised</li><li><strong>What is the output of</strong> tuple1 = (1, 2, 2); print(tuple1.count(2))<strong>?</strong><br>a) 0<br>b) 1<br>c) 2<br>d) TypeError<br><strong>Answer</strong>: c) 2</li><li><strong>What does</strong> phonebook = {“Alice”: “123”}; print(“Alice” in phonebook) <strong>return?</strong><br>a) True<br>b) False<br>c) None<br>d) KeyError<br><strong>Answer</strong>: a) True</li><li><strong>What is the result of</strong> my_dict = {“a”: 1, “a”: 2}; print(my_dict)<strong>?</strong><br>a) {“a”: 1, “a”: 2}<br>b) {“a”: 2}<br>c) {“a”: 1}<br>d) KeyError<br><strong>Answer</strong>: b) {“a”: 2}</li><li><strong>What does</strong> my_dict = {“name”: “Alice”}; print(my_dict.values()) <strong>return?</strong><br>a) [“Alice”]<br>b) dict_values([“Alice”])<br>c) (“Alice”,)<br>d) TypeError<br><strong>Answer</strong>: b) dict_values([“Alice”])</li><li><strong>What is the output of</strong> my_dict = {“name”: “Alice”}; print(len(my_dict))<strong>?</strong><br>a) 0<br>b) 1<br>c) 2<br>d) TypeError<br><strong>Answer</strong>: b) 1</li><li><strong>What does</strong> my_dict = {“name”: “Alice”}; my_dict.copy(); print(my_dict) <strong>output?</strong><br>a) {}<br>b) {“name”: “Alice”}<br>c) None<br>d) TypeError<br><strong>Answer</strong>: b) {“name”: “Alice”}</li><li><strong>What is the result of</strong> nested_dict = {“person”: {“name”: “Alice”}}; print(nested_dict[“person”][“name”])<strong>?</strong><br>a) Alice<br>b) {“name”: “Alice”}<br>c) KeyError<br>d) TypeError<br><strong>Answer</strong>: a) Alice</li><li><strong>What is the output of</strong> for key in {“name”: “Alice”, “age”: 25}: print(key)<strong>?</strong><br>a) name, age<br>b) Alice, 25<br>c) (“name”, “Alice”), (“age”, 25)<br>d) TypeError<br><strong>Answer</strong>: a) name, age</li><li><strong>What does</strong> word_count = {}; word_count[“word”] = 1; print(word_count) <strong>output?</strong><br>a) {“word”: 1}<br>b) {}<br>c) None<br>d) KeyError<br><strong>Answer</strong>: a) {“word”: 1}</li><li><strong>What is the output of</strong> numbers = [1, 2, 3]; numbers.pop(1); print(numbers)<strong>?</strong><br>a) [1, 3]<br>b) [1, 2]<br>c) [2, 3]<br>d) TypeError<br><strong>Answer</strong>: a) [1, 3]</li><li><strong>What does</strong> tuple1 = (1, 2); print(tuple1[1:]) <strong>output?</strong><br>a) (1, 2)<br>b) (2,)<br>c) ()<br>d) TypeError<br><strong>Answer</strong>: b) (2,)</li><li><strong>What is the result of</strong> my_dict = {“a”: 1}; my_dict.update({“a”: 2}); print(my_dict)<strong>?</strong><br>a) {“a”: 1}<br>b) {“a”: 2}<br>c) {“a”: 1, “a”: 2}<br>d) TypeError<br><strong>Answer</strong>: b) {“a”: 2}</li><li><strong>What does</strong> sorted_word_count = dict(sorted({“a”: 2, “b”: 1}.items(), key=lambda x: x[1])); print(sorted_word_count) <strong>output?</strong><br>a) {“b”: 1, “a”: 2}<br>b) {“a”: 2, “b”: 1}<br>c) [“b”, “a”]<br>d) TypeError<br><strong>Answer</strong>: a) {“b”: 1, “a”: 2}</li><li><strong>What is the output of</strong> fruits = [“apple”, “banana”]; fruits[0:1] = [“cherry”]; print(fruits)<strong>?</strong><br>a) [“cherry”, “banana”]<br>b) [“apple”, “banana”]<br>c) [“cherry”, “apple”, “banana”]<br>d) TypeError<br><strong>Answer</strong>: a) [“cherry”, “banana”]</li><li><strong>What does</strong> tuple1 = (1, 2, 3); print(2 in tuple1) <strong>return?</strong><br>a) True<br>b) False<br>c) None<br>d) TypeError<br><strong>Answer</strong>: a) True</li><li><strong>What is the output of</strong> my_dict = {“name”: “Alice”, “age”: 25}; print(my_dict.items())<strong>?</strong><br>a) dict_items([(“name”, “Alice”), (“age”, 25)])<br>b) [(“name”, “Alice”), (“age”, 25)]<br>c) {“name”: “Alice”, “age”: 25}<br>d) TypeError<br><strong>Answer</strong>: a) dict_items([(“name”, “Alice”), (“age”, 25)])</li><li><strong>What does</strong> numbers = [1, 2, 3]; numbers.reverse(); print(numbers) <strong>output?</strong><br>a) [1, 2, 3]<br>b) [3, 2, 1]<br>c) [2, 1, 3]<br>d) TypeError<br><strong>Answer</strong>: b) [3, 2, 1]</li><li><strong>What is the result of</strong> tuple1 = (1, 2); tuple2 = (1, 2); print(id(tuple1) == id(tuple2))<strong>?</strong><br>a) True<br>b) False<br>c) TypeError<br>d) None<br><strong>Answer</strong>: b) False</li><li><strong>What does</strong> my_dict = {“a”: 1}; print(my_dict.pop(“b”, -1)) <strong>return?</strong><br>a) 1<br>b) -1<br>c) KeyError<br>d) None<br><strong>Answer</strong>: b) -1</li><li><strong>What is the output of</strong> [x**2 for x in [1, 2, 3] if x &gt; 1]<strong>?</strong><br>a) [1, 4, 9]<br>b) [4, 9]<br>c) [1, 2, 3]<br>d) TypeError<br><strong>Answer</strong>: b) [4, 9]</li><li><strong>What does</strong> phonebook = {“Alice”: “123”}; phonebook[“Alice”] = “456”; print(phonebook) <strong>output?</strong><br>a) {“Alice”: “123”}<br>b) {“Alice”: “456”}<br>c) {“Alice”: “123”, “Alice”: “456”}<br>d) KeyError<br><strong>Answer</strong>: b) {“Alice”: “456”}</li><li><strong>What is the output of</strong> numbers = [1, 2, 3]; print(numbers.pop())<strong>?</strong><br>a) 1<br>b) 2<br>c) 3<br>d) TypeError<br><strong>Answer</strong>: c) 3</li><li><strong>What does</strong> my_dict = {“name”: “Alice”}; print(“name” in my_dict) <strong>return?</strong><br>a) True<br>b) False<br>c) None<br>d) KeyError<br><strong>Answer</strong>: a) True</li></ol><p>These MCQs should effectively prepare you for a deep understanding of Python lists, tuples, and dictionaries.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=10a3fad6c91d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ NumPy Extensive CheatSheet]]></title>
            <link>https://danielhashmi.medium.com/numpy-extensive-cheatsheet-80ec5e5c7d24?source=rss-54f99fe76131------2</link>
            <guid isPermaLink="false">https://medium.com/p/80ec5e5c7d24</guid>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[numpy]]></category>
            <category><![CDATA[pandas]]></category>
            <category><![CDATA[python-programming]]></category>
            <category><![CDATA[python]]></category>
            <dc:creator><![CDATA[Daniel Hashmi]]></dc:creator>
            <pubDate>Mon, 24 Feb 2025 19:06:40 GMT</pubDate>
            <atom:updated>2025-02-24T19:09:51.671Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="Numpy Image" src="https://cdn-images-1.medium.com/max/646/1*puBVyo59sdC1Ltx0vcNUrw.jpeg" /><figcaption>Numpy Image</figcaption></figure><h3>1. Introduction to NumPy 🤗</h3><h4>Who Created NumPy? 💡</h4><ul><li><strong>Background: </strong>NumPy is the successor to earlier array-handling libraries in Python such as Numeric and numarray.</li><li><strong>Key Contributor: </strong>Travis Oliphant was instrumental in combining and advancing these efforts into what we now know as NumPy. His work, along with the contributions of many community members, helped establish NumPy as the cornerstone of numerical computing in Python.</li></ul><h4>What is NumPy? 🔢</h4><ul><li><strong>Purpose &amp; Scope: </strong>NumPy is a foundational library designed for efficient numerical computation. It provides support for large, multi-dimensional arrays and matrices, along with a collection of mathematical functions to operate on these data structures.</li><li><strong>Core Feature — ndarray: </strong>The heart of NumPy is its n-dimensional array object, or <strong>ndarray</strong>. This object allows for fast and efficient storage and manipulation of homogeneous data. Its design lets you perform vectorized operations, reducing the need for slow Python loops.</li></ul><h4>Why is it Called NumPy?</h4><ul><li><strong>Name Origin: </strong>“NumPy” stands for <strong>Numerical Python</strong>. The name emphasizes its focus on numerical data and operations, distinguishing it as a tool optimized for numerical computations rather than generic programming tasks.</li></ul><h4>Importing NumPy 💻</h4><ul><li><strong>Standard Practice:</strong></li></ul><pre>import numpy as np</pre><p>This common import statement loads NumPy into your Python environment and assigns it the alias “np”. This shorthand is widely used, making code more concise and readable.</p><h3>2. NumPy Arrays: The Core Data Structure 🗃️</h3><h4>What is an ndarray? 🔎</h4><ul><li><strong>Definition: </strong>The <strong>ndarray</strong> is a powerful, multi-dimensional container for homogeneous data (all elements are of the same type).</li><li><strong>Key Attributes: Shape:</strong> A tuple indicating the size along each dimension (e.g., (3, 4) for 3 rows and 4 columns).</li><li><strong>dtype:</strong> The data type of the elements (e.g., int32, float64), ensuring consistency and enabling optimizations.</li><li><strong>ndim:</strong> The number of dimensions (e.g., 1 for a vector, 2 for a matrix).</li><li><strong>Size:</strong> The total number of elements in the array.</li><li><strong>Benefits: </strong>This structure allows for efficient, low-level computations and memory management, making it possible to perform operations on large datasets quickly.</li></ul><h4>Creating a Basic Array</h4><ul><li><strong>Example:</strong></li></ul><pre>arr = np.array([1,  2,  3,  4])<br>print(arr)  # Output: [1 2 3 4]</pre><p>Here, a standard Python list is converted into an ndarray. This conversion is the first step to taking advantage of NumPy’s vectorized operations and performance benefits.</p><h3>3. Creating Arrays 🔧</h3><h4>Arrays Filled with Zeros and Ones</h4><ul><li><strong>Zeros</strong></li></ul><pre>zeros = np.zeros((2,  3))</pre><p>This creates a 2x3 array where every element is 0. You can also specify a data type with the dtype parameter.</p><ul><li><strong>Ones:</strong></li></ul><pre>ones = np.ones((2,  3))</pre><p>Similarly, this creates a 2x3 array where every element is 1.</p><h4>Using np.arange and np.linspace 🔢</h4><ul><li><strong>np.arange:</strong></li></ul><pre>arange_array = np.arange(0,  10,  2)</pre><p>Generates an array starting at 0, increasing in steps of 2, and stopping before 10. This is similar to Python’s built-in range, but returns an array.</p><ul><li><strong>np.linspace:</strong></li></ul><pre>linspace_array = np.linspace(0,  1,  5)</pre><p>Produces 5 evenly spaced values between 0 and 1 (inclusive). By specifying endpoint=False, you can exclude the final value, which is useful in some applications like plotting or simulations.</p><h4>Creating Arrays with Random Values 🎲</h4><ul><li><strong>Uniform Distribution:</strong></li></ul><pre>random_array = np.random.rand(3,  3)</pre><p>Generates a 3x3 array with random floats in the interval [0, 1).</p><ul><li><strong>Random Integers:</strong></li></ul><pre>rand_int = np.random.randint(0,  10,  size=(2,  2))</pre><p>Produces a 2x2 array with random integers between 0 and 9.</p><ul><li><strong>Normal Distribution:</strong></li></ul><pre>normal_array = np.random.randn(3,  3)</pre><p>Generates numbers drawn from the standard normal distribution (mean 0, variance 1).</p><ul><li><strong>Reproducibility:</strong></li></ul><pre>np.random.seed(42)</pre><p>Setting a seed ensures that the same random numbers are generated each time, which is important for debugging and reproducible research.</p><h3>4. Array Indexing and Slicing ✂️</h3><h4>Basic Indexing</h4><ul><li><strong>Accessing Elements:</strong></li></ul><pre>print(arr[2])</pre><p>NumPy arrays are zero-indexed. Here, arr[2] retrieves the third element of the array.</p><h4>Slicing ✂️</h4><ul><li><strong>Extracting Subarrays:</strong></li></ul><pre>sub_array = arr[1:3]</pre><p>This extracts a slice from index 1 up to (but not including) index 3. For the array [1, 2, 3, 4], the result is [2, 3].</p><h4>Multi-dimensional Indexing 📐</h4><ul><li><strong>Accessing Matrix Elements:</strong></li></ul><pre>matrix = np.array([[1,  2,  3],  [4,  5,  6]])<br>print(matrix[1,  2])</pre><p>In a 2D array, matrix[1, 2] accesses the element at the second row and third column. This direct indexing is both intuitive and efficient.</p><h4>Boolean Indexing ✅</h4><ul><li><strong>Filtering Elements:</strong></li></ul><pre>filtered = arr[arr &gt;  2]</pre><p>This returns a new array containing only the elements of arr that are greater than 2. Boolean indexing is a powerful tool for conditional data selection without needing explicit loops.</p><h3>5. Array Operations and Broadcasting 📡</h3><h4>Element-wise Operations ➕</h4><ul><li><strong>Arithmetic on Arrays:</strong></li></ul><pre>sum_array = arr +  5<br>product_array = arr *  2</pre><p>These operations are applied element-by-element. For example, adding 5 to each element of [1, 2, 3, 4] results in [6, 7, 8, 9].</p><h4>Broadcasting 📡</h4><ul><li><strong>Concept:</strong></li></ul><p>Broadcasting is NumPy’s ability to perform arithmetic operations on arrays of different shapes. It “stretches” the smaller array so that its shape becomes compatible with the larger array.</p><ul><li><strong>Example:</strong></li></ul><pre>a = np.array([1,  2,  3])<br>b = np.array([[10],  [20],  [30]])<br>broadcast_sum = a + b</pre><p>Here, a is a 1D array and b is a 2D column vector. Broadcasting automatically expands a so that each row of b is added to it, resulting in a 3x3 array.</p><h4>Universal Functions (ufuncs) 🔧</h4><ul><li><strong>Definition and Examples:</strong></li></ul><p>Universal functions (or ufuncs) like np.sin, np.exp, and np.log operate element-wise over arrays. They are implemented in C and optimized for performance, making them much faster than applying the corresponding Python math functions within a loop.</p><h3>6. Array Manipulation 🔄</h3><h4>Reshaping Arrays 🔀</h4><ul><li><strong>Changing the Shape:</strong></li></ul><pre>reshaped = np.reshape(arr,  (2,  2))</pre><p>Reshaping rearranges the data in the array without altering the data itself. For example, [1, 2, 3, 4] can be reshaped into a 2x2 matrix:</p><pre>[[1, 2], [3, 4]]</pre><h4>Flattening Arrays 📏</h4><ul><li><strong>One-dimensional Conversion:</strong></li></ul><pre>flat = matrix.flatten()</pre><p>This method converts a multi-dimensional array into a one-dimensional array. It is useful when you need a linear view of the data.</p><h4>Transposing ↕️</h4><ul><li><strong>Swapping Axes:</strong></li></ul><pre>transposed = matrix.T</pre><p>Transposing flips the array over its diagonal, swapping rows with columns. This is especially useful in linear algebra and data analysis for aligning data structures.</p><h3>7. Aggregation and Statistical Functions 📊</h3><h4>Basic Aggregations 🧮</h4><ul><li><strong>Summarizing Data:</strong></li></ul><pre>sum_val = np.sum(arr)<br>mean_val = np.mean(arr)<br>min_val = np.min(arr)<br>max_val = np.max(arr)</pre><p>These functions quickly compute summary statistics for the entire array, which is essential for data analysis.</p><h4>Aggregations Across Axes 📐</h4><ul><li><strong>Axis-Specific Operations:</strong></li></ul><pre>matrix_sum = np.sum(matrix,  axis=0)  # Sum across columns<br>row_mean = np.mean(matrix,  axis=1)  # Mean across rows</pre><p>By specifying the axis parameter, you can perform computations along a specific dimension. This is useful when working with matrices or higher-dimensional arrays.</p><h4>Other Statistical Functions 📈</h4><ul><li><strong>Advanced Metrics:</strong></li></ul><pre>std_dev = np.std(arr)<br>variance = np.var(arr)<br>median_val = np.median(arr)<br>percentiles = np.percentile(arr,  [25,  50,  75])</pre><ul><li><strong>Standard Deviation &amp; Variance:</strong> Measure the dispersion of data.</li><li><strong>Median:</strong> Identifies the central value in the sorted array.</li><li><strong>Percentiles:</strong> Indicate the values below which a given percentage of observations fall, providing insight into the distribution of data.</li></ul><h3>8. Linear Algebra with NumPy 🧮</h3><h4>Dot Product and Matrix Multiplication ✖️</h4><ul><li><strong>Dot Product:</strong></li></ul><pre>dot_product = np.dot(a, a)</pre><p>For vectors, the dot product multiplies corresponding elements and sums them up, which is a fundamental operation in linear algebra.</p><ul><li><strong>Matrix Multiplication:</strong></li></ul><pre>matrix_product = np.matmul(matrix, matrix.T)</pre><p>Matrix multiplication combines rows and columns according to the rules of linear algebra. The @ operator is a shorthand for np.matmul, which enhances code readability.</p><h4>Inverse and Determinant 🧮</h4><ul><li><strong>Inverse:</strong></li></ul><pre>inverse_matrix = np.linalg.inv(matrix)</pre><p>The inverse of a matrix is another matrix that, when multiplied with the original, yields the identity matrix. This operation is only defined for square matrices with a non-zero determinant.</p><ul><li><strong>Determinant:</strong></li></ul><pre>determinant = np.linalg.det(matrix)</pre><p>The determinant is a scalar that can indicate if a matrix is invertible (a zero determinant means the matrix is singular).</p><ul><li><strong>Additional Topics:</strong></li><li><strong>Eigenvalues and Eigenvectors:</strong> These reveal intrinsic properties of a matrix, such as its axes of symmetry.</li><li><strong>Singular Value Decomposition (SVD):</strong> Breaks down a matrix into three component matrices, useful in many applications including signal processing and statistics.</li><li><strong>Solving Linear Systems:</strong></li></ul><pre>A = np.array([[3,  1],  [1,  2]])<br>b = np.array([9,  8])<br>x = np.linalg.solve(A, b)</pre><p>This solves the system of linear equations (Ax = b), a common problem in many scientific computations.</p><h3>9. Saving and Loading Arrays 💾</h3><h4>Saving Arrays 💾</h4><ul><li><strong>Binary Format:</strong></li></ul><pre>np.save(&#39;array.npy&#39;, arr)</pre><p>Saves the array in a binary format that preserves its structure and data type.</p><h4>Loading Arrays 📂</h4><ul><li><strong>Restoring Data:</strong></li></ul><pre>loaded_arr = np.load(&#39;array.npy&#39;)</pre><p>Loads the binary file back into an ndarray with its original properties intact.</p><h4>Saving Multiple Arrays 📦</h4><ul><li><strong>Compressed Format:</strong></li></ul><pre>np.savez(&#39;arrays.npz&#39;,  array1=arr,  array2=matrix)</pre><p>This allows you to save several arrays into a single compressed file, making data management more convenient.</p><h4>Working with Text Files 📝</h4><ul><li><strong>Human-Readable Format:</strong></li></ul><pre>np.savetxt(&#39;array.txt&#39;, arr,  fmt=&#39;%d&#39;)<br>loaded_txt_arr = np.loadtxt(&#39;array.txt&#39;,  dtype=int)</pre><p>These functions save arrays to a text file and load them back, which is useful when you need to inspect the data or share it with non-Python tools.</p><h3>10. Advanced Techniques 🚀</h3><h4>Stacking and Splitting Arrays 🔀</h4><ul><li><strong>Stacking:</strong></li></ul><pre># Vertical stacking: Adds rows<br>stacked_v = np.vstack((arr, arr))<br># Horizontal stacking: Adds columns (after reshaping, if necessary)<br>stacked_h = np.hstack((arr.reshape(4,  1), arr.reshape(4,  1)))</pre><p>Stacking combines arrays along a new axis — either vertically (adding rows) or horizontally (adding columns).</p><ul><li><strong>Splitting:</strong></li></ul><pre># Splitting along columns<br>split_arr = np.hsplit(stacked_v,  2)<br># Splitting along rows<br>split_arr_v = np.vsplit(stacked_v,  2)</pre><p>Splitting divides an array into multiple sub-arrays along a specified axis.</p><h4>Copy vs. View</h4><ul><li><strong>copy():</strong></li></ul><pre>copy_arr = arr.copy()</pre><p>This creates a completely new array with its own memory. Modifications to the copy do not affect the original array.</p><ul><li><strong>view():</strong></li></ul><pre>view_arr = arr.view()</pre><p>A view creates a new array object that references the same underlying data. Changes made through a view are reflected in the original array, so it’s important to use views carefully when you need independent copies.</p><h3>11. Additional Advanced Topics 🧠</h3><h4>Fancy Indexing 🎯</h4><ul><li><strong>Definition:</strong></li></ul><p>Fancy indexing lets you select arbitrary items in an array using an array of indices or boolean values.</p><ul><li><strong>Example:</strong></li></ul><pre>indices =  [0,  2]<br>fancy = arr[indices]</pre><p>This returns the elements at positions 0 and 2 from arr, which is especially useful when the elements you need are not contiguous.</p><h4>Memory Layout and Performance ⚡</h4><ul><li><strong>Memory Orders:</strong></li><li><strong>C Order (Row-major):</strong> Data is stored row by row. This is the default in NumPy and is optimal for many row-wise operations.</li><li><strong>F Order (Column-major):</strong> Data is stored column by column, which can be beneficial for certain linear algebra routines.</li><li><strong>Vectorization:</strong></li></ul><p>By replacing explicit Python loops with array operations, you can exploit low-level optimizations and achieve significant performance gains.</p><ul><li><strong>In-place Operations:</strong></li></ul><p>Operations like arr += 1 update the array directly in memory, reducing overhead and memory usage compared to creating new arrays.</p><h4>Other Useful Array Functions 🛠️</h4><ul><li><strong>Sorting and Searching:</strong></li></ul><pre>sorted_arr = np.sort(arr)<br>indices_sorted = np.argsort(arr)</pre><p>These functions allow you to sort an array and obtain the indices that would sort the array, which is useful in many data analysis tasks.</p><ul><li><strong>Finding Unique Values:</strong></li></ul><pre>unique_elements = np.unique(arr)</pre><p>This returns the sorted unique elements of the array, helping to identify duplicates or categorize data.</p><ul><li><strong>Resizing vs. Reshaping:</strong></li><li><strong>np.resize:</strong> Can change the size of an array, repeating elements if necessary.</li><li><strong>np.reshape:</strong> Changes the dimensions of an array without altering the total number of elements.</li></ul><h3>Glossary of Key Jargons 📚</h3><ul><li><a href="https://numpy.org/doc/stable/reference/arrays.ndarray.html"><strong>ndarray</strong></a><strong>:</strong> The core multi-dimensional array object in NumPy that stores elements of a single data type.</li><li><a href="https://numpy.org/doc/stable/reference/arrays.dtypes.html"><strong>dtype</strong></a><strong>:</strong> Defines the data type (e.g., integers, floats) for the elements in an ndarray.</li><li><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.shape.html"><strong>Shape</strong></a><strong> &amp; </strong><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.ndim.html"><strong>ndim</strong></a><strong>:</strong> Shape refers to the dimensions (e.g., rows and columns) of an array, and ndim indicates how many dimensions the array has.</li><li><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.size.html"><strong>Size</strong></a><strong>:</strong> The total number of elements in an array.</li><li><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.strides.html"><strong>Strides</strong></a><strong>:</strong> Describe how many bytes to step in each dimension when traversing an array, impacting performance and memory layout.</li><li><a href="https://numpy.org/doc/stable/reference/ufuncs.html"><strong>Vectorized Operations</strong></a><strong>:</strong> Allow operations to be performed on entire arrays at once, rather than element by element in Python loops.</li><li><a href="https://numpy.org/doc/stable/user/basics.broadcasting.html"><strong>Broadcasting</strong></a><strong>:</strong> Automatically expands arrays with smaller dimensions to match larger arrays during arithmetic operations.</li><li><a href="https://numpy.org/doc/stable/reference/ufuncs.html"><strong>ufuncs (Universal Functions)</strong></a><strong>:</strong> Optimized functions that perform element-wise operations on arrays (e.g., np.sin, np.exp).</li><li><a href="https://numpy.org/doc/stable/glossary.html#term-axis"><strong>Axis</strong></a><strong>:</strong> The dimension along which an operation is performed, such as summing or averaging.</li><li><a href="https://numpy.org/doc/stable/reference/routines.statistics.html"><strong>Aggregation</strong></a><strong>:</strong> Functions like np.sum, np.mean, etc., that combine elements of an array to produce summary statistics.</li><li><a href="https://numpy.org/doc/stable/reference/generated/numpy.dot.html"><strong>Dot Product</strong></a><strong> &amp; </strong><a href="https://numpy.org/doc/stable/reference/generated/numpy.matmul.html"><strong>Matrix Multiplication</strong></a><strong>:</strong> Fundamental operations in linear algebra — dot product is used for vectors, while matrix multiplication combines rows and columns of matrices.</li><li><a href="https://numpy.org/doc/stable/reference/generated/numpy.linalg.inv.html"><strong>Inverse</strong></a><strong> &amp; </strong><a href="https://numpy.org/doc/stable/reference/generated/numpy.linalg.det.html"><strong>Determinant</strong></a><strong>:</strong> Concepts used in solving systems of linear equations and understanding matrix properties.</li><li><a href="https://numpy.org/doc/stable/reference/generated/numpy.linalg.eig.html"><strong>Eigenvalues and Eigenvectors</strong></a><strong>:</strong> Values and corresponding vectors that reveal important properties of a matrix.</li><li><a href="https://numpy.org/doc/stable/reference/generated/numpy.linalg.svd.html"><strong>Singular Value Decomposition (SVD)</strong></a><strong>:</strong> A technique that decomposes a matrix into three simpler matrices to reveal useful properties of the original matrix.</li><li><a href="https://numpy.org/doc/stable/reference/generated/numpy.linalg.solve.html"><strong>Linear System</strong></a><strong>:</strong> A set of equations represented in matrix form that can be solved using functions like np.linalg.solve().</li><li><a href="https://numpy.org/doc/stable/reference/generated/numpy.stack.html"><strong>Stacking</strong></a><strong> and </strong><a href="https://numpy.org/doc/stable/reference/generated/numpy.split.html"><strong>Splitting</strong></a><strong>:</strong> Methods for combining arrays (stacking) and dividing an array into smaller parts (splitting).</li><li><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.copy.html"><strong>Copy</strong></a><strong>:</strong> Creates a new, independent copy of an array.</li><li><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.view.html"><strong>View</strong></a><strong>:</strong> Creates a new array object that references the same data as the original array; modifications to the view may affect the original.</li><li><a href="https://numpy.org/doc/stable/reference/arrays.indexing.html#advanced-indexing"><strong>Fancy Indexing</strong></a><strong>:</strong> Accessing array elements using another array of indices.</li><li><a href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.flags.html"><strong>Memory Layout</strong></a><strong>:</strong> Describes the way in which array data is stored in memory (e.g., row-major or column-major order).</li><li><a href="https://numpy.org/doc/stable/user/basics.vectorization.html"><strong>Vectorization</strong></a><strong>:</strong> The practice of using NumPy’s array operations to replace explicit loops, thereby improving performance.</li><li><a href="https://numpy.org/doc/stable/reference/ufuncs.html#ufuncs-kwargs"><strong>In-place Operations</strong></a><strong>:</strong> Modify arrays directly, which can save memory and improve performance.</li></ul><h4>This list covers the main terms and concepts mentioned in the cheat sheet.</h4><p><em>“Originally published on </em><a href="https://danielforgechronicles.vercel.app/resource/blog/pandas-extensive-cheatsheet"><em>DanielForgeChronicles</em></a><em>”</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=80ec5e5c7d24" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ Pandas Extensive CheatSheet]]></title>
            <link>https://danielhashmi.medium.com/pandas-extensive-cheatsheet-a6b87f7959a1?source=rss-54f99fe76131------2</link>
            <guid isPermaLink="false">https://medium.com/p/a6b87f7959a1</guid>
            <category><![CDATA[data-analysis]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[pandas]]></category>
            <category><![CDATA[python-pandas]]></category>
            <category><![CDATA[python]]></category>
            <dc:creator><![CDATA[Daniel Hashmi]]></dc:creator>
            <pubDate>Sat, 22 Feb 2025 05:50:30 GMT</pubDate>
            <atom:updated>2025-02-22T05:50:30.109Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="Pandas Image" src="https://cdn-images-1.medium.com/max/750/1*o9ROhzDNla0TiE8vfgagdg.png" /><figcaption>Pandas Image</figcaption></figure><h3>🚀 1. Introduction to Pandas</h3><h4>Who Created Pandas?</h4><blockquote><em>The </em><strong><em>creator</em></strong><em> of pandas is </em><strong><em>Wes McKinney</em></strong><em>. He is an American </em><strong><em>software developer</em></strong><em> who developed the </em><strong><em>open-source</em></strong><em> Python library </em><em>&quot;pandas&quot; for </em><strong><em>data analysis</em></strong><em>.</em></blockquote><h4>What is Pandas?</h4><ul><li><strong>Pandas</strong> is a powerful Python library for data analysis and manipulation.</li><li>It provides tools to work with structured data like tables and spreadsheets.</li></ul><h4>Why is it called Pandas?</h4><ul><li>The name <strong>Pandas</strong> comes from <strong>‘Panel Data’</strong> — a term in statistics referring to multi-dimensional data, This might be confusing so you can check it out on <a href="https://en.wikipedia.org/wiki/Pandas_(software)#:~:text=The%20name%20is%20derived%20from%20the%20term%20%22panel%20data%22%2C%20an%20econometrics%20term%20for%20data%20sets%20that%20include%20observations%20over%20multiple%20time%20periods%20for%20the%20same%20individuals%2C%5B3%5D%20as%20well%20as%20a%20play%20on%20the%20phrase%20%22Python%20data%20analysis%22">Wiki</a>.</li></ul><h4>Importing Pandas</h4><pre>import pandas as pd</pre><ul><li><strong>Explanation:</strong> This line imports the pandas library into your project and gives it the alias pd. Using pd saves you from typing the full name “pandas” every time you call a function from the library. Although you can choose another name, pd is the standard convention.</li></ul><h3>📏 2. Pandas Data Structures</h3><h4>1D and 2D Data Structures</h4><ul><li><strong>Series</strong> (1D): Think of it as a single column in Excel, where each element has an index.</li><li><strong>DataFrame</strong> (2D): This is like a full table with rows and multiple columns.</li></ul><h4>Creating a Series</h4><pre>s = pd.Series([1, 2, 3, 4], name=&#39;Numbers&#39;, dtype=&#39;float64&#39;)<br>print(s)</pre><ul><li><strong>Explanation:</strong> This creates a Series with four values. The series is given a name (“Numbers”) and its data type is forced to be float64. This ensures all values are treated as floats, which can be important when doing mathematical operations.</li></ul><h4>Creating a DataFrame</h4><pre>data = [[&#39;Alice&#39;, 25], [&#39;Bob&#39;, 30]]<br>df = pd.DataFrame(data, columns=[&#39;Name&#39;, &#39;Age&#39;], index=[&#39;A&#39;, &#39;B&#39;])<br>print(df)</pre><ul><li><strong>Explanation:</strong> This snippet creates a DataFrame using a list of lists. It assigns column names (“Name” and “Age”) and custom row labels (“A” and “B”). The DataFrame structure helps organize data in a table format, making it easier to perform operations on rows and columns.</li></ul><h3>📥 3. Importing and Exporting Data</h3><h4>Reading Files</h4><pre>pd.read_csv(&#39;file.csv&#39;, sep=&#39;;&#39;, header=0, skiprows=2)</pre><ul><li><strong>Explanation:</strong> This line reads a CSV file named file.csv. The sep=&#39;;&#39; tells pandas that the file uses a semicolon as the delimiter. The parameter header=0 means the first row contains column names, and skiprows=2 tells pandas to ignore the first two rows after the header. This is useful if the file contains extra header information or notes you don’t need.</li></ul><pre>pd.read_excel(&#39;file.xlsx&#39;, sheet_name=&#39;Sheet2&#39;, usecols=&#39;A:C&#39;)</pre><ul><li><strong>Explanation:</strong> This reads an Excel file called file.xlsx. It specifically opens the sheet named “Sheet2” and loads only the columns from A to C. This helps when you only need a part of a large Excel file.</li></ul><pre>pd.read_sql(&#39;SELECT * FROM table&#39;, con=engine)</pre><ul><li><strong>Explanation:</strong> This command executes a SQL query on a connected database (using the connection engine) and loads the resulting data into a DataFrame. It’s a powerful way to directly manipulate database query results using pandas.</li></ul><h4>Writing Files</h4><pre>df.to_csv(&#39;file.csv&#39;, index=False, encoding=&#39;utf-8&#39;)</pre><ul><li><strong>Explanation:</strong> This exports the DataFrame to a CSV file named file.csv. The parameter index=False prevents pandas from writing row indices to the file, while encoding=&#39;utf-8&#39; ensures the file supports a wide range of characters.</li></ul><pre>df.to_parquet(&#39;file.parquet&#39;, compression=&#39;snappy&#39;)</pre><ul><li><strong>Explanation:</strong> This saves the DataFrame as a Parquet file, which is a columnar storage format. The compression=&#39;snappy&#39; parameter compresses the file efficiently, making it ideal for handling large datasets while saving space.</li></ul><h3>🔍 4. Exploring Data</h3><pre>df.sample(3)</pre><ul><li><strong>Explanation:</strong> This function returns 3 random rows from the DataFrame. It’s a quick way to inspect your data and get a feel for its content, especially useful when working with very large datasets.</li></ul><pre>df.nunique()</pre><ul><li><strong>Explanation:</strong> This counts the number of unique values in each column. It helps you understand the diversity of data in each column, which is useful for data cleaning and preparation.</li></ul><pre>df.corr()</pre><ul><li><strong>Explanation:</strong> This calculates the correlation matrix for all numeric columns in the DataFrame. It shows how strongly each pair of columns is related, which can be key in identifying trends or relationships in your data.</li></ul><pre>df.memory_usage(deep=True)</pre><ul><li><strong>Explanation:</strong> This displays the memory usage of each column, including the true size of objects like strings. It helps in identifying which parts of your data might be optimized for better performance.</li></ul><h3>🎯 5. Selecting Data</h3><h4>Advanced Selection</h4><pre>df.loc[df[&#39;Age&#39;] &gt; 25, &#39;Name&#39;]</pre><ul><li><strong>Explanation:</strong> This line uses label-based indexing to select rows where the ‘Age’ column is greater than 25, and then returns the corresponding ‘Name’ values. It makes filtering data based on column conditions straightforward and readable.</li></ul><pre>df.iloc[1:3, 0:2]</pre><ul><li><strong>Explanation:</strong> Here, integer-based indexing is used with iloc. It selects rows 1 and 2 (remember, Python indexing starts at 0 and the end index is not included) and columns in positions 0 and 1. This method is handy when you want to select data by its numerical position rather than by label.</li></ul><h4>Conditional Selection</h4><pre>df.query(&#39;Age &gt; 25 &amp; Salary &lt; 70000&#39;)</pre><ul><li><strong>Explanation:</strong> The query method allows filtering using a string expression similar to SQL. This example returns rows where Age is greater than 25 and Salary is less than 70,000. It makes complex filtering conditions easier to write and understand.</li></ul><h3>🔧 6. Filtering Data</h3><pre>df[df[&#39;Name&#39;].str.contains(&#39;li&#39;)]</pre><ul><li><strong>Explanation:</strong> This filters the DataFrame to include only rows where the ‘Name’ column contains the substring ‘li’. It’s useful for searching text within a column. Note that this search is case-sensitive unless you adjust the parameters.</li></ul><pre>df[df[&#39;Age&#39;].between(20, 40)]</pre><ul><li><strong>Explanation:</strong> The between method filters rows to include only those where the ‘Age’ is between 20 and 40 (inclusive). This offers a concise way to apply a range filter on numeric data.</li></ul><h3>🔄 7. Sorting Data</h3><pre>df.sort_values([&#39;Age&#39;, &#39;Salary&#39;], ascending=[True, False])</pre><ul><li><strong>Explanation:</strong> This sorts the DataFrame first by the ‘Age’ column in ascending order, then by the ‘Salary’ column in descending order. Sorting your data can help in analyzing trends, such as identifying the highest salaries within age groups.</li></ul><pre>df.sort_index(ascending=False)</pre><ul><li><strong>Explanation:</strong> This command sorts the DataFrame by its index in reverse (descending) order. Sorting by index is useful when your index holds meaningful data, such as dates or unique identifiers.</li></ul><h3>🔀 8. Adding &amp; Removing Data</h3><h4>Advanced Column Operations</h4><pre>df.assign(Bonus = df[&#39;Salary&#39;] * 0.1)</pre><ul><li><strong>Explanation:</strong> The assign method creates a new column called ‘Bonus’ by calculating 10% of each value in the ‘Salary’ column. This operation is temporary and does not modify the original DataFrame unless you reassign it, making it great for testing new columns.</li></ul><pre>df.rename(columns={&#39;Age&#39;: &#39;Years&#39;}, inplace=True)</pre><ul><li><strong>Explanation:</strong> This permanently renames the ‘Age’ column to ‘Years’ in the DataFrame by using the rename method with inplace=True. Renaming columns can make the data clearer, especially if the current names are ambiguous.</li></ul><h4>Multi-Index Support</h4><pre>df.set_index([&#39;Name&#39;, &#39;Age&#39;])</pre><ul><li><strong>Explanation:</strong> This sets a hierarchical (multi-level) index using the ‘Name’ and ‘Age’ columns. A multi-index allows for more complex data grouping and easier access to subsets of your data.</li></ul><h3>📊 9. Aggregation &amp; Grouping</h3><pre>df.groupby(&#39;Department&#39;).agg({&#39;Salary&#39;: [&#39;mean&#39;, &#39;max&#39;], &#39;Age&#39;: &#39;median&#39;})</pre><ul><li><strong>Explanation:</strong> This groups the DataFrame by the ‘Department’ column and then calculates several statistics for each group: the mean and maximum of ‘Salary’ and the median of ‘Age’. It helps summarize data within each group to find overall trends.</li></ul><pre>df.groupby(&#39;City&#39;)[&#39;Sales&#39;].transform(lambda x: x - x.mean())</pre><ul><li><strong>Explanation:</strong> This groups data by ‘City’ and then centers the ‘Sales’ values by subtracting the average sales for each city. This transformation is useful for comparing individual sales to the city average.</li></ul><h4>Pivot Tables</h4><pre>df.pivot_table(values=&#39;Sales&#39;, index=&#39;Region&#39;, columns=&#39;Year&#39;, aggfunc=&#39;sum&#39;)</pre><ul><li><strong>Explanation:</strong> This creates a pivot table that summarizes sales data by region and year. It aggregates (sums) the sales values for each combination of ‘Region’ and ‘Year’, similar to pivot tables in Excel, which can be very useful for analysis.</li></ul><h3>🔥 10. Combining Data</h3><h4>Concatenation</h4><pre>pd.concat([df1, df2], axis=0)  # Stack vertically<br>pd.concat([df1, df2], axis=1)  # Stack horizontally</pre><ul><li><strong>Explanation:</strong> The concat function joins two DataFrames together. With axis=0, it stacks the DataFrames on top of each other (adding rows). With axis=1, it joins them side-by-side (adding columns). This is handy when you have related datasets you want to combine into a single DataFrame.</li></ul><h4>Merging Data</h4><pre>pd.merge(orders, customers, left_on=&#39;cust_id&#39;, right_on=&#39;id&#39;, how=&#39;left&#39;)</pre><ul><li><strong>Explanation:</strong> This command merges two DataFrames (orders and customers) based on matching values from cust_id in the orders DataFrame and id in the customers DataFrame. The how=&#39;left&#39; parameter means all rows from the orders DataFrame will be kept, and matching rows from the customers DataFrame will be joined in. This is similar to performing a left join in SQL.</li></ul><h3>🔄 11. Handling Missing Data</h3><pre>df.interpolate(method=&#39;linear&#39;)</pre><ul><li><strong>Explanation:</strong> This fills in missing values in the DataFrame by calculating linear interpolations between known values. It’s particularly useful for time series data where you expect a smooth transition between points.</li></ul><pre>df.ffill(limit=1)</pre><ul><li><strong>Explanation:</strong> The ffill (forward fill) method replaces missing values with the last valid observation, but only for up to 1 row at a time. This helps fill small gaps without overly distorting your data.</li></ul><pre>df.replace(-999, np.nan)</pre><ul><li><strong>Explanation:</strong> This replaces a specific placeholder value (-999) with NaN (Not a Number), which is the standard marker for missing data in pandas. Converting these placeholders to NaN allows pandas functions to handle missing values appropriately.</li></ul><h3>📆 12. DateTime Operations</h3><h4>Convert to DateTime</h4><pre>df[&#39;Date&#39;] = pd.to_datetime(df[&#39;Timestamp&#39;], format=&#39;%Y-%m-%d&#39;)</pre><ul><li><strong>Explanation:</strong> This converts a column containing timestamp strings into datetime objects using the specified format. Converting to datetime enables you to use pandas’ powerful time-based functions for filtering and analysis.</li></ul><h4>Date Calculations</h4><pre>df[&#39;Year&#39;] = df[&#39;Date&#39;].dt.year<br>df[&#39;Days_Since&#39;] = (pd.Timestamp.now() - df[&#39;Date&#39;]).dt.days</pre><ul><li><strong>Explanation:</strong> The first line extracts the year from each date, while the second calculates how many days have passed since each date. These operations are useful for breaking down date information and performing time-based comparisons.</li></ul><h4>Resampling</h4><pre>df.resample(&#39;M&#39;, on=&#39;Date&#39;)[&#39;Sales&#39;].sum()</pre><ul><li><strong>Explanation:</strong> This resamples the DataFrame by month using the ‘Date’ column, then sums up the ‘Sales’ values for each month. Resampling helps in aggregating time series data to observe trends over different time periods.</li></ul><h3>✨ 13. Advanced Techniques</h3><h4>Method Chaining</h4><pre>(df.sort_values(&#39;Date&#39;)<br>   .assign(Total=lambda x: x[&#39;Price&#39;] * x[&#39;Quantity&#39;])<br>   .query(&#39;Total &gt; 100&#39;))</pre><ul><li><strong>Explanation:</strong> This method chain performs several operations in one go. It first sorts the DataFrame by the ‘Date’ column, then creates a new column ‘Total’ by multiplying ‘Price’ and ‘Quantity’, and finally filters the rows where ‘Total’ is greater than 100. Chaining makes your code concise and easier to read by linking operations together.</li></ul><h4>Optimizing Performance</h4><pre>df = df.astype({&#39;Category&#39;: &#39;category&#39;, &#39;Price&#39;: &#39;float32&#39;})</pre><ul><li><strong>Explanation:</strong> This converts the data types of the ‘Category’ and ‘Price’ columns to more memory-efficient types. Using the category data type for textual data and float32 for numerical data reduces memory usage, which is crucial for handling large datasets.</li></ul><h4>Working with Text</h4><pre>df[&#39;Name&#39;] = df[&#39;Name&#39;].str.upper().str.replace(&#39; &#39;, &#39;_&#39;)</pre><ul><li><strong>Explanation:</strong> This line standardizes the text in the ‘Name’ column by converting all characters to uppercase and replacing spaces with underscores. Standardized text data can simplify further analysis and comparisons.</li></ul><p><strong>Hope</strong> this will <strong>definitely</strong> help you <strong>Master Pandas</strong> 💖</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a6b87f7959a1" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ultimate Git Cheat Sheet: Everything You Need to Know]]></title>
            <link>https://danielhashmi.medium.com/ultimate-git-cheat-sheet-everything-you-need-to-know-e24031045df7?source=rss-54f99fe76131------2</link>
            <guid isPermaLink="false">https://medium.com/p/e24031045df7</guid>
            <category><![CDATA[version-control]]></category>
            <category><![CDATA[git-cheat-sheet]]></category>
            <category><![CDATA[version-control-with-git]]></category>
            <category><![CDATA[github]]></category>
            <category><![CDATA[git]]></category>
            <dc:creator><![CDATA[Daniel Hashmi]]></dc:creator>
            <pubDate>Fri, 21 Feb 2025 14:20:26 GMT</pubDate>
            <atom:updated>2025-03-12T13:37:52.597Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="Git Logo" src="https://cdn-images-1.medium.com/max/1024/1*GVGVGJuEsa5YUjCKM2ailQ.png" /><figcaption>Git Logo</figcaption></figure><p>📌 <strong>Master Git with essential commands, workflows, pro techniques, and advanced tricks!</strong></p><h3>🌱 Getting Started with Git</h3><ul><li>git init – Initialize a new Git repository</li><li>git clone &lt;repo_url&gt; – Clone an existing repository</li><li>git config --global user.name &quot;Your Name&quot; – Set Git username</li><li>git config --global user.email &quot;you@example.com&quot; – Set Git email</li><li>git config --list – Show all Git configurations</li></ul><h3>📌 Tracking &amp; Staging Changes</h3><ul><li>git status – Show the status of the working directory</li><li>git add &lt;file&gt; – Stage a specific file</li><li>git add . – Stage all changes</li><li>git reset &lt;file&gt; – Unstage a file</li><li>git reset . – Unstage all changes</li><li>git reset --hard – Remove all changes (⚠ Irreversible!)</li></ul><h3>📜 Committing Changes</h3><ul><li>git commit -m &quot;message&quot; – Commit staged changes</li><li>git commit --amend -m &quot;new message&quot; – Edit the last commit message</li><li>git commit -a -m &quot;message&quot; – Add &amp; commit tracked files</li><li>git log – View commit history</li><li>git log --oneline – Short log format</li><li>git diff – Show unstaged changes</li><li>git diff --staged – Show staged changes</li></ul><h3>🌿 Branching &amp; Merging</h3><ul><li>git branch – List branches</li><li>git branch &lt;branch_name&gt; – Create a new branch</li><li>git checkout &lt;branch_name&gt; – Switch to another branch</li><li>git checkout -b &lt;branch_name&gt; – Create &amp; switch to a new branch</li><li>git merge &lt;branch_name&gt; – Merge a branch into the current one</li><li>git branch -d &lt;branch_name&gt; – Delete a branch</li><li>git branch -D &lt;branch_name&gt; – Force delete a branch</li></ul><h3>🌍 Remote Repositories</h3><ul><li>git remote -v – Show connected remotes</li><li>git remote add origin &lt;repo_url&gt; – Connect local repo to remote</li><li>git push -u origin &lt;branch&gt; – Push changes to remote repo</li><li>git push – Push committed changes</li><li>git pull origin &lt;branch&gt; – Pull latest changes from a branch</li><li>git fetch – Fetch changes from remote without merging</li></ul><h3>🔄 Undo &amp; Reset Changes</h3><ul><li>git checkout -- &lt;file&gt; – Discard local changes in a file</li><li>git reset --soft HEAD~1 – Undo last commit (keep changes)</li><li>git reset --mixed HEAD~1 – Undo commit &amp; unstage changes</li><li>git reset --hard HEAD~1 – Undo commit &amp; delete changes (⚠ Irreversible!)</li><li>git revert &lt;commit_hash&gt; – Undo a commit by creating a new one</li><li>git reflog – View history of HEAD movements</li></ul><h3>🕵️ Logs &amp; History</h3><ul><li>git log --graph --oneline --all – View a simple commit graph</li><li>git blame &lt;file&gt; – See who last edited each line</li><li>git show &lt;commit_hash&gt; – Show details of a specific commit</li><li>git shortlog -sn – See contributors ranked by commits</li></ul><h3>🏷️ Tagging (Versioning)</h3><ul><li>git tag &lt;tag_name&gt; – Create a tag</li><li>git tag – List all tags</li><li>git push --tags – Push tags to remote</li><li>git tag -d &lt;tag_name&gt; – Delete a tag</li></ul><h3>🔀 Git Stashing (Temporary Save)</h3><ul><li>git stash – Save changes without committing</li><li>git stash push -m &quot;message&quot; – Save stash with a name</li><li>git stash pop – Restore the last stash</li><li>git stash list – View all saved stashes</li><li>git stash show -p stash@{0} – View stash contents</li><li>git stash drop – Delete the latest stash</li></ul><h3>🛠️ Advanced Git Commands</h3><h3>Rebasing &amp; Rewriting History</h3><ul><li>git rebase &lt;branch&gt; – Reapply commits on top of another branch</li><li>git rebase -i HEAD~3 – Interactive rebase (edit last 3 commits)</li><li>git cherry-pick &lt;commit_hash&gt; – Apply a commit from another branch</li><li>git replace &lt;bad_commit&gt; &lt;good_commit&gt; – Temporarily replace a commit</li><li>git filter-branch --tree-filter &#39;rm -rf secrets/&#39; HEAD – Remove sensitive files from history (⚠ Dangerous)</li></ul><h3>Debugging &amp; Fixing Issues</h3><ul><li>git bisect start – Begin binary search for a bad commit</li><li>git bisect bad – Mark current commit as bad</li><li>git bisect good &lt;commit&gt; – Mark a known good commit</li><li>git bisect reset – End bisecting</li></ul><h3>📦 Submodules &amp; Subtrees (Multi-Repo Projects)</h3><h3>Submodules</h3><ul><li>git submodule add &lt;repo_url&gt; – Add a submodule</li><li>git submodule update --init --recursive – Clone &amp; update all submodules</li><li>git submodule foreach git pull origin main – Update all submodules</li></ul><h3>Subtrees</h3><ul><li>git subtree add --prefix=&lt;dir&gt; &lt;repo_url&gt; &lt;branch&gt; – Add a repository as a subtree</li><li>git subtree pull --prefix=&lt;dir&gt; &lt;repo_url&gt; &lt;branch&gt; – Pull latest changes from a subtree</li></ul><h3>🚀 Force &amp; Safety Measures</h3><ul><li>git push --force – Force push (⚠ Use with caution!)</li><li>git push --force-with-lease – Safer force push (checks if no one else has pushed)</li></ul><h3>🔄 Syncing &amp; Collaboration</h3><ul><li>git pull --rebase – Pull latest changes and rebase instead of merge</li><li>git push origin --delete &lt;branch&gt; – Delete a remote branch</li></ul><h3>🔥 Pro-Level Git Workflows</h3><h3>Feature Branch Workflow</h3><ul><li>Use separate branches for each feature</li><li>Merge only when the feature is complete</li></ul><h3>Git Flow (Popular for Teams)</h3><ul><li>main – Stable production branch</li><li>develop – Main development branch</li><li>feature/* – Branches for new features</li><li>release/* – Prepares for release</li><li>hotfix/* – Emergency fixes</li></ul><h3>Forking Workflow (For Open-Source Contributions)</h3><ol><li>Fork the repo</li><li>Clone it locally</li><li>Create a new branch</li><li>Make changes and push</li><li>Submit a pull request</li></ol><h3>🧪 Git Hooks (Automate Workflows)</h3><ul><li>.git/hooks/pre-commit – Runs before committing</li><li>.git/hooks/pre-push – Runs before pushing</li><li>.git/hooks/post-merge – Runs after merging</li></ul><h3>🔥 Git Aliases (Shortcuts to Save Time)</h3><ul><li>git config --global alias.st status – Make git st show status</li><li>git config --global alias.ci commit – Make git ci commit changes</li><li>git config --global alias.unstage &quot;reset HEAD --&quot; – Make git unstage &lt;file&gt; remove from staging</li></ul><h3>☿ Quick Setup (Setting Up Git)</h3><p>• <strong>git init</strong><br>Initializes a new Git repository in your project directory.</p><p>• <strong>git add .</strong><br>Stages all files in your project for commit.<br><strong>Note:</strong> Be cautious when adding sensitive files, such as .env.local. You might want to add them to .gitignore to prevent them from being tracked.</p><p>• <strong>git commit -m &#39;message&#39;</strong><br>Commits the staged files with a descriptive message.<br><strong>Example:</strong> git commit -m &#39;Initial commit&#39;<br>Choose clear and concise commit messages for better version history tracking.</p><p>• <strong>git branch -M main</strong><br>Renames the default branch to main. This is the new standard for Git repositories, replacing the older master branch.</p><p>• <strong>git remote add origin &#39;your-repo-link&#39;</strong><br>Links your local repository to a remote repository (e.g., GitHub, GitLab, Bitbucket).<br><strong>Example:</strong> git remote add origin <a href="https://github.com/username/repository.git">https://github.com/username/repository.git</a></p><p>• <strong>git pull origin main --allow-unrelated-histories</strong><br>Pulls the latest changes from the remote main branch to your local repository, allowing for unrelated histories (useful when combining repositories or working with an existing repo).</p><p>• <strong>git push -u origin main</strong><br>Pushes your local commits to the remote main branch. The -u flag sets up tracking, so in the future, you can simply use git push to push changes.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e24031045df7" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Setup UV In Windows]]></title>
            <link>https://blog.devgenius.io/setup-uv-in-windows-a43385a397ce?source=rss-54f99fe76131------2</link>
            <guid isPermaLink="false">https://medium.com/p/a43385a397ce</guid>
            <category><![CDATA[package-manager]]></category>
            <category><![CDATA[uv-package-manager]]></category>
            <category><![CDATA[pip]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[uv]]></category>
            <dc:creator><![CDATA[Daniel Hashmi]]></dc:creator>
            <pubDate>Thu, 20 Feb 2025 05:00:41 GMT</pubDate>
            <atom:updated>2025-03-01T16:12:20.677Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="UV LOGO" src="https://cdn-images-1.medium.com/max/1024/1*tnUzdHdveFNp2IoeN7Sc-Q.png" /><figcaption>UV LOGO</figcaption></figure><h3>Let’s install UV Package Manager in your windows</h3><p>Run this in your powershell</p><pre>irm https://astral.sh/uv/install.ps1 | iex</pre><ul><li>Press <strong>Win + R</strong>, type sysdm.cpl, and hit <strong>Enter</strong>.</li><li>Go to the <strong>Advanced</strong> tab.</li><li>Click <strong>Environment Variables</strong></li><li>Under <strong>User variables section</strong>, find and select Path, then click <strong>Edit</strong>.</li><li>Click <strong>New</strong>, then enter:</li></ul><pre>C:\Users\&quot;username&quot;\.local\bin</pre><ul><li>Make sure to replace &quot;username&quot; with your actual PC username</li><li>Click <strong>OK</strong> on all windows to save changes.</li><li>Restart your <strong>Powershell</strong>.</li></ul><p>Run</p><pre>uv --version</pre><p>You should see something like this 🎉</p><pre>uv 0.6.2 (6d3614eec 2025-02-19)</pre><h3>Let’s Test It</h3><p>Install pyfiglet Package</p><pre>uv pip install pyfiglet --system</pre><p>Run this code</p><pre>import pyfiglet<br><br>ascii_art = pyfiglet.figlet_format(&quot;Hello UV!&quot;)<br>print(ascii_art)</pre><p>You should see <strong>Hello UV!</strong></p><pre> _   _      _ _         _   ___     ___ <br>| | | | ___| | | ___   | | | \ \   / / |<br>| |_| |/ _ \ | |/ _ \  | | | |\ \ / /| |<br>|  _  |  __/ | | (_) | | |_| | \ V / |_|<br>|_| |_|\___|_|_|\___/   \___/   \_/  (_)</pre><p>Clap 👏 if it really helped! 🧡</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a43385a397ce" width="1" height="1" alt=""><hr><p><a href="https://blog.devgenius.io/setup-uv-in-windows-a43385a397ce">Setup UV In Windows</a> was originally published in <a href="https://blog.devgenius.io">Dev Genius</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Easily Integrate Stripe in Next.js 15 App Router]]></title>
            <link>https://danielhashmi.medium.com/easily-integrate-stripe-in-next-js-15-app-router-9fa16230c80b?source=rss-54f99fe76131------2</link>
            <guid isPermaLink="false">https://medium.com/p/9fa16230c80b</guid>
            <category><![CDATA[nextjs]]></category>
            <category><![CDATA[stripe-integration]]></category>
            <category><![CDATA[stripe]]></category>
            <category><![CDATA[payments]]></category>
            <category><![CDATA[app-router]]></category>
            <dc:creator><![CDATA[Daniel Hashmi]]></dc:creator>
            <pubDate>Mon, 17 Feb 2025 17:12:58 GMT</pubDate>
            <atom:updated>2025-02-18T04:22:41.345Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="Stripe Image" src="https://cdn-images-1.medium.com/max/880/1*q6J8rRpbZxpk7tunQMnsDw.png" /><figcaption>Stripe Image</figcaption></figure><h3>1. Install Required Packages</h3><p>To begin integrating Stripe, install the necessary dependencies:</p><pre>npm install stripe @stripe/stripe-js react-stripe-js @stripe/react-stripe-js</pre><h3>2. Configure Environment Variables</h3><p>Add the following environment variables in your .env.local file:</p><pre>NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_your_test_publishable_key<br>STRIPE_SECRET_KEY=sk_test_your_text_secret_key<br>NEXT_PUBLIC_BASE_URL=http://localhost:3000</pre><ul><li>NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: The publishable key from Stripe for the client-side.</li><li>STRIPE_SECRET_KEY: The secret key from Stripe for server-side operations.</li><li>NEXT_PUBLIC_BASE_URL: The base URL of your app.</li></ul><h3>3. Create Payment Intent API Route</h3><p>Create app/api/payment-intent/route.ts to handle payment requests:</p><pre>import { NextRequest, NextResponse } from &quot;next/server&quot;;<br>import Stripe from &quot;stripe&quot;;<br><br>const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string, {<br>  apiVersion: &quot;2025-01-27.acacia&quot;,<br>});<br><br>export async function POST(request: NextRequest): Promise&lt;NextResponse&gt; {<br>  try {<br>    const { amount }: { amount: number } = await request.json();<br><br>    const paymentIntent = await stripe.paymentIntents.create({<br>      amount: amount,<br>      currency: &quot;usd&quot;,<br>      automatic_payment_methods: { enabled: true },<br>    });<br><br>    return NextResponse.json({<br>      clientSecret: paymentIntent.client_secret,<br>      paymentIntentId: paymentIntent.id,<br>    });<br>  } catch (error) {<br>    console.error(&quot;Internal Error:&quot;, error);<br>    return NextResponse.json(<br>      { error: `Internal Server Error: ${error}` },<br>      { status: 500 }<br>    );<br>  }<br>}</pre><h3>Explanation:</h3><ul><li>This route handles POST requests to create a payment intent.</li><li>Uses the Stripe secret key to create a payment intent with the requested amount.</li><li>Returns the clientSecret for further processing on the frontend.</li></ul><h3>4. Create the Stripe Payment Element</h3><p>Create app/components/StripeElement/page.tsx</p><pre>&#39;use client&#39;<br>import React, { useEffect, useState } from &#39;react&#39;<br>import {<br>    useStripe,<br>    useElements,<br>    PaymentElement,<br>} from &quot;@stripe/react-stripe-js&quot;;<br><br>const StripeElement = () =&gt; {<br>    const stripe = useStripe();<br>    const elements = useElements();<br>    const [errorMessage, setErrorMessage] = useState&lt;string&gt;();<br>    const [clientSecret, setClientSecret] = useState(&quot;&quot;);<br>    const [loading, setLoading] = useState(false);<br><br>    useEffect(() =&gt; {<br>        fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/payment-intent`, {<br>            method: &quot;POST&quot;,<br>            headers: { &quot;Content-Type&quot;: &quot;application/json&quot; },<br>            body: JSON.stringify({ amount: 1500 }),<br>        })<br>            .then((res) =&gt; res.json())<br>            .then((data) =&gt; setClientSecret(data.clientSecret));<br>    }, []);<br><br>    const handleSubmit = async (e: React.FormEvent) =&gt; {<br>        e.preventDefault();<br>        try {<br>            setLoading(true);<br>            if (!stripe || !elements) return;<br><br>            const { error: submitError } = await elements.submit();<br>            if (submitError) {<br>                setErrorMessage(submitError.message);<br>                setLoading(false);<br>                return;<br>            }<br><br>            const { error } = await stripe.confirmPayment({<br>                elements,<br>                clientSecret,<br>                confirmParams: {<br>                    return_url: `${process.env.NEXT_PUBLIC_BASE_URL}/success`,<br>                },<br>            });<br>            setErrorMessage(error?.message);<br>            setLoading(false);<br>        } catch (err) {<br>            console.log(err);<br>        }<br>    }<br><br>    return (<br>        &lt;div className=&quot;flex justify-center bg-[#f6f7f9] py-6 h-screen&quot;&gt;<br>            &lt;form className=&quot;w-full flex flex-col gap-6&quot; onSubmit={handleSubmit}&gt;<br>                &lt;div className=&quot;bg-white p-6 rounded-xl flex flex-col gap-6&quot;&gt;<br>                    {clientSecret ? &lt;PaymentElement /&gt; :<br>                        &lt;div className=&#39;w-full bg-gray-200 h-10 animate-pulse&#39;&gt;&lt;/div&gt;<br>                    }<br>                    {errorMessage &amp;&amp; &lt;div className=&#39;text-xs text-red-600&#39;&gt;{errorMessage}&lt;/div&gt;}<br><br>                    &lt;button disabled={!stripe || loading} className=&quot;px-4 py-2 w-fit text-sm md:text-base bg-yellow-600 hover:bg-yellow-800 transition-all disabled:opacity-50 text-white rounded-md&quot;&gt;<br>                        {!loading ? `Pay $${15}` : &quot;Processing...&quot;}<br>                    &lt;/button&gt;<br>                &lt;/div&gt;<br>            &lt;/form&gt;<br>        &lt;/div&gt;<br>    )<br>};<br>export default StripeElement;</pre><ul><li>Fetches the payment intent clientSecret on component mount.</li><li>Uses PaymentElement from react-stripe-js for UI rendering.</li><li>Handles payment confirmation on form submission.</li></ul><h3>5. Use Stripe Element in the Payment Page</h3><p>Modify app/page.tsx to include the payment element:</p><pre>&#39;use client&#39;<br>import { Elements } from &quot;@stripe/react-stripe-js&quot;;<br>import { loadStripe } from &quot;@stripe/stripe-js&quot;;<br>import StripeElement from &quot;./components/StripeElement/page&quot;;<br><br>if (process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY === undefined) {<br>  throw new Error(&quot;NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY is not defined&quot;);<br>}<br>const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);<br><br>const Home = () =&gt; {<br>  return (<br>    &lt;Elements stripe={stripePromise} options={{ mode: &quot;payment&quot;, amount: 1500, currency: &quot;usd&quot; }}&gt;<br>      &lt;StripeElement /&gt;<br>    &lt;/Elements&gt;<br>  )<br>}<br>export default Home;</pre><h3>Explanation:</h3><ul><li>Wraps StripeElement inside &lt;Elements&gt; for Stripe functionality.</li><li>Uses loadStripe with the publishable key.</li></ul><h3>6. Create Success and Cancel Pages (Optional)</h3><h3>Success Page (app/success/page.tsx):</h3><pre>export default function SuccessPage() {<br>    return (<br>      &lt;div className=&quot;flex flex-col gap-6 justify-center items-center h-screen text-center p-6&quot;&gt;<br>        &lt;h1 className=&#39;text-7xl text-yellow-600&#39;&gt;Payment Successful!&lt;/h1&gt;<br>        &lt;p className=&#39;font-bold text-xl&#39;&gt;Check your Stripe account for transaction history.&lt;/p&gt;<br>      &lt;/div&gt;<br>    );<br>}</pre><h3>Cancel Page (app/cancel/page.tsx):</h3><pre>export default function CancelPage() {<br>    return (<br>        &lt;div className=&quot;flex flex-col gap-6 justify-center items-center h-screen text-center p-6&quot;&gt;<br>            &lt;h1 className=&#39;text-7xl text-red-600&#39;&gt;Payment Cancelled!&lt;/h1&gt;<br>            &lt;p className=&#39;font-bold text-xl&#39;&gt;Your payment was not completed. Please try again!&lt;/p&gt;<br>        &lt;/div&gt;<br>    );<br>}</pre><h4>Hope this guide helps you! 🧡</h4><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9fa16230c80b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Next.js 15: Modern Development]]></title>
            <link>https://danielhashmi.medium.com/next-js-15-modern-development-68efc77374c6?source=rss-54f99fe76131------2</link>
            <guid isPermaLink="false">https://medium.com/p/68efc77374c6</guid>
            <category><![CDATA[nextjs-tutorial]]></category>
            <category><![CDATA[nextjs]]></category>
            <category><![CDATA[react-framework]]></category>
            <category><![CDATA[nextjs-15]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[Daniel Hashmi]]></dc:creator>
            <pubDate>Fri, 14 Feb 2025 13:27:08 GMT</pubDate>
            <atom:updated>2025-02-14T13:27:08.568Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="nextjs" src="https://cdn-images-1.medium.com/max/1024/1*nrQo8jir8N7g69zk6xPGUg.png" /></figure><h3>1. Routing in the App Router</h3><p>In Next.js 15, routes are defined within the app directory. Each folder represents a route, and a page.tsx file within that folder corresponds to the route’s content.</p><h3>File Structure:</h3><pre>app/<br>  ├─ about/<br>  │   └─ page.tsx<br>  └─ contact/<br>      └─ page.tsx</pre><h3>Example: app/about/page.tsx</h3><pre>export default function AboutPage() {<br>  return &lt;h1&gt;About Us&lt;/h1&gt;;<br>}</pre><h3>Example: app/contact/page.tsx</h3><pre>export default function ContactPage() {<br>  return &lt;h1&gt;Contact Us&lt;/h1&gt;;<br>}</pre><p>Navigating to /about will render the AboutPage component, while /contact will render the ContactPage component.</p><h3>2. Dynamic and Catch-All Routes</h3><p>Next.js 15 allows dynamic and catch-all routes to create flexible routing structures.</p><ul><li><strong>Dynamic routes</strong> use [slug] to represent URL parameters.</li><li><strong>Catch-all routes</strong> use [...param] to handle multiple path segments dynamically.</li></ul><h3>File Structure:</h3><pre>app/<br>  ├─ blog/<br>  │   ├─ [slug]/<br>  │   │   └─ page.tsx<br>  │   └─ [...categories]/<br>  │       └─ page.tsx</pre><h3>Example: app/blog/[slug]/page.tsx</h3><pre>interface BlogPostProps {<br>  params: Promise&lt;{ slug: string }&gt;;<br>}</pre><pre>export default async function BlogPost({ params }: BlogPostProps) {<br>  const { slug } = await params;<br>  return &lt;h1&gt;Blog Post: {slug}&lt;/h1&gt;;<br>}</pre><h3>Example: app/blog/[...categories]/page.tsx</h3><pre>interface BlogCategoriesProps {<br>  params: Promise&lt;{ categories: string[] }&gt;;<br>}</pre><pre>export default async function BlogCategories({ params }: BlogCategoriesProps) {<br>  const { categories } = await params;<br>  return &lt;h1&gt;Categories: {categories.join(&#39; &gt; &#39;)}&lt;/h1&gt;;<br>}</pre><ul><li>Visiting /blog/nextjs-routing will display <strong>“Blog Post: nextjs-routing”</strong>.</li><li>Visiting /blog/tech/frontend/react will display <strong>“Categories: tech &gt; frontend &gt; react”</strong>.</li></ul><h3>3. Data Fetching Methods</h3><p>In the App Router, <strong>data fetching</strong> can be performed <strong>inside Server Components</strong> using fetch().</p><h3>Example: app/users/page.tsx</h3><pre>interface User {<br>  id: number;<br>  name: string;<br>}</pre><pre>export default async function UsersPage() {<br>  const res = await fetch(&#39;https://jsonplaceholder.typicode.com/users&#39;);<br>  const users: User[] = await res.json();</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;h1&gt;Users List&lt;/h1&gt;<br>      &lt;ul&gt;<br>        {users.map((user) =&gt; (<br>          &lt;li key={user.id}&gt;{user.name}&lt;/li&gt;<br>        ))}<br>      &lt;/ul&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><p>This component <strong>fetches user data at build time</strong> and renders a list of users.</p><h3>4. Incremental Static Regeneration (ISR)</h3><p>ISR allows pages to update static content <strong>after a set time</strong> without needing a full rebuild. In the App Router, you use the revalidate property.</p><h3>Example: app/posts/page.tsx</h3><pre>interface Post {<br>  id: number;<br>  title: string;<br>}</pre><pre>export const revalidate = 60; // Revalidate every 60 seconds</pre><pre>export default async function PostsPage() {<br>  const res = await fetch(&#39;https://jsonplaceholder.typicode.com/posts&#39;);<br>  const posts: Post[] = await res.json();</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;h1&gt;Blog Posts&lt;/h1&gt;<br>      &lt;ul&gt;<br>        {posts.map((post) =&gt; (<br>          &lt;li key={post.id}&gt;{post.title}&lt;/li&gt;<br>        ))}<br>      &lt;/ul&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><p>This page will <strong>revalidate its data every 60 seconds</strong>, ensuring freshness without requiring a full deployment.</p><h3>5. Client-Side Data Fetching</h3><p>For <strong>client-side data fetching</strong>, Next.js recommends using libraries like <strong>SWR</strong> or <strong>React Query</strong>.</p><h3>Example: app/profile/page.tsx</h3><pre>&#39;use client&#39;;</pre><pre>import useSWR from &#39;swr&#39;;</pre><pre>interface Profile {<br>  name: string;<br>  email: string;<br>}</pre><pre>const fetcher = (url: string) =&gt; fetch(url).then((res) =&gt; res.json());</pre><pre>export default function ProfilePage() {<br>  const { data, error } = useSWR&lt;Profile&gt;(&#39;/api/profile&#39;, fetcher);</pre><pre>  if (error) return &lt;div&gt;Failed to load&lt;/div&gt;;<br>  if (!data) return &lt;div&gt;Loading...&lt;/div&gt;;</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;h1&gt;{data.name}&#39;s Profile&lt;/h1&gt;<br>      &lt;p&gt;Email: {data.email}&lt;/p&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><p>This component <strong>fetches profile data on the client side</strong>, allowing for <strong>real-time updates</strong> without requiring a full page reload.</p><h3>6. Middleware Usage</h3><p>Middleware in Next.js allows you to run code before a request is completed, such as authentication or redirect logic.</p><h3>Example: middleware.ts</h3><pre>import { NextResponse } from &#39;next/server&#39;;</pre><pre>export function middleware(request: Request) {<br>  const url = request.nextUrl.clone();<br>  <br>  // Redirect from &#39;/old-path&#39; to &#39;/new-path&#39;<br>  if (url.pathname === &#39;/old-path&#39;) {<br>    url.pathname = &#39;/new-path&#39;;<br>    return NextResponse.redirect(url);<br>  }</pre><pre>  return NextResponse.next(); // Proceed with the request if no redirect<br>}</pre><p>This middleware intercepts requests to /old-path and redirects them to /new-path.</p><h3>7. Image Optimization</h3><p>Next.js provides the Image component to automatically optimize images, making them more efficient for performance.</p><h3>Example: app/gallery/page.tsx</h3><pre>import Image from &#39;next/image&#39;;</pre><pre>export default function GalleryPage() {<br>  return (<br>    &lt;div&gt;<br>      &lt;h1&gt;Gallery&lt;/h1&gt;<br>      &lt;Image<br>        src=&quot;/images/photo.jpg&quot;<br>        alt=&quot;Sample Photo&quot;<br>        width={600}<br>        height={400}<br>      /&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><p>This component will automatically optimize the image for better performance, reducing load time.</p><h3>8. Static Site Generation (SSG)</h3><p>Pages are statically generated by default in Next.js 15. This means the page is pre-rendered at build time.</p><h3>Example: app/products/page.tsx</h3><pre>interface Product {<br>  id: number;<br>  title: string;<br>}</pre><pre>export default async function ProductsPage() {<br>  const res = await fetch(&#39;https://fakestoreapi.com/products&#39;);<br>  const products: Product[] = await res.json();</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;h1&gt;Products&lt;/h1&gt;<br>      &lt;ul&gt;<br>        {products.map((product) =&gt; (<br>          &lt;li key={product.id}&gt;{product.title}&lt;/li&gt;<br>        ))}<br>      &lt;/ul&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><p>This page will be <strong>statically generated</strong> at build time, fetching product data from an external API.</p><h3>9. Server Components</h3><p>Server Components in Next.js 15 allow rendering on the server by default, improving performance by reducing the load on the client.</p><h3>Example: app/dashboard/page.tsx</h3><pre>interface Data {<br>  value: string;<br>}</pre><pre>export default async function DashboardPage() {<br>  const res = await fetch(&#39;https://api.example.com/data&#39;);<br>  const data: Data = await res.json();</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;h1&gt;Dashboard&lt;/h1&gt;<br>      &lt;p&gt;Data: {data.value}&lt;/p&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><p>This <strong>Server Component</strong> fetches the data on the server and renders it, resulting in a faster initial page load for the user.</p><h3>10. Authentication Strategies</h3><p>Next.js provides a simple way to implement authentication using <strong>NextAuth.js</strong>. This example shows how to authenticate using GitHub as the provider.</p><h3>Installation:</h3><pre>npm install next-auth</pre><h3>app/api/auth/[...nextauth]/route.ts</h3><pre>import NextAuth from &#39;next-auth&#39;;<br>import GitHubProvider from &#39;next-auth/providers/github&#39;;</pre><pre>const handler = NextAuth({<br>  providers: [<br>    GitHubProvider({<br>      clientId: process.env.GITHUB_ID,<br>      clientSecret: process.env.GITHUB_SECRET,<br>    }),<br>  ],<br>});</pre><pre>export { handler as GET, handler as POST };</pre><h3>app/layout.tsx</h3><pre>&#39;use client&#39;;</pre><pre>import { SessionProvider } from &#39;next-auth/react&#39;;</pre><pre>export default function RootLayout({ children }: { children: React.ReactNode }) {<br>  return (<br>    &lt;html lang=&quot;en&quot;&gt;<br>      &lt;body&gt;<br>        &lt;SessionProvider&gt;{children}&lt;/SessionProvider&gt;<br>      &lt;/body&gt;<br>    &lt;/html&gt;<br>  );<br>}</pre><h3>app/page.tsx</h3><pre>&#39;use client&#39;;</pre><pre>import { useSession, signIn, signOut } from &#39;next-auth/react&#39;;</pre><pre>export default function HomePage() {<br>  const { data: session } = useSession();</pre><pre>  if (session) {<br>    return (<br>      &lt;div&gt;<br>        &lt;p&gt;Welcome, {session.user?.name}&lt;/p&gt;<br>        &lt;button onClick={() =&gt; signOut()}&gt;Sign out&lt;/button&gt;<br>      &lt;/div&gt;<br>    );<br>  } else {<br>    return (<br>      &lt;div&gt;<br>        &lt;p&gt;You are not signed in.&lt;/p&gt;<br>        &lt;button onClick={() =&gt; signIn()}&gt;Sign in&lt;/button&gt;<br>      &lt;/div&gt;<br>    );<br>  }<br>}</pre><p>This setup enables <strong>GitHub authentication</strong> in your Next.js application. It includes the NextAuth.js API route for authentication handling and session management in the UI.</p><h3>11. API Routes and Middleware</h3><p>Creating an <strong>API route</strong> with middleware in the App Router.</p><h3>app/api/hello/route.ts</h3><pre>export async function GET(request: Request) {<br>  return new Response(JSON.stringify({ message: &#39;Hello, world!&#39; }), {<br>    headers: { &#39;Content-Type&#39;: &#39;application/json&#39; },<br>  });<br>}</pre><p>This API route responds with a JSON message when a GET request is made to /api/hello.</p><h3>middleware.ts</h3><pre>import { NextResponse } from &#39;next/server&#39;;</pre><pre>export function middleware(request: Request) {<br>  const { pathname } = request.nextUrl;</pre><pre>  if (pathname.startsWith(&#39;/api&#39;)) {<br>    // Add a custom header to all API responses<br>    const response = NextResponse.next();<br>    response.headers.set(&#39;X-Custom-Header&#39;, &#39;my-custom-header&#39;);<br>    return response;<br>  }</pre><pre>  return NextResponse.next();<br>}</pre><p>This middleware adds a custom header (X-Custom-Header) to all API responses.</p><h3>12. Styling Techniques</h3><h3>Tailwind CSS Setup</h3><p>To style your application using <strong>Tailwind CSS</strong>, follow these steps:</p><h3>Installation:</h3><pre>npm install -D tailwindcss postcss autoprefixer<br>npx tailwindcss init -p</pre><h3>tailwind.config.js</h3><pre>/** @type {import(&#39;tailwindcss&#39;).Config} */<br>module.exports = {<br>  content: [<br>    &#39;./app/**/*.{js,ts,jsx,tsx}&#39;,<br>    &#39;./components/**/*.{js,ts,jsx,tsx}&#39;,<br>  ],<br>  theme: {<br>    extend: {},<br>  },<br>  plugins: [],<br>};</pre><h3>app/globals.css</h3><pre>@tailwind base;<br>@tailwind components;<br>@tailwind utilities;</pre><h3>app/page.tsx</h3><pre>export default function HomePage() {<br>  return (<br>    &lt;div className=&quot;flex items-center justify-center h-screen&quot;&gt;<br>      &lt;h1 className=&quot;text-4xl font-bold&quot;&gt;Welcome to Next.js with Tailwind CSS&lt;/h1&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><p>This setup integrates <strong>Tailwind CSS</strong> into your Next.js application, allowing you to use utility classes for styling.</p><h3>13. Head Management</h3><p>Managing document <strong>head elements</strong> using the head component.</p><h3>app/page.tsx</h3><pre>import Head from &#39;next/head&#39;;</pre><pre>export default function HomePage() {<br>  return (<br>    &lt;&gt;<br>      &lt;Head&gt;<br>        &lt;title&gt;My Next.js App&lt;/title&gt;<br>        &lt;meta name=&quot;description&quot; content=&quot;Welcome to my Next.js application&quot; /&gt;<br>      &lt;/Head&gt;<br>      &lt;div&gt;<br>        &lt;h1&gt;Home Page&lt;/h1&gt;<br>      &lt;/div&gt;<br>    &lt;/&gt;<br>  );<br>}</pre><p>This setup dynamically adds the <strong>title</strong> and <strong>meta description</strong> to the document head.</p><h3>14. Internationalization (i18n)</h3><p>Implementing <strong>internationalization (i18n)</strong> using the next-intl package.</p><h3>Installation:</h3><pre>npm install next-intl</pre><h3>app/[locale]/page.tsx</h3><pre>import { useTranslations } from &#39;next-intl&#39;;</pre><pre>export default function HomePage() {<br>  const t = useTranslations(&#39;Index&#39;);</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;h1&gt;{t(&#39;title&#39;)}&lt;/h1&gt;<br>      &lt;p&gt;{t(&#39;description&#39;)}&lt;/p&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><p>This component renders text according to the current locale.</p><h3>i18n.ts</h3><pre>import { NextIntlProvider } from &#39;next-intl&#39;;</pre><pre>export function withLocale(Component: React.FC) {<br>  return function LocaleWrapper(props: { messages: Record&lt;string, string&gt; }) {<br>    return (<br>      &lt;NextIntlProvider messages={props.messages}&gt;<br>        &lt;Component {...props} /&gt;<br>      &lt;/NextIntlProvider&gt;<br>    );<br>  };<br>}</pre><p>This withLocale function wraps your component in the NextIntlProvider to provide the translation messages.</p><h3>app/[locale]/layout.tsx</h3><pre>import { withLocale } from &#39;../../i18n&#39;;</pre><pre>export default withLocale(function LocaleLayout({ children }: { children: React.ReactNode }) {<br>  return &lt;&gt;{children}&lt;/&gt;;<br>});</pre><p>This layout ensures that your app supports multiple languages by wrapping it with the <strong>internationalization</strong> context.</p><p>Here is the updated version with TypeScript, advanced Next.js features, and improvements for deployment and form handling:</p><h3>15. Deployment Strategies — Vercel, Self-hosting, and CI/CD</h3><h3>Vercel Deployment Example:</h3><p>Deploying your Next.js app to <strong>Vercel</strong> is straightforward. Simply follow these steps:</p><ol><li><strong>Install Vercel CLI</strong>:</li></ol><pre>npm install -g vercel</pre><ol><li><strong>Deploy the App</strong>:</li></ol><pre>vercel</pre><p>This will guide you through the deployment process, and your app will be live on Vercel.</p><h3>CI/CD with GitHub Actions Example:</h3><p>Set up <strong>GitHub Actions</strong> to automatically deploy your app to Vercel on every push to the main branch.</p><h3>.github/workflows/deploy.yml</h3><pre>name: Deploy to Vercel</pre><pre>on:<br>  push:<br>   branches:<br>    - main</pre><pre>jobs:<br>  deploy:<br>   runs-on: ubuntu-latest<br>   steps:<br>    - uses: actions/checkout@v3<br>    - name: Deploy to Vercel<br>      run: vercel --prod<br>      env:<br>       VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}</pre><p>This workflow will deploy your app to Vercel whenever you push changes to the main branch.</p><h3>Self-Hosting</h3><p>To deploy your Next.js app by self-hosting, follow these steps:</p><ol><li>Build the project:</li></ol><ul><li>npm run build</li></ul><p>2. Start the server:</p><ul><li>npm run start</li></ul><p>This will serve your app locally or on a server.</p><h3>16. Handling Forms and Validations</h3><p>This section demonstrates how to handle <strong>forms</strong> with basic validation in a Next.js app.</p><h3>app/contact-form/page.tsx</h3><pre>&#39;use client&#39;;</pre><pre>import { useState } from &#39;react&#39;;</pre><pre>export default function ContactForm() {<br>  const [name, setName] = useState(&#39;&#39;);<br>  const [error, setError] = useState(&#39;&#39;);</pre><pre>  const handleSubmit = (e: React.FormEvent) =&gt; {<br>    e.preventDefault();<br>    if (name.trim() === &#39;&#39;) {<br>      setError(&#39;Name is required&#39;);<br>      return;<br>    }<br>    setError(&#39;&#39;);<br>    // Process the form submission (e.g., call an API)<br>    alert(`Form submitted with name: ${name}`);<br>  };</pre><pre>  return (<br>    &lt;form onSubmit={handleSubmit} className=&quot;p-4 max-w-md mx-auto&quot;&gt;<br>      &lt;label className=&quot;block mb-2 font-bold&quot;&gt;Name:&lt;/label&gt;<br>      &lt;input<br>        type=&quot;text&quot;<br>        value={name}<br>        onChange={(e) =&gt; setName(e.target.value)}<br>        className=&quot;border p-2 w-full&quot;<br>      /&gt;<br>      {error &amp;&amp; &lt;p className=&quot;text-red-500 mt-1&quot;&gt;{error}&lt;/p&gt;}<br>      &lt;button type=&quot;submit&quot; className=&quot;mt-4 bg-blue-500 text-white p-2 rounded&quot;&gt;<br>        Submit<br>      &lt;/button&gt;<br>    &lt;/form&gt;<br>  );<br>}</pre><h3>Key Concepts in This Example:</h3><ul><li><strong>State Management</strong>: The name and error state hooks manage the input field and validation errors.</li><li><strong>Form Validation</strong>: Simple validation checks if the name field is empty.</li><li><strong>Handling Form Submission</strong>: On form submission, it triggers an alert with the entered name (this could be replaced with an API call in real use cases).</li></ul><h3>17. Using Environment Variables in Next.js</h3><p>Environment variables are critical for storing sensitive data or settings that vary between environments (e.g., development, staging, production). Variables prefixed with NEXT_PUBLIC_ are accessible in both <strong>server</strong> and <strong>client</strong> components.</p><h3>Setting Up Environment Variables</h3><p>Add your variables in a .env.local file to store them locally.</p><h3>.env.local</h3><pre>NEXT_PUBLIC_API_URL=https://api.example.com</pre><p>You can access these variables in your components:</p><h3>app/api-config/page.tsx</h3><pre>export default function ConfigPage() {<br>  // Access environment variables on both server and client if prefixed with NEXT_PUBLIC_<br>  const apiUrl = process.env.NEXT_PUBLIC_API_URL;<br>  <br>  return (<br>    &lt;div className=&quot;p-4&quot;&gt;<br>      &lt;h1&gt;Configuration&lt;/h1&gt;<br>      &lt;p&gt;API URL: {apiUrl}&lt;/p&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><h3>18. Caching Strategies and Performance Optimization</h3><p>You can optimize performance by caching data in <strong>Server Components</strong> using revalidation options. This allows you to keep data fresh without repeatedly fetching it from the server.</p><h3>app/api/cached-data/route.ts</h3><pre>export async function GET(request: Request) {<br>  // This fetch call instructs Next.js to revalidate the data every 300 seconds (5 minutes)<br>  const res = await fetch(&#39;https://api.example.com/data&#39;, {<br>    next: { revalidate: 300 }  // Revalidate every 5 minutes<br>  });<br>  const data = await res.json();</pre><pre>  return new Response(JSON.stringify(data), {<br>    headers: { &#39;Content-Type&#39;: &#39;application/json&#39; },<br>  });<br>}</pre><p>This ensures efficient data fetching and caching with periodic updates for fresh data.</p><h3>19. State Management — Context API, Redux, and Zustand</h3><h3>A. Using the Context API</h3><p>The <strong>Context API</strong> provides a way to pass data through the component tree without prop drilling.</p><h3>app/context/CounterContext.tsx</h3><pre>&#39;use client&#39;;<br>import { createContext, useContext, useState, ReactNode } from &#39;react&#39;;</pre><pre>const CounterContext = createContext&lt;any&gt;(null);</pre><pre>interface CounterProviderProps {<br>  children: ReactNode;<br>}</pre><pre>export function CounterProvider({ children }: CounterProviderProps) {<br>  const [count, setCount] = useState(0);<br>  const increment = () =&gt; setCount((prev) =&gt; prev + 1);<br>  <br>  return (<br>    &lt;CounterContext.Provider value={{ count, increment }}&gt;<br>      {children}<br>    &lt;/CounterContext.Provider&gt;<br>  );<br>}</pre><pre>export function useCounter() {<br>  return useContext(CounterContext);<br>}</pre><h3>app/counter/page.tsx</h3><pre>&#39;use client&#39;;<br>import { CounterProvider, useCounter } from &#39;../context/CounterContext&#39;;</pre><pre>function CounterDisplay() {<br>  const { count, increment } = useCounter();<br>  return (<br>    &lt;div&gt;<br>      &lt;p&gt;Count: {count}&lt;/p&gt;<br>      &lt;button onClick={increment}&gt;Increment&lt;/button&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><pre>export default function CounterPage() {<br>  return (<br>    &lt;CounterProvider&gt;<br>      &lt;CounterDisplay /&gt;<br>    &lt;/CounterProvider&gt;<br>  );<br>}</pre><h3>B. Using Redux (with Redux Toolkit)</h3><p>Redux is another popular state management tool for more complex scenarios.</p><h3>store.ts</h3><pre>import { configureStore, createSlice } from &#39;@reduxjs/toolkit&#39;;</pre><pre>const counterSlice = createSlice({<br>  name: &#39;counter&#39;,<br>  initialState: { count: 0 },<br>  reducers: {<br>    increment: (state) =&gt; { state.count += 1; },<br>  },<br>});</pre><pre>export const { increment } = counterSlice.actions;</pre><pre>export const store = configureStore({<br>  reducer: { counter: counterSlice.reducer },<br>});</pre><h3>app/redux-counter/page.tsx</h3><pre>&#39;use client&#39;;<br>import { Provider, useDispatch, useSelector } from &#39;react-redux&#39;;<br>import { store, increment } from &#39;../../store&#39;;</pre><pre>function ReduxCounter() {<br>  const count = useSelector((state: any) =&gt; state.counter.count);<br>  const dispatch = useDispatch();</pre><pre>  return (<br>    &lt;div&gt;<br>      &lt;p&gt;Redux Count: {count}&lt;/p&gt;<br>      &lt;button onClick={() =&gt; dispatch(increment())}&gt;Increment&lt;/button&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><pre>export default function ReduxCounterPage() {<br>  return (<br>    &lt;Provider store={store}&gt;<br>      &lt;ReduxCounter /&gt;<br>    &lt;/Provider&gt;<br>  );<br>}</pre><h3>C. Using Zustand</h3><p><strong>Zustand</strong> is a small and simple state management library for React.</p><h3>app/zustand-counter/page.tsx</h3><pre>&#39;use client&#39;;<br>import create from &#39;zustand&#39;;</pre><pre>// Create a simple Zustand store<br>const useStore = create((set) =&gt; ({<br>  count: 0,<br>  increment: () =&gt; set((state) =&gt; ({ count: state.count + 1 })),<br>}));</pre><pre>export default function ZustandCounter() {<br>  const { count, increment } = useStore();<br>  return (<br>    &lt;div&gt;<br>      &lt;p&gt;Zustand Count: {count}&lt;/p&gt;<br>      &lt;button onClick={increment}&gt;Increment&lt;/button&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><h3>20. Integrating Third-Party APIs (REST and GraphQL)</h3><h3>A. Integrating a REST API</h3><p>You can fetch data from a <strong>REST API</strong> using the fetch method.</p><h3>app/rest-api/page.tsx</h3><pre>export default async function RestApiPage() {<br>  // Fetch posts from a sample REST API<br>  const res = await fetch(&#39;https://jsonplaceholder.typicode.com/posts&#39;);<br>  const posts = await res.json();</pre><pre>  return (<br>    &lt;div className=&quot;p-4&quot;&gt;<br>      &lt;h1&gt;REST API Data&lt;/h1&gt;<br>      &lt;ul&gt;<br>        {posts.slice(0, 5).map((post: { id: number; title: string }) =&gt; (<br>          &lt;li key={post.id}&gt;<br>            &lt;strong&gt;{post.title}&lt;/strong&gt;<br>          &lt;/li&gt;<br>        ))}<br>      &lt;/ul&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><h3>B. Integrating a GraphQL API</h3><p>To use <strong>GraphQL</strong>, install a lightweight client like graphql-request:</p><pre>npm install graphql-request</pre><h3>app/graphql/page.tsx</h3><pre>import { GraphQLClient, gql } from &#39;graphql-request&#39;;</pre><pre>export default async function GraphQLPage() {<br>  const endpoint = &#39;https://countries.trevorblades.com/&#39;;<br>  const client = new GraphQLClient(endpoint);<br>  <br>  const query = gql`<br>    {<br>      countries {<br>        code<br>        name<br>      }<br>    }<br>  `;<br>  <br>  const data = await client.request(query);<br>  const countries = data.countries;</pre><pre>  return (<br>    &lt;div className=&quot;p-4&quot;&gt;<br>      &lt;h1&gt;GraphQL API Data&lt;/h1&gt;<br>      &lt;ul&gt;<br>        {countries.slice(0, 5).map((country: { code: string; name: string }) =&gt; (<br>          &lt;li key={country.code}&gt;<br>            {country.name} ({country.code})<br>          &lt;/li&gt;<br>        ))}<br>      &lt;/ul&gt;<br>    &lt;/div&gt;<br>  );<br>}</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=68efc77374c6" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>