<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Arunachalam B - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Arunachalam B - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Wed, 13 May 2026 15:16:11 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/arunachalamb/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ React’s Critical "React2Shell" Vulnerability — What You Should Know, and How to Upgrade Your App ]]>
                </title>
                <description>
                    <![CDATA[ Web development is always evolving, and sometimes those changes happen a bit under the hood. One such change involved the shift to React Server Components (RSC). If you’re a NextJS or React developer, especially using the App Router, understanding th... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/reacts-critical-react2shell-vulnerability-what-you-should-know-and-how-to-upgrade-your-app/</link>
                <guid isPermaLink="false">6939b6ee10076c81dd6c3f49</guid>
                
                    <category>
                        <![CDATA[ React2Shell ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Next.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hacking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cybersecurity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Wed, 10 Dec 2025 18:07:42 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1765328805925/a9c016a1-90a9-4123-bbb0-17c7d46da035.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Web development is always evolving, and sometimes those changes happen a bit under the hood. One such change involved the shift to React Server Components (RSC). If you’re a NextJS or React developer, especially using the App Router, understanding the new security alert is really important for keeping your apps safe and secure.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-react2shell">What is "React2Shell"?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-is-this-happening-now">Why is this Happening Now?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-should-you-worry-about-this-change">Should You Worry About this Change?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-is-this-mandatory">Is this Mandatory?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-bad-can-it-get-the-extent-of-exploitation">How Bad Can It Get? The Extent of Exploitation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-would-be-the-code-change-for-this">What Would be the Code Change for This?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-advanced-verify-with-the-original-exploit-poc">Advanced: Verify with the Original Exploit (PoC)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-emergency-response-what-if-you-were-already-compromised">Emergency Response: What If You Were Already Compromised?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-react2shell">What is "React2Shell"?</h2>
<p>Think of your server receiving data like a mailroom receiving packages.</p>
<p>Usually, a mailroom checks if a package is safe before opening it. But in vulnerable versions of React and NextJS, the "Flight" protocol (used to communicate between the server and client) acts like a mailroom that blindly opens every package and follows any instructions inside immediately.</p>
<p>This vulnerability (CVE-2025-55182) allows an attacker to send a specifically crafted "package" (HTTP request) that forces your server to execute malicious code – like stealing passwords or installing viruses –without even logging in.</p>
<h2 id="heading-why-is-this-happening-now">Why is this Happening Now?</h2>
<p>It's all about how modern frameworks handle data serialization. There are a few reasons why this was just discovered.</p>
<p>First, React has complex serialization. To make Server Components seamless, React sends complex data structures back and forth.</p>
<p>Second, it has the "Flight" protocol. The vulnerability was found in how this specific protocol de-serializes (unpacks) data. It was too trusting of the input it received from the client side.</p>
<h2 id="heading-should-you-worry-about-this-change">Should You Worry About this Change?</h2>
<p>You need to pay attention if your app qualifies for any of the below:</p>
<ul>
<li><p><strong>You are using NextJS App Router:</strong> This is the default in newer NextJS versions (v13+).</p>
</li>
<li><p><strong>You are using React 19:</strong> Specifically versions with Server Components enabled.</p>
</li>
<li><p><strong>You use Server Actions:</strong> If your app takes user input and processes it on the server using React's server actions.</p>
</li>
</ul>
<h2 id="heading-is-this-mandatory">Is this Mandatory?</h2>
<p><strong>Yes.</strong> This is a critical security update. If your app qualifies in any of the above scenarios, you need to act immediately. Because, this vulnerability is being exploited right now.</p>
<h2 id="heading-how-bad-can-it-get-the-extent-of-exploitation">How Bad Can It Get? The Extent of Exploitation</h2>
<p>You might be thinking, "My site is just a simple content wrapper, surely I'm not a target?" Unfortunately, with Remote Code Execution (RCE), the attacker doesn't just "break" your site – they own the server it runs on.</p>
<p>Here is exactly what a hacker can do once they exploit this vulnerability:</p>
<h3 id="heading-total-environment-theft">Total Environment Theft</h3>
<p>The most immediate risk is your <code>.env</code> file. Attackers can execute code to read your environment variables, instantly gaining access to your AWS Secret Keys, Database passwords, Stripe API keys, and OpenAI tokens.</p>
<h3 id="heading-the-shell-access">The "Shell" Access</h3>
<p>As the name "React2Shell" implies, attackers can open a reverse shell. This gives them a command-line interface on your server, allowing them to browse your file system as if they were sitting in front of your computer.</p>
<h3 id="heading-lateral-movement">Lateral Movement</h3>
<p>Once inside your NodeJS server, they are behind your firewall. They can now attack your internal services (like Redis, internal databases, or private micro-services) that are usually blocked from the outside world.</p>
<h3 id="heading-supply-chain-poisoning">Supply Chain Poisoning</h3>
<p>If your build server is vulnerable, an attacker could potentially inject malicious code into your deployment pipeline, affecting every user who visits your site in the future.</p>
<h3 id="heading-botnet-recruitment">Botnet Recruitment</h3>
<p>Hackers often automate these attacks to install crypto-miners, using your server's CPU (which you pay for!) to mine digital currency for them, often crashing your application in the process.</p>
<h2 id="heading-what-would-be-the-code-change-for-this">What Would be the Code Change for This?</h2>
<p>You don’t need to rewrite your application code, but you must update your dependencies in your release line.</p>
<p>The vulnerability is fully resolved in the following patched NextJS releases:</p>
<ul>
<li><p>15.0.5</p>
</li>
<li><p>15.1.9</p>
</li>
<li><p>15.2.6</p>
</li>
<li><p>15.3.6</p>
</li>
<li><p>15.4.8</p>
</li>
<li><p>15.5.7</p>
</li>
<li><p>16.0.7</p>
</li>
</ul>
<p>Patched canary releases for NextJS 15 and 16:</p>
<ul>
<li><p>15.6.0-canary.58 (for 15.x canary releases)</p>
</li>
<li><p>16.1.0-canary.12 (for 16.x canary releases)</p>
</li>
</ul>
<p>These versions include the hardened React Server Components implementation.</p>
<p>Here are the patched versions for React JS:</p>
<ul>
<li><p>19.0.1</p>
</li>
<li><p>19.1.2</p>
</li>
<li><p>19.2.1</p>
</li>
</ul>
<p>Frameworks and bundlers using the aforementioned packages should install the latest versions provided by their respective maintainers.</p>
<p>Alternatively, you can run <code>npx fix-react2shell-next</code> in your NextJS project to launch an interactive tool which can check versions and perform deterministic version bumps per the recommended versions above. See the <a target="_blank" href="https://github.com/vercel-labs/fix-react2shell-next">GitHub repository</a> for full details.</p>
<p><strong>There is no workaround other than upgrading to a patched version.</strong></p>
<p>It’s highly recommended to rotate all your application secrets, once you have patched your version and re-deployed your application.</p>
<h2 id="heading-advanced-verify-with-the-original-exploit-poc">Advanced: Verify with the Original Exploit (PoC)</h2>
<p>If you want to be 100% sure your patch is working, or if you want to understand how the attack actually works, you can use the original Proof of Concept (PoC) created by the security researcher (Lachlan Davidson) who found the bug.</p>
<p><strong>Repository:</strong> <a target="_blank" href="https://github.com/lachlan2k/React2Shell-CVE-2025-55182-original-poc">React2Shell-CVE-2025-55182-original-poc</a></p>
<p>Lachlan provided three variations of the exploit script. The most important one for testing is <code>01-submitted-poc.js</code>, which is the exact, simplified version submitted to Meta for the bug bounty.</p>
<h3 id="heading-how-the-exploit-works">How the Exploit Works</h3>
<p>According to the repository, the attack works by tricking the parser:</p>
<ol>
<li><p>The attacker sends a payload using <code>$@x</code> to access a specific data <code>Chunk</code>.</p>
</li>
<li><p>They "plant" a <code>.then</code> function on a fake object.</p>
</li>
<li><p>The JavaScript runtime thinks it is handling a Promise and tries to "unravel" it.</p>
</li>
<li><p>This allows the attacker to re-enter the parser with a malicious fake chunk, giving them access to internal server gadgets (like <code>_response</code>) to execute code (RCE).</p>
</li>
</ol>
<h3 id="heading-steps-to-recreate-the-issue">Steps to Recreate the Issue</h3>
<p><strong>⚠️ WARNING:</strong> Only run this against a local development server (<a target="_blank" href="http://localhost"><code>localhost</code></a>) that you own. Never run this against production servers or public websites.</p>
<p><strong>Note:</strong> I forked Lachlan’s repo and made minor changes to make it easy for you to run the script.</p>
<h4 id="heading-step-1-clone-the-repository">Step 1: Clone the Repository</h4>
<p>Run the following commands to clone the repository, navigate into the project, and install dependencies:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> https://github.com/arunachalam-b/React2Shell-CVE-2025-55182-original-poc.git
<span class="hljs-built_in">cd</span> React2Shell-CVE-2025-55182-original-poc
npm i
</code></pre>
<h4 id="heading-step-2-run-a-vulnerable-local-server">Step 2: Run a Vulnerable Local Server</h4>
<p>Start your NextJS application locally (ensure it’s running a vulnerable version, for example NextJS 15.0.0, for the test to succeed).</p>
<pre><code class="lang-bash">npm run dev
<span class="hljs-comment"># usually runs on http://localhost:3000</span>
</code></pre>
<h4 id="heading-step-3-execute-the-test">Step 3: Execute the Test</h4>
<p>You will need to modify the script or use a tool like <code>curl</code> to send the payload structure found in <code>01-submitted-poc.js</code> to your server's endpoint (usually a Server Action endpoint). Or simply run the following command if your app is accessible at <code>http://localhost:3000</code>:</p>
<pre><code class="lang-bash">node 01-submitted-poc.js
</code></pre>
<p>If the exploit succeeds (on the vulnerable version), the console will log the execution of the code (RCE). If the exploit fails (after you patch), the server will either reject the request or error out safely.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765298324009/7a8158bb-30cc-4604-9591-4503a4c8d655.png" alt="This response on running the script indicates your server is vulnerable" class="image--center mx-auto" width="1160" height="461" loading="lazy"></p>
<p>You can also confirm if your infected web server prints <code>50</code> in the console. Because we inject the code to do a calculation (look at <code>_prefix</code> field in the below JSON) that results in <code>50</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765298178869/417d5f3c-15d2-4806-854c-f4216d336bd9.png" alt="The payload used to demonstrate this hack" class="image--center mx-auto" width="568" height="367" loading="lazy"></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765298285565/38bcbcfa-390f-4198-9db1-218d2ed0dd65.png" alt="The 50 in your NextJS console indicates the hackers code has been executed on your server" class="image--center mx-auto" width="707" height="208" loading="lazy"></p>
<p>After you apply the fix, you should see an error while running the script. In this case, as I’m using NextJS v15.1, the fix is upgrading the <code>next</code> package to version <code>15.1.9</code>. Here are the screenshots after upgrading the package and running the script.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765298558607/36103fd0-2a23-44f5-bff6-f979255a9765.png" alt="Response on running script after applying the fix" class="image--center mx-auto" width="1160" height="572" loading="lazy"></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765298580698/53bcd836-013a-4291-98df-2d9188512a2c.png" alt="The console does not print 50 while running same script which indicates the hackers code is not executed on your server after applying the fix" class="image--center mx-auto" width="1321" height="251" loading="lazy"></p>
<h4 id="heading-step-4-verification">Step 4: Verification</h4>
<p>Once you have confirmed the exploit works on the old version, update your packages (as shown in the section above) and run the script again. It should no longer trigger the code execution.</p>
<h2 id="heading-emergency-response-what-if-you-were-already-compromised">Emergency Response: What If You Were Already Compromised?</h2>
<p>If you suspect your server was exposed to the internet with a vulnerable version, assume the worst. A hacker may have already stolen your keys or left a "backdoor" to return later. Patching the code alone is NOT enough in this case.</p>
<p>Follow this <strong>"Nuke and Pave"</strong> protocol immediately:</p>
<h3 id="heading-step-1-isolate-and-shutdown">Step 1: Isolate and Shutdown</h3>
<p>Take the compromised server offline immediately. Do not try to "fix" it while it is running.</p>
<h3 id="heading-step-2-rotate-all-secrets-crucial-step">Step 2: Rotate ALL Secrets (Crucial Step)</h3>
<p>Assume every secret in your <code>.env</code> file is in the hands of a hacker. You must generate new ones:</p>
<ul>
<li><p>Change the password for your database users.</p>
</li>
<li><p>Rotate AWS Access Keys, Google Cloud Service Account keys, and so on.</p>
</li>
<li><p>Roll your Stripe/PayPal/Razorpay API keys.</p>
</li>
<li><p>Rotate your <code>NEXTAUTH_SECRET</code> or any JWT signing keys.</p>
</li>
</ul>
<h3 id="heading-step-3-do-not-clean-rebuild">Step 3: Do Not "Clean" — Rebuild</h3>
<p>Do not attempt to find and delete malware files on the server. Hackers are good at hiding.</p>
<ul>
<li><p>Destroy the existing container, droplet, or EC2 instance entirely.</p>
</li>
<li><p>Build a fresh instance from your source code (after applying the patch).</p>
</li>
</ul>
<h3 id="heading-step-4-audit-your-logs">Step 4: Audit Your Logs</h3>
<p>Look at your database and cloud provider logs. Did anyone download your entire user database? Did anyone spin up expensive GPU instances on your AWS account? Check for unusual activity that occurred before you patched.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, you learned about the "React2Shell" vulnerability, how to verify it using the original developer's tools, and how to upgrade your app to secure your Server Components. I hope you have a clear idea about why this update is urgent. By being proactive now, you can avoid a catastrophic data breach.</p>
<p>You can follow my <a target="_blank" href="https://x.com/AI_Techie_Arun">Twitter/X account</a> to receive the top AI news everyday. If you wish to learn more about cybersecurity, <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=react2shell-vulnerability">subscribe to my email newsletter</a> and follow me on social media.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Google Play’s 16 KB Page Size Compatibility Requirement — What You Should Know, and How to Upgrade Your App ]]>
                </title>
                <description>
                    <![CDATA[ Android is always evolving, and sometimes those changes happen a bit under the hood. One such change that's been gaining traction—and now has a firm deadline from Google—is the move to a 16 KB page size. If you're an Android developer, especially wit... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/google-16-kb-page-size-requirement-what-to-do/</link>
                <guid isPermaLink="false">68d703052043890036a92cb0</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ android app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mobile app development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Fri, 26 Sep 2025 21:17:57 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1758921064544/80db1a03-73e1-48c3-b2a0-566f20244431.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Android is always evolving, and sometimes those changes happen a bit under the hood. One such change that's been gaining traction—and now has a firm deadline from Google—is the move to a 16 KB page size. If you're an Android developer, especially with native code in your app, understanding this shift is really important for keeping your apps smooth and compatible.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-a-page-size">What is a Page Size?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-is-this-change-being-implemented-now">Why is this Change Being Implemented Now?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-are-the-pros-and-cons-of-this-change">What are the Pros and Cons of this Change?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-should-you-worry-about-this-change">Should You worry About this Change?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-is-this-mandatory">Is this Mandatory?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-if-you-dont-upgrade-your-app">What if You Don’t Upgrade Your App?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-does-this-affect-hybrid-apps">How Does this Affect Hybrid Apps?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-would-be-the-code-change-for-this">What Would be the Code Change for This?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-verify-if-your-app-is-upgraded-to-a-16-kb-page-size">How to Verify if Your App is Upgraded to a 16 KB Page Size</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-a-page-size">What is a Page Size?</h2>
<p>Think of your device's memory like a book. An operating system doesn't read memory one tiny word at a time; it reads in chunks. These chunks are called "pages." For a long time, on most ARM64 Android devices, these pages were 4 KB in size. Now, for some newer Android devices (specifically those launching with Android 13 and later), that page size has quadrupled to 16 KB.</p>
<h2 id="heading-why-is-this-change-being-implemented-now">Why is this Change Being Implemented Now?</h2>
<p>It's all about making Android run better on modern hardware. Here are some of the reasons why is it being implemented:</p>
<p><strong>Better Performance:</strong> Modern processors can handle larger memory chunks more efficiently. A 16 KB page size means the CPU spends less time managing tiny bits of memory and more time doing actual work, which can lead to faster app performance.</p>
<p><strong>Smoother Operations:</strong> With fewer, larger pages to keep track of, the system itself has a little less overhead, making things a bit more streamlined.</p>
<p><strong>Keeping Up with Tech:</strong> This change helps Android align with how newer ARM64 processors are designed to work best.</p>
<h2 id="heading-what-are-the-pros-and-cons-of-this-change">What are the Pros and Cons of this Change?</h2>
<p>Every big change has its own pros and cons.</p>
<h3 id="heading-pros">Pros</h3>
<ul>
<li><p>Apps that move a lot of data around or are memory-intensive might just feel a bit snappier</p>
</li>
<li><p>The system could run a bit more efficiently, benefiting all apps indirectly</p>
</li>
</ul>
<h3 id="heading-cons">Cons</h3>
<ul>
<li><p>If your native code is constantly asking for very small bits of memory (less than 16 KB), each of those might now take up a full 16 KB page, potentially using a little more memory than before.</p>
</li>
<li><p>If your native code makes assumptions that "memory pages are always 4 KB," it could run into issues on 16 KB page devices.</p>
</li>
</ul>
<h2 id="heading-should-you-worry-about-this-change">Should You worry About this Change?</h2>
<p>You need to pay attention if:</p>
<ul>
<li><p>Your app includes native libraries (like <code>.so</code> files) written in C/C++. This is where the impact is most direct. If your native code does anything with memory mapping (mmap, shmem) or file I/O where it calculates offsets or sizes based on a fixed page size.</p>
</li>
<li><p>You're developing games or other highly performance-sensitive apps with native components.</p>
</li>
<li><p>You're targeting Android 15+ with your app updates.</p>
</li>
</ul>
<p>You need not worry if:</p>
<ul>
<li><p>Your app is built purely in Java or Kotlin with no native components. The Android Runtime (ART) handles memory for you, so these underlying page size changes are largely invisible. You'll still get the performance benefits!</p>
</li>
<li><p>You're using React Native or Flutter, unless you've added custom native modules that directly deal with memory mapping or page-size-dependent operations</p>
</li>
</ul>
<h2 id="heading-is-this-mandatory">Is this Mandatory?</h2>
<p>Yes. Google Play is making this a requirement for app updates. You would have received an email from Google Play if your app does not support 16 KB page size yet.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758343797173/da2aff04-d5ae-4964-9d72-02f21b4a0d96.png" alt="Your app is affected by Google Play's 16KB page size requirements" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>As the screenshot clearly shows, "From Nov 1, 2025, if your app updates do not support 16 KB memory page sizes, you won't be able to release these updates" for apps targeting Android 15+. This gives us a solid timeframe to get things ready.</p>
<h2 id="heading-what-if-you-dont-upgrade-your-app">What if You Don’t Upgrade Your App?</h2>
<p>You could notice some serious issues if your app has native libraries that aren't ready for the 16 KB page size by the deadline. Here are a few:</p>
<ul>
<li><p><strong>Crashes:</strong> This is the most serious. Your app might crash unexpectedly (often with a "segmentation fault") if it tries to access memory incorrectly due to old page size assumptions.</p>
</li>
<li><p><strong>Wasted Memory:</strong> If your code allocates memory in smaller chunks than 16 KB, it could end up using more memory than necessary, potentially slowing things down or hitting memory limits.</p>
</li>
<li><p><strong>Performance Hit:</strong> Instead of gaining speed, your app might actually run slower if its memory operations aren't aligned with the larger page size.</p>
</li>
</ul>
<p>Essentially, your app might work fine today, but become unstable or inefficient on newer Android devices if its native components aren't updated.</p>
<h2 id="heading-how-does-this-affect-hybrid-apps">How Does this Affect Hybrid Apps?</h2>
<p>Generally, if you're building a standard hybrid app (React Native or Flutter app) without custom native modules, you're in a pretty good spot. The frameworks themselves, and the underlying runtimes (JavaScript engine for React Native, Dart VM for Flutter), usually handle memory management, abstracting away the page size.</p>
<p>However, if you've implemented custom native modules in C++ for performance-critical tasks or specific hardware interactions, then you do need to check those modules.</p>
<p>For the vast majority of standard React Native and Flutter apps, you likely won't need direct code changes related to page size, but always ensure you're using the latest SDK versions for your framework to benefit from any underlying platform updates.</p>
<h2 id="heading-what-would-be-the-code-change-for-this">What Would be the Code Change for This?</h2>
<p>The biggest thing to avoid in your native code is making assumptions about memory page sizes. Instead of hardcoding 4096 (for 4 KB), always ask the operating system what its current page size is.</p>
<h3 id="heading-steps-to-take"><strong>Steps to Take:</strong></h3>
<ol>
<li><p><strong>Audit Your Native Code:</strong> Search your <code>.cpp</code>, <code>.c</code>, and <code>.h</code> files for any direct use of 4096 or 4 KB in memory allocation, buffer sizing, or alignment calculations</p>
</li>
<li><p><strong>Replace with</strong> <code>sysconf(_SC_PAGESIZE)</code> <strong>or</strong> <code>getpagesize()</code><strong>:</strong> Update any fixed values to dynamically retrieve the actual page size.</p>
</li>
<li><p><strong>Recompile with Latest NDK:</strong> Make sure you're building your native libraries with a recent Android NDK (r25 or newer is a good target). This ensures your toolchain is aware of the 16 KB page size and provides correct system definitions.</p>
</li>
</ol>
<h2 id="heading-how-to-verify-if-your-app-is-upgraded-to-a-16-kb-page-size">How to Verify if Your App is Upgraded to a 16 KB Page Size</h2>
<p>You can verify if your app is upgraded by running extensive testing. However, here are the few more steps.</p>
<ol>
<li><p><strong>Check Your Test Device's Page Size:</strong></p>
<ul>
<li><p>Connect your Android 13+ test device (preferably a newer one like a Pixel) via ADB</p>
</li>
<li><p>Run <code>adb shell getconf PAGE_SIZE</code></p>
</li>
<li><p>If it returns 16384, you're testing on a 16 KB page device! If it returns 4096, you'll need to find a different device to properly test for this change</p>
</li>
<li><p>Here’s an example screenshot from my device</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1758368982307/f5696dab-f23a-4731-95b4-0372159d2107.png" alt="Find page size of an Android device/emulator" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
</li>
</ul>
</li>
<li><p><strong>Run Your App Extensively:</strong> Once you have a 16 KB page device, put your app through its paces. Try all features, especially those involving native code, heavy data loading, or complex operations.</p>
</li>
<li><p><strong>Monitor for Crashes:</strong> Keep a close eye on your crash reporting tools (like Crashlytics). Specifically look for native crashes (<code>SIGSEGV</code>, <code>SIGBUS</code>) coming from Android 13+ devices, as these could be related to page size issues.</p>
</li>
<li><p><strong>Memory Profiling:</strong> While less direct, if you suspect memory inefficiency in your native code, use Android Studio's Memory Profiler to see if allocations are unexpectedly large or if there's excessive memory usage.</p>
</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this blog, we learnt about page size in Android, and why and how to upgrade your app to support 16 KB page size. I hope you have a clear idea about 16 KB page size in Android. By being proactive now, you can avoid last-minute scrambling and ensure your apps continue to perform beautifully on the latest Android devices, well past the November 2025 deadline!</p>
<p>You can follow my <a target="_blank" href="https://x.com/AI_Techie_Arun">Twitter/X account</a> to receive the top AI news everyday. If you wish to learn more about mobile app development, subscribe to my email newsletter (<a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_android_16kb_page_size">https://5minslearn.gogosoon.com/</a>) and follow me on social media.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create an AI-Powered Bot that Can Post on Twitter/X ]]>
                </title>
                <description>
                    <![CDATA[ These days, everyone wants to be a content creator. But it can be hard to find time to create and curate content, post on social media, build engagement, and grow your brand. And I’m not an exception to this. I wanted to create more content, and had ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-an-ai-powered-bot/</link>
                <guid isPermaLink="false">680931204adb8ffdef48642a</guid>
                
                    <category>
                        <![CDATA[ automation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ bot ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Twitter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ gemini ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Wed, 23 Apr 2025 18:27:44 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1745416845372/5eb9963d-e092-4844-99d9-01fa70032169.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>These days, everyone wants to be a content creator. But it can be hard to find time to create and curate content, post on social media, build engagement, and grow your brand.</p>
<p>And I’m not an exception to this. I wanted to create more content, and had an idea based on something I’ve observed. I subscribe to a few technology newsletters, and I read lots of updates every day about the tech ecosystem. But I’ve noticed that many of my peers often don’t seem to be aware of this news. So, I decided to post my top three news stories (especially about AI) on my Twitter/X account every day.</p>
<p>I did this for a couple of weeks, but after that I couldn’t find the time to keep it going. So, I did some research into how I could automate the process, and I found a solution. In this guide, I’ll explain the process so you can use it, too.</p>
<p>By the end of this tutorial, you’ll have created your own AI bot that:</p>
<ul>
<li><p>Fetches data from an API or crawls a webpage</p>
</li>
<li><p>Processes the data using AI</p>
</li>
<li><p>Posts the results on Twitter/X</p>
</li>
</ul>
<p>And the great thing: this entire process is automated.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-the-bot">How to Build the Bot</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-step-1-generate-the-twitter-api-key">Step 1: Generate the Twitter API Key</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-generate-access-token-and-secret">Step 2: Generate Access Token and Secret</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-generate-an-api-key-in-google-gemini">Step 3: Generate an API Key in Google Gemini</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-nodejs-project-setup">Node.js Project Setup</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-step-1-fetch-data-from-the-api">Step 1: Fetch Data from the API</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-upload-the-data-as-a-file-to-gemini-api">Step 2: Upload the Data as a File to Gemini API</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-prompt-gemini-to-get-the-latest-ai-news">Step 3: Prompt Gemini to Get the Latest AI News</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-4-post-using-the-twitterx-api">Step 4: Post Using the Twitter/X API</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-5-delete-the-file-uploaded-in-the-gemini-api">Step 5: Delete the File Uploaded in the Gemini API</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-result">The Result</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before we begin creating a bot, you’ll need to have the following setup and tools ready to go:</p>
<ul>
<li><a target="_blank" href="https://nodejs.org/en/learn/getting-started/introduction-to-nodejs">NodeJS</a> - A simple NodeJS app to code the bot</li>
</ul>
<p>You’ll also need some API keys, secrets, and tokens. So, you’ll need to have the following accounts created:</p>
<ul>
<li><p><a target="_blank" href="https://developer.x.com/">Twitter Developer</a> – To generate the Twitter/X API keys, secrets, and tokens</p>
</li>
<li><p><a target="_blank" href="https://aistudio.google.com/">Google AI Studio</a> – To generate the Gemini API key</p>
</li>
</ul>
<h2 id="heading-how-to-build-the-bot">How to Build the Bot</h2>
<p>There are a number of steps I’ll walk you through to build your bot.</p>
<p>We’ll start by generating an API Key and Secret so we can use the Twitter/X API. Then we’ll generate an access token and access token secret with “Read and Write” permissions that’ll be able to post in your account. After that we’ll generate an API Key in Google Gemini (we’ll be using the Gemini API to process the data).</p>
<p>With all that taken care of, we’ll start working on the Node.js app. The app will be able to fetch data from an API, process the data using AI, and then post that data in the form of tweets on Twitter/X.</p>
<p>Finally, we’ll automate the entire process and schedule it to run daily.</p>
<h3 id="heading-step-1-generate-the-twitter-api-key">Step 1: Generate the Twitter API Key</h3>
<ol>
<li><p>Navigate to <a target="_blank" href="https://developer.x.com/">Twitter Developer Website</a>.</p>
</li>
<li><p>Click on the “Developer Portal” in the top right:</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745152618491/214fe6d6-b699-40bb-8ac0-533b0c72b927.png" alt="Image showing developer portal highlighted" class="image--center mx-auto" width="1865" height="945" loading="lazy"></p>
</li>
<li><p>Signup using your account.</p>
</li>
<li><p>You’ll be asked to fill out a form asking how will you use the Twitter API, and a few basic details. It may take up to 24 hours to get approved. But, it’s approved instantly for me.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745152170917/d2c2ba21-f3f5-4bc6-bdd5-58d222e203e6.png" alt="Form asking how you'll use the Twitter API" class="image--center mx-auto" width="833" height="388" loading="lazy"></p>
</li>
<li><p>After login, Navigate to "Projects and Apps" and under “Overview” click on "Create App":</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745153184830/1a731639-0df2-47e3-baf2-3633e1735a69.png" alt="Create App screen" class="image--center mx-auto" width="691" height="306" loading="lazy"></p>
</li>
<li><p>Enter a name for your app and click “Next” to proceed with creating your app. At the end, you’ll be shown your API Key and Secret. Don’t copy that now.</p>
</li>
<li><p>Click on the project you created from the left side drawer and click on the "Edit" option in “User authentication settings” section.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745153746932/002f3b38-5aaf-43ef-8d7c-0368f141524f.png" alt="Editing the user authentication settings section" class="image--center mx-auto" width="1230" height="719" loading="lazy"></p>
</li>
<li><p>Select “Read and Write” in App Permissions section, “Web App, Automated App or Bot” in Type of App section, and enter your website URL (it can be any URL including http://localhost) in the “Callback URI” and “Website URL”. Then hit “Save”.</p>
</li>
<li><p>Go to “Keys and tokens” tab.</p>
</li>
<li><p>Click on “Regenerate” button in “API Key and Secret” section.</p>
</li>
<li><p>Copy and save the API Key and Secret somewhere securely.</p>
</li>
</ol>
<h3 id="heading-step-2-generate-access-token-and-secret">Step 2: Generate Access Token and Secret</h3>
<ol>
<li><p>Go to “Keys and tokens” tab.</p>
</li>
<li><p>Click on “Generate” or “Regenerate” button in “Access Token and Secret” section.</p>
</li>
<li><p>Copy and save the Access Token and Secret somewhere securely.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745154373207/4309dbcc-1081-46b7-be71-5babf950eae0.png" alt="Generating or regenerating keys and tokens" class="image--center mx-auto" width="1230" height="629" loading="lazy"></p>
</li>
</ol>
<h3 id="heading-step-3-generate-an-api-key-in-google-gemini">Step 3: Generate an API Key in Google Gemini</h3>
<ol>
<li><p>Navigate to <a target="_blank" href="https://aistudio.google.com/">Google AI Studio</a>.</p>
</li>
<li><p>Login to your account.</p>
</li>
<li><p>Click on “Get API Key” button at the top right.</p>
</li>
<li><p>Click on “Create API Key” button.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745154646809/54c4fa1a-097e-4bf6-8a5f-229c01845d28.png" alt="Create API screen" class="image--center mx-auto" width="1802" height="309" loading="lazy"></p>
</li>
<li><p>Copy and save the API Key somewhere securely.</p>
</li>
</ol>
<p>Alright, we are done with creating the necessary API Keys and Secrets for our project. Let’s put on our coding shoes.</p>
<h2 id="heading-nodejs-project-setup">Node.js Project Setup</h2>
<p>There are 5 major steps for this part of the project. They are:</p>
<ol>
<li><p>Fetch data from the API</p>
</li>
<li><p>Upload the data as a file to Gemini API</p>
</li>
<li><p>Prompt Gemini with the uploaded file to get the latest AI news</p>
</li>
<li><p>Post news to Twitter/X using their API</p>
</li>
<li><p>Delete the file uploaded in Gemini API</p>
</li>
</ol>
<p>These are just the snippets of code that can be assembled together to run this project.</p>
<h3 id="heading-step-1-fetch-data-from-the-api">Step 1: Fetch Data from the API</h3>
<p>In my case, I’ll be using <code>techmeme.com</code> to get the latest news. But this site does not offer an API. So, I’ll be downloading the HTML of this site.</p>
<div class="gist-block embed-wrapper" data-gist-show-loading="false" data-id="b204531fbfda5e805202b5f5ab5aa55d">
        <script src="https://gist.github.com/arunachalam-b/b204531fbfda5e805202b5f5ab5aa55d.js"></script></div><p> </p>
<p>In the <code>User-Agent</code> header, we pass the value that mimics a browser user agent to avoid potential blocks.</p>
<h3 id="heading-step-2-upload-the-data-as-a-file-to-gemini-api">Step 2: Upload the Data as a File to Gemini API</h3>
<p>Now we need to store this HTML in a separate file. We cannot directly pass the HTML code in the prompt to the Gemini API, as it’ll result in an error. This is because Gemini accepts only a limited number of tokens in this API. The HTML code of any website will always result in huge number of tokens. So, we’ll create a separate file.</p>
<p>Upload the file to the Gemini API. Refer to the file id in the prompt to Gemini.</p>
<div class="gist-block embed-wrapper" data-gist-show-loading="false" data-id="5ebfed570c79a0f0faa8c4e42559c673">
        <script src="https://gist.github.com/arunachalam-b/5ebfed570c79a0f0faa8c4e42559c673.js"></script></div><p> </p>
<h3 id="heading-step-3-prompt-gemini-to-get-the-latest-ai-news">Step 3: Prompt Gemini to Get the Latest AI News</h3>
<p>Let’s write a prompt to Gemini asking it to generate top news by referring to the HTML file provided. We’ll ask it to provide a headline, short description, URL, and three relevant hashtags for each tweet. We’ll also give some example data of how it should look. We’ll ask it to generate a structured response by providing the format of the JSON that we want the output to be.</p>
<p>You can use whatever model you want to, but I’ll be using the <code>gemini-2.5-pro-exp-03-25</code> model for this use case. I’m using this model because we need a thinking model that thinks and picks the correct top news – not just one that predicts the next token/word. The Gemini 2.5 Pro model best qualifies for this.</p>
<div class="gist-block embed-wrapper" data-gist-show-loading="false" data-id="466449de313bcbc4241eaf3b6e1646a7">
        <script src="https://gist.github.com/arunachalam-b/466449de313bcbc4241eaf3b6e1646a7.js"></script></div><p> </p>
<h3 id="heading-step-4-post-using-the-twitterx-api">Step 4: Post Using the Twitter/X API</h3>
<p>Here’s the core of our app. We need to post all the tweets we received from Gemini. We’ll be posting the tweet as a thread. This means that the first tweet will be the root tweet and subsequent tweets will be in the comments of the prior tweet. This makes it a thread.</p>
<p>To do this, we’ll take the id of each tweet after it’s posted and pass it on to the next tweet as a reference. One additional thing to note here is, after each successful tweet, we’ll give a pause of 5 seconds before posting the next tweet. There are few reasons for doing it this way.</p>
<ol>
<li><p>When any script runs, it usually runs at a much higher speed (usually in milliseconds). So, the second tweet may get posted before the first tweet was posted (maybe due to some poor internet connection). Also, I believe Twitter implements some queue system which may quickly process the second tweet before your first. So it’s always better to leave a small gap – if not 5 seconds then at least 1 second</p>
</li>
<li><p>Twitter may have implemented some rate limiting mechanism. So if there are multiple request received from a same IP within a short time frame, they may block the IP and consider your account as spam.</p>
</li>
<li><p>Since we’re using a Free tier API, we are limited to 1500 tweets per month. If you’ve paid for this API, you won’t have to worry about this (since you’ll have a higher limit and the rate limiting mechanism –refer to point #2 – might not be applicable). All of this depends on their <a target="_blank" href="https://docs.x.com/x-api/introduction#access-levels">pricing</a>, so just refer to that and make your call accordingly.</p>
</li>
</ol>
<p>I’m using the free tier, and since it’s a hobby project, having a 5 seconds wait time makes sense. I have not faced any issues so far with this.</p>
<div class="gist-block embed-wrapper" data-gist-show-loading="false" data-id="b049fda9e567bc68c7fb33de0ce67cd3">
        <script src="https://gist.github.com/arunachalam-b/b049fda9e567bc68c7fb33de0ce67cd3.js"></script></div><p> </p>
<h3 id="heading-step-5-delete-the-file-uploaded-in-the-gemini-api">Step 5: Delete the File Uploaded in the Gemini API</h3>
<p>After posting all the tweets, it’s time to clean up the system. The only thing we need to do as a clean up is delete the uploaded file. It’s always a best practice to remove an unused file that’s no longer needed. And since we’ve already posted the tweets, we no longer need that file. So, we’ll be deleting it in this step.</p>
<div class="gist-block embed-wrapper" data-gist-show-loading="false" data-id="741c5b13603187c76905f7b349661293">
        <script src="https://gist.github.com/arunachalam-b/741c5b13603187c76905f7b349661293.js"></script></div><p> </p>
<p>That’s it. We’re all done. You just need to copy these blocks of code into an <code>index.js</code> file and install some dependencies into the project and you should be good to go.</p>
<p>To make this even more simple, I have created a repo and made it public. Here’s the <a target="_blank" href="https://github.com/arunachalam-b/existential-crisis-alert-bot">Github repo URL</a>. You just need to clone the repo, install the dependencies, and run the <code>post</code> command</p>
<pre><code class="lang-plaintext">git clone https://github.com/arunachalam-b/existential-crisis-alert-bot.git
cd existential-crisis-alert-bot
npm i
</code></pre>
<p>Create a .env file and update your API keys and secrets in that file:</p>
<pre><code class="lang-plaintext">GEMINI_API_KEY=
TWITTER_API_KEY=
TWITTER_API_SECRET=
TWITTER_ACCESS_TOKEN=
TWITTER_ACCESS_TOKEN_SECRET=
</code></pre>
<p>Run the following command to post the latest AI news to your account:</p>
<pre><code class="lang-plaintext">npm run post
</code></pre>
<h3 id="heading-the-result">The Result</h3>
<p>Here’s a sample output of that command:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1745169397786/14e08ef8-dba5-45e0-a5d5-f3c6135c6347.png" alt="Output" class="image--center mx-auto" width="604" height="308" loading="lazy"></p>
<p>You can modify the code/prompt to fetch data from a different API and post the top results in your Twitter account.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope you now understand how you can automate a slightly complex process using AI and some APIs. Just note that this example is not completely automated. You still have to manually run the command everyday to post the tweets.</p>
<p>But you can automate that process as well. Just drop me a message if you wish to know about that. That topic itself deserves to be a separate tutorial. Also, I would request that you give a star for my project if you enjoyed this tutorial.</p>
<p>Meanwhile, you can follow my <a target="_blank" href="https://x.com/AI_Techie_Arun">Twitter/X account</a> to receive the top AI news everyday. If you wish to learn more about automation, subscribe to my email newsletter (<a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_automated_tweet">https://5minslearn.gogosoon.com/</a>) and follow me on social media.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What Are Scripts and How Do They Work? Improve Your Productivity with Scripting ]]>
                </title>
                <description>
                    <![CDATA[ Developers who have a lot of experience building rigid, quality software tend to automate most of their work by writing scripts. These scripts range from simple alias bash commands to repetitive cron triggers that run on a server. In this tutorial, y... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-are-scripts-and-how-do-they-work/</link>
                <guid isPermaLink="false">679798b5c4e8c2bf2c88f7bc</guid>
                
                    <category>
                        <![CDATA[ scripts ]]>
                    </category>
                
                    <category>
                        <![CDATA[ automation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Mon, 27 Jan 2025 14:31:17 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1737988076418/347e6d8a-1dd8-45d1-854b-fbc576eeed5f.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Developers who have a lot of experience building rigid, quality software tend to automate most of their work by writing scripts. These scripts range from simple alias bash commands to repetitive cron triggers that run on a server.</p>
<p>In this tutorial, you’ll learn about what scripting is, its many use cases, and some advantages and disadvantages of using scripts. We’ll also go through a few example scripts so you can see them in action.</p>
<h2 id="heading-what-is-a-script">What is a Script?</h2>
<p>A script is a set of instructions written in any scripting language (like Bash, Python, JavaScript, and others) that helps you automate tasks or control processes. Unlike compiled programs, scripts are typically <a target="_blank" href="https://www.freecodecamp.org/news/compiled-versus-interpreted-languages/">interpreted</a>, meaning they are executed directly by a runtime environment without prior compilation.</p>
<p>Scripts are powerful tools for automating repetitive tasks, managing workflows, and solving small (and sometimes large) problems efficiently. Whether you’re a beginner or an experienced developer, understanding how to write scripts can enhance your productivity and broaden your technical capabilities.</p>
<h2 id="heading-why-write-scripts">Why Write Scripts?</h2>
<p>I’ve already touched on what you can do with scripts. So let’s look at some of their advantages (and challenges, too) so you understand why they’re so powerful – and when to use them.</p>
<h3 id="heading-advantages-of-scripts">Advantages of scripts</h3>
<ol>
<li><p>Automation: Scripts can help you simplify repetitive tasks such as data processing or file management.</p>
</li>
<li><p>Efficiency: they can also save you time by automating tasks that you would otherwise have to do manually.</p>
</li>
<li><p>Error reduction: Scripts can help reduce human errors through consistent execution of instructions.</p>
</li>
<li><p>Flexibility: Scripts can adapt to a wide variety of tasks with minimal modification.</p>
</li>
<li><p>Integration: They can also seamlessly integrate with other systems, tools, or workflows.</p>
</li>
</ol>
<h3 id="heading-challenges-with-scripts">Challenges with scripts</h3>
<ol>
<li><p>Performance: Scripts can be slower than compiled programs due to interpretation overhead.</p>
</li>
<li><p>Scalability: They’re not always suitable for large-scale or highly complex tasks.</p>
</li>
<li><p>Debugging: Debugging scripts can sometimes be challenging due to their dynamic nature.</p>
</li>
<li><p>Security risks: Poorly written scripts can expose vulnerabilities, especially if they execute system-level commands.</p>
</li>
</ol>
<h3 id="heading-when-to-use-vs-not-use-scripts">When to Use vs Not Use Scripts</h3>
<p>Scripts are ideal for:</p>
<ol>
<li><p>Tasks are simple, well-defined, or one-off</p>
</li>
<li><p>Prototyping or quickly automating a process</p>
</li>
<li><p>The scope is small enough to avoid complexity</p>
</li>
</ol>
<p>Scripts are not ideal for:</p>
<ol>
<li><p>Performance-critical tasks requiring high efficiency. Instead of a script, try using a dedicated ETL (Extract, Transform, Load) tool or a message broker, or similar alternative tools that fit your use-case.</p>
</li>
<li><p>Applications with extensive user interfaces. Instead, you can build a small application or a modular system with proper logging, testing, and documentation.</p>
</li>
<li><p>Scenarios needing long-term maintenance, where compiled programs might be more stable. Instead, use task schedulers or workflow managers like CRON, Airflow, AWS Lambda/GCP Functions.</p>
</li>
</ol>
<h2 id="heading-how-to-write-effective-scripts">How to Write Effective Scripts</h2>
<p>This is the process I use for writing helpful scripts. After we go through this, we’ll see some examples of scripts in different languages so you can get some hands-on practice.</p>
<ol>
<li><p>Define the problem: Before writing a script, identify the problem it will solve. Be clear about the tasks to automate and the expected outcomes.</p>
</li>
<li><p>Choose the right language:</p>
<ul>
<li><p><strong>Bash:</strong> Ideal for system-level tasks like file operations or server management.</p>
</li>
<li><p><strong>Python:</strong> Great for data processing, web scraping, and more complex automation.</p>
</li>
<li><p><strong>JavaScript:</strong> Suited for web development and browser-based automation.</p>
</li>
</ul>
</li>
<li><p>Write the script: Use a text editor or an Integrated Development Environment (IDE), and make sure you follow best practices like using comments, meaningful variable names, and modular code. We’ll cover these below.</p>
</li>
<li><p>Test the script: Test the script in a controlled environment to ensure it performs as expected without causing errors.</p>
</li>
<li><p>Execute and deploy: Run the script in its intended environment. If necessary, schedule its execution using tools like Cron (for Bash) or task schedulers.</p>
</li>
</ol>
<h2 id="heading-example-scripts">Example Scripts</h2>
<p>Now that you know the basics, let's have some practice. Assume you have around 100 files with the names “book-part-1.pdf”, “book-part-2.pdf”, …, “book-part-100.pdf”. You want to replace all the hyphens (-) in the file names with underscores (_), because the website where you're trying to upload these documents doesn’t allow you to upload files with names containing hyphens.</p>
<p>Here are scripts written in three different languages that all perform the same operation. The process looks like this:</p>
<ol>
<li><p>find all the files in a directory,</p>
</li>
<li><p>check if they contain hyphens (-) in their name, and</p>
</li>
<li><p>replace any hyphens with underscores (_).</p>
</li>
</ol>
<p>Here are the file names to start (containing hyphens):</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737563509852/e9b1e671-465d-43ed-a831-3034852de624.png" alt="File names with hyphen" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-bash-script">Bash Script</h3>
<p>We’ll start with a bash script. Here it is:</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-comment"># Replace "-" with "_" in file names</span>
DIRECTORY=<span class="hljs-string">"/path/to/your/folder"</span>
<span class="hljs-keyword">for</span> FILE <span class="hljs-keyword">in</span> <span class="hljs-string">"<span class="hljs-variable">$DIRECTORY</span>"</span>/*; <span class="hljs-keyword">do</span>
    <span class="hljs-keyword">if</span> [[ <span class="hljs-string">"<span class="hljs-variable">$FILE</span>"</span> == *-* ]]; <span class="hljs-keyword">then</span>
        NEW_NAME=$(<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$FILE</span>"</span> | sed <span class="hljs-string">'s/-/_/g'</span>)
        mv <span class="hljs-string">"<span class="hljs-variable">$FILE</span>"</span> <span class="hljs-string">"<span class="hljs-variable">$NEW_NAME</span>"</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"Renamed: <span class="hljs-variable">$FILE</span> -&gt; <span class="hljs-variable">$NEW_NAME</span>"</span>
    <span class="hljs-keyword">fi</span>
<span class="hljs-keyword">done</span>
</code></pre>
<p>We define the directory (folder) at the top where our files reside. For each file in the directory, we check if the name contains a <code>-</code>. In such case, we create a new file name and store it in the variable <code>NEW_NAME</code> by copying the old file name using the <code>echo</code> command and replace the <code>-</code> with <code>_</code> using the <code>sed</code> command. Finally we use the move command <code>mv</code> with the old and new file names as arguments.</p>
<h3 id="heading-python-script">Python Script</h3>
<p>Next, let’s see what it would look like in Python:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> os
<span class="hljs-comment"># Replace "-" with "_" in file names</span>
directory = <span class="hljs-string">"/path/to/your/folder"</span>
<span class="hljs-keyword">for</span> filename <span class="hljs-keyword">in</span> os.listdir(directory):
    <span class="hljs-keyword">if</span> <span class="hljs-string">"-"</span> <span class="hljs-keyword">in</span> filename:
        old_path = os.path.join(directory, filename)
        new_filename = filename.replace(<span class="hljs-string">"-"</span>, <span class="hljs-string">"_"</span>)
        new_path = os.path.join(directory, new_filename)
        os.rename(old_path, new_path)
        print(<span class="hljs-string">f"Renamed: <span class="hljs-subst">{filename}</span> -&gt; <span class="hljs-subst">{new_filename}</span>"</span>)
</code></pre>
<p>The steps are pretty similar in Python. First, we define the directory and then iterate through each file in the directory. To find all files in the directory, we have to use the <code>listdir</code> method from the <code>os</code> package.</p>
<p>Then we check if the file name contains a <code>-</code> in the next line. In such a case, we find the current path (<code>old_path</code>) of the file by merging the directory and its file name. We can create the new file name by replacing the <code>-</code> with <code>_</code> using the <code>replace</code> method.</p>
<p>We then generate the new file path (<code>new_path</code>) in the similar way we generate the <code>old_path</code>. Finally, we call the <code>rename</code> method in <code>os</code> package with old and new file paths as arguments.</p>
<h3 id="heading-javascript-script">JavaScript Script</h3>
<p>And now let’s see how it would look in JavaScript:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);
<span class="hljs-keyword">const</span> directory = <span class="hljs-string">'/path/to/your/folder'</span>;

fs.readdir(directory, <span class="hljs-function">(<span class="hljs-params">err, files</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (err) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error reading directory:'</span>, err);
        <span class="hljs-keyword">return</span>;
    }
    files.forEach(<span class="hljs-function"><span class="hljs-params">file</span> =&gt;</span> {
        <span class="hljs-keyword">if</span> (file.includes(<span class="hljs-string">'-'</span>)) {
            <span class="hljs-keyword">const</span> oldPath = path.join(directory, file);
            <span class="hljs-keyword">const</span> newFilename = file.replace(<span class="hljs-regexp">/-/g</span>, <span class="hljs-string">'_'</span>);
            <span class="hljs-keyword">const</span> newPath = path.join(directory, newFilename);
            fs.rename(oldPath, newPath, <span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> {
                <span class="hljs-keyword">if</span> (err) {
                    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">`Error renaming <span class="hljs-subst">${file}</span>:`</span>, err);
                } <span class="hljs-keyword">else</span> {
                    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Renamed: <span class="hljs-subst">${file}</span> -&gt; <span class="hljs-subst">${newFilename}</span>`</span>);
                }
            });
        }
    });
});
</code></pre>
<p>The JavaScript implementation is somewhat similar to the Python implementation – but you’ll need to write more code. Generally, devs don’t prefer JavaScript for these kind of scripts. Most of them rely on Bash/Python. JavaScript is better-suited for browser-based automation scripts.</p>
<p>Still, let’s see what we have here. In this JavaScript code, you have to use two different packages, <code>fs</code> and <code>path</code>. We define the directory at the top, read the files in the directory using the <code>readdir</code> method from the <code>fs</code> package, and pass the directory as the argument. Along with directory, we also pass a callback function that will be executed once the files are read.</p>
<p>Inside the callback function, we loop through each file and check if the file name includes a hyphen (<code>-</code>). If it does, we find the old path using the <code>path</code> package with the directory and file names as arguments. We then construct the new file name by replacing all hyphens with underscores using the <code>replace</code> method.</p>
<p>Similar to the old path, we find the new path using the new file name as an argument. Then we use the <code>rename</code> method from the <code>fs</code> package to rename the file by passing both the old and new file names. If there are errors during renaming or reading the files in a directory, we log the error message. Otherwise, we log the success message.</p>
<h4 id="heading-how-to-run-these-scripts">How to run these scripts</h4>
<p>Ok, here’s how you can actually use these scripts:</p>
<ol>
<li><p>Replace <code>/path/to/your/folder</code> with the actual directory containing the files.</p>
</li>
<li><p>Run the script in the corresponding environment:</p>
<ul>
<li><p><strong>Bash:</strong> Save as a <code>.sh</code> file, then execute with <code>bash script.sh</code></p>
</li>
<li><p><strong>Python:</strong> Save as a <code>.py</code> file, then execute with <code>python script.py</code></p>
</li>
<li><p><strong>JavaScript:</strong> Save as a <code>.js</code> file, then execute with <code>node script.js</code></p>
</li>
</ul>
</li>
</ol>
<p>The screenshot below shows running the bash script to change the names of the files.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737563774216/f31158ab-da77-4b18-8625-ee0b2522e3e6.png" alt="Change the name of files using bash script" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737563640766/4aa508af-1f0e-4fad-8b2c-ac2369cbe337.png" alt="After running the script, the hyphens in file name are replaced with underscores" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-recurring-scripts">Recurring Scripts</h2>
<p>Recurring scripts are designed to execute at regular intervals, like checking a system’s status weekly, cleaning up logs, or fetching data updates. These scripts typically use some form of task scheduler.</p>
<h3 id="heading-common-approaches">Common Approaches</h3>
<ol>
<li><p>CRON jobs: Most operating systems support CRON, which can trigger scripts based on a defined schedule.</p>
</li>
<li><p>Task queues: Tools like Celery (Python), Bull (Node.js), or Sidekiq (Ruby) can handle scheduled jobs with more flexibility.</p>
</li>
<li><p>Cloud schedulers: Services like AWS Lambda with EventBridge, Google Cloud Scheduler, or Azure Logic Apps allow you to set up recurring scripts in a serverless architecture.</p>
</li>
</ol>
<p>One good example use case for recurring scripts would be sending a daily/weekly report of your system’s usage/performance. You could write a script that finds the number of users who have joined and subscribed to your product and send that report as an email every day/week.</p>
<h2 id="heading-best-practices-for-writing-scripts">Best Practices for Writing Scripts</h2>
<p>Here are some things to keep in mind when you’re writing scripts:</p>
<p><strong>1. Use comments</strong>: Explain complex parts of the script with comments.</p>
<p>In the below example, without the comment, someone might have to spend extra time figuring out why the tax rate is a decimal and not a percentage.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Calculate the total price with tax</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">calculate_price_with_tax</span>(<span class="hljs-params">price, tax_rate</span>):</span>
    <span class="hljs-comment"># Tax rate is expressed as a decimal (e.g., 0.07 for 7%)</span>
    <span class="hljs-keyword">return</span> price + (price * tax_rate)
</code></pre>
<p>2. <strong>Error handling</strong>: Account for possible errors and handle them gracefully.</p>
<p>In the below example, if the file is missing, the script won’t crash – instead, it will show a helpful error message.</p>
<pre><code class="lang-python"><span class="hljs-keyword">try</span>:
    <span class="hljs-keyword">with</span> open(<span class="hljs-string">'data.csv'</span>, <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> file:
        data = file.readlines()
<span class="hljs-keyword">except</span> FileNotFoundError:
    print(<span class="hljs-string">"Error: 'data.csv' file not found. Make sure the file exists before running the script."</span>)
<span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
    print(<span class="hljs-string">f"An unexpected error occurred: <span class="hljs-subst">{e}</span>"</span>)
</code></pre>
<p>3. <strong>Modular design</strong>: Break down the script into reusable functions or modules.</p>
<p>In the below example, by separating functionality into smaller, reusable functions, you can debug or reuse parts of the script independently.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fetch_data_from_api</span>(<span class="hljs-params">api_url</span>):</span>
    <span class="hljs-comment"># Fetch data from the given API</span>
    <span class="hljs-keyword">pass</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">process_data</span>(<span class="hljs-params">data</span>):</span>
    <span class="hljs-comment"># Process the data into the desired format</span>
    <span class="hljs-keyword">pass</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">save_to_file</span>(<span class="hljs-params">data, filename</span>):</span>
    <span class="hljs-comment"># Save processed data to a file</span>
    <span class="hljs-keyword">pass</span>

<span class="hljs-comment"># Main script</span>
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    data = fetch_data_from_api(<span class="hljs-string">"https://example.com/api"</span>)
    processed_data = process_data(data)
    save_to_file(processed_data, <span class="hljs-string">"output.json"</span>)
</code></pre>
<p>4. <strong>Input validation</strong>: Validate user inputs to prevent unexpected errors or security risks.</p>
<p>Without validation, someone could input invalid or malicious data (for example, SQL injection strings in certain scenarios).</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> re

<span class="hljs-comment"># Validate that the input is a valid email address</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">validate_email</span>(<span class="hljs-params">email</span>):</span>
    pattern = <span class="hljs-string">r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'</span>
    <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> re.match(pattern, email):
        <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">"Invalid email address format"</span>)
    <span class="hljs-keyword">return</span> email

<span class="hljs-comment"># Example usage</span>
<span class="hljs-keyword">try</span>:
    user_email = validate_email(input(<span class="hljs-string">"Enter your email: "</span>))
    print(<span class="hljs-string">f"Valid email: <span class="hljs-subst">{user_email}</span>"</span>)
<span class="hljs-keyword">except</span> ValueError <span class="hljs-keyword">as</span> e:
    print(e)
</code></pre>
<p>5. <strong>Version control</strong>: Use Git or other version control tools to track changes.</p>
<p>If a change breaks the script, you can easily revert to a previous commit using <code>git checkout</code>. Plus, you can collaborate seamlessly with team members.</p>
<pre><code class="lang-bash">git init
git add script.py
git commit -m <span class="hljs-string">"Initial commit"</span>
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Writing scripts is a skill that can significantly boost your productivity and problem-solving abilities. By understanding the basics of scripting languages like Bash, Python, and JavaScript, you can automate tasks, streamline workflows, and save valuable time. Start small, build incrementally, and practice writing scripts for different use cases to master this invaluable skill.</p>
<p>I have an exercise for you. To run and verify this example script, you may think you have to manually create 100 files. That consumes a lot of time.</p>
<p>I wrote a script to generate those 100 files. I would also recommend that you try writing a script to generate 100 files with hyphens in their file names. Then try to run the example script to convert the hyphens to underscores.</p>
<p>This may sound difficult at the beginning, but believe me you just need to write 5 lines of bash code to generate 100 files. Not just 100 – you can even generate a million/billion/trillion files with just 5 lines of code.</p>
<p>If you wish to learn more about Scripts, subscribe to my <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_what_are_scripts">email newsletter (https://5minslearn.gogosoon.com/)</a> and follow me on social media.</p>
<p>Happy scripting!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use the Sliding Window Technique – Algorithm Example and Solution ]]>
                </title>
                <description>
                    <![CDATA[ Recently, I was practicing coding problems that focused on Data Structures and Algorithms in preparation for a job change.  During this process, I came across the Sliding Window technique. I found this algorithm to be very interesting, so I wanted to... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/sliding-window-technique/</link>
                <guid isPermaLink="false">66ba10f3da6e5d90e89ee191</guid>
                
                    <category>
                        <![CDATA[ algorithms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data structures ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Thu, 11 Jan 2024 15:11:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/Sliding-Window-Technique---Banner.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Recently, I was practicing coding problems that focused on Data Structures and Algorithms in preparation for a job change. </p>
<p>During this process, I came across the Sliding Window technique. I found this algorithm to be very interesting, so I wanted to share my learnings with the community. </p>
<p>This tutorial will be useful for you if you're preparing for competitive programming interviews. So, let's get started. </p>
<h2 id="heading-what-is-the-sliding-window-technique">What is the Sliding Window Technique?</h2>
<p>The sliding window technique is an algorithmic approach used in computer science and signal processing. It involves selecting a fixed-size subset, or "window," from a larger dataset and moving this window through the dataset in a step-wise fashion. </p>
<p>The window slides over the data, typically one element at a time, and performs some operation on the elements within the window at each step. </p>
<p>Are you confused? Let me elaborate on this technique with an example. </p>
<h3 id="heading-sliding-window-example">Sliding Window example</h3>
<p>Assume you're practicing for competitive programming and you encounter the following problem:</p>
<p>"Find the maximum sum of sub-array of size k with the time complexity of O(N).</p>
<p>Array = [1, 2, 6, 2, 4, 1], k = 3"</p>
<p>If you're not familiar with the concept of time complexity, here's a quick definition:</p>
<blockquote>
<p>In theoretical computer science, the time complexity is the computational complexity that describes the amount of computer time it takes to run an algorithm.</p>
</blockquote>
<p>And <a target="_blank" href="https://www.freecodecamp.org/news/learn-big-o-notation/">here's a course</a> if you'd like to learn more.</p>
<p>Back to our problem. Basically, we have to find the sub-array of size 3, whose sum is the maximum (largest number). Here's a pictorial view of how we can go about solving this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/image-27.png" alt="Image" width="600" height="400" loading="lazy">
<em>Find sum of sub-array of size k</em></p>
<h4 id="heading-manual-solution">Manual solution</h4>
<p>Let's solve it manually. From the above image, let's find the sum of each of the sub-arrays of size 3. </p>
<ul>
<li>Sum of 1st sub-array = 1 + 2 + 6 = 9</li>
<li>Sum of 2nd sub-array = 2 + 6 + 2 = 10</li>
<li>Sum of 3rd sub-array = 6 + 2 + 4 = 12</li>
<li>Sum of 4th sub-array = 2 + 4 + 1 = 7</li>
</ul>
<p>The maximum (biggest) number among 9, 10, 12, and 7 is 12 – or the 3rd sub-array. That is our solution. </p>
<h4 id="heading-code-solution">Code solution</h4>
<p>Alright, let's wear our programming shoes and try to solve this using code. </p>
<p>Here's my solution to the problem:</p>


<p>Here's a quick walk through of the above code. </p>
<p>I'm defining the input array and window size at the bottom, and calling the method <code>findMaxSumOfSequence</code> with these parameters. </p>
<p>Initially I'm doing a validation if the input array size is more than the window size, else the calculation is not possible, so return null. </p>
<p>I'm assuming the maximum sum to be negative infinity. </p>
<p>I iterate over the array, and for each item in the array, I iterate for next <code>k</code> items, find their sum, and assign the current window sum to maximum sum variable if the current window sum is more than existing maximum sum. Finally, return the maximum sum. </p>
<p>Let's try to run the code. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/image-26.png" alt="Image" width="600" height="400" loading="lazy">
<em>Find maximum sum of a sub-array of size k</em></p>
<p>Here we go. We got the right answer. </p>
<p>But, the problem does not stop here. If you look at the problem carefully, we have to find the solution in O(N) time complexity. </p>
<p>So, you might wonder what's the time complexity of the above solution. Well, the time complexity of the above solution is O(N*k). This means, we're iterating <code>k</code> times for each item in the array (nested for-loop). </p>
<p>O(N) time complexity basically describes that you have to find the maximum value by iterating over the given array only once. </p>
<h4 id="heading-using-the-sliding-window-technique">Using the Sliding Window technique</h4>
<p>How do we solve this with one iteration? Here's where sliding window technique comes into play. Let's take a look at the pictorial representation of our solution once again:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/image-27.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sliding window technique</em></p>
<p>Here, you may notice that the window slides over the array. It's initially covering the indices 0, 1, and 2 in the 1st sub-array. For the next sub-array, it slides one-position to the right, eliminating 0th index to the left and adding the 3rd index to the right. So, now it covers the 1, 2, and 3 in the 2nd sub-array...and so on. </p>
<p>The calculation goes this way for the sub-arrays:</p>
<ul>
<li>1st sub-array = 1 + 2 + 6 = 9</li>
<li>2nd sub-array = 9 (sum of 1st sub-array) - 1 + 2 = 10</li>
</ul>
<p>Let's take a look at this carefully. We find the sum of 1st sub-array to be 9. To calculate the sum of 2nd sub-array, we subtract the number that's going out (1 at 0th index) and add the number that's coming in (2 at 3rd index). </p>
<ul>
<li>3rd sub-array = 10 (sum of 2nd sub-array) - 2 + 4 = 12</li>
<li>4th sub-array = 12 (sum of 3rd sub-array) - 6 + 1 = 7</li>
</ul>
<p>This is the sliding window technique. Following this technique, we'll able to find the sum of maximum sub-array in a single iteration. </p>
<h4 id="heading-how-to-implement-sliding-window-in-code">How to implement Sliding Window in code</h4>
<p>Alright, let's put on our coding shoes again and try to implement this. </p>


<p>Let's try to understand the above code. I made some changes to the <code>findMaxSumOfSequence</code> method. I introduced <code>start</code> and <code>end</code> variables which describe the window block. </p>
<p>In this implementation, we have 2 loops but they're not nested. This is because, in the first loop, we have to find the sum of the 1st window. The second loop will subtract and add items from the result of the first loop. </p>
<p>From the above example, the first loop will iterate over the first k items (3) which are 1, 2, and 6. I calculate the sum and store them in the <code>maxSum</code> and <code>windowSum</code> variables. </p>
<p>In the next loop, I'm iterating over each item in the array. For each item, I'm subtracting the previous number and adding the next number, and updating the result in the <code>windowSum</code> variable. I compare the <code>windowSum</code> and <code>maxSum</code> variables and update the <code>maxSum</code> variable if the <code>windowSum</code> is larger. Then I move the window to the next sub-array by incrementing the <code>start</code> and <code>end</code> variables. Finally, I return the maximum sum. </p>
<p>Here's the output of the above code:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/image-32.png" alt="Image" width="600" height="400" loading="lazy">
<em>Find maximum sum of a sub-array of size k using sliding window technique</em></p>
<p>With this implementation, we have satisfied the problem's requirement by iterating over the array only once and finding the maximum sum of a sub-array (with O(N) time complexity). </p>
<h2 id="heading-applications-of-the-sliding-window-technique">Applications of the Sliding Window Technique</h2>
<p>The Sliding Window Technique is versatile and finds applications in various domains. </p>
<p><strong>Array and String Manipulation</strong>: In array or string processing, a sliding window can be used to efficiently perform operations such as finding subarrays or substrings that satisfy certain conditions.</p>
<p><strong>Data Compression</strong>: Sliding window compression algorithms, like LZ77 and its variants, use a window to find repeated patterns in the input data and replace them with references to previous occurrences.</p>
<p><strong>Image Processing</strong>: In image processing, a sliding window can be employed for tasks such as feature extraction, object detection, or image segmentation.</p>
<p><strong>Signal Processing</strong>: Time-series data can be analyzed using a sliding window to capture local patterns, trends, or anomalies.</p>
<p><strong>Network Protocols</strong>: Sliding window protocols are used in computer networks for reliable and efficient data transmission. The sender and receiver maintain a window of allowable sequence numbers to manage the flow of data. </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Hope you now have a clear idea of how the Sliding Window Technique works after seeing these examples. I would recommend that you try to solve some other problems with this technique to get familiar with it. Trying to find the minimum sum of the sub-array of size k on your own using this technique would be a helpful exercise.</p>
<p>As I mentioned earlier, I'm actively looking to switch my job. If you have a good position available in your organization, please refer <a target="_blank" href="https://arunachalam-b.github.io/">me</a>. </p>
<p>Hope you enjoyed reading this article. If you wish to learn more about techniques to crack competitive programming interviews, subscribe to my newsletter by visiting my <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_sliding_window_technique">site</a> which also has a consolidated list of all my blogs. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Binary Classification with TensorFlow Tutorial ]]>
                </title>
                <description>
                    <![CDATA[ Binary classification is a fundamental task in machine learning, where the goal is to categorize data into one of two classes or categories.  Binary classification is used in a wide range of applications, such as spam email detection, medical diagnos... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/binary-classification-made-simple-with-tensorflow/</link>
                <guid isPermaLink="false">66ba10937282cc17abcf0c66</guid>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TensorFlow ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Thu, 21 Sep 2023 14:21:22 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/09/Binary-Classification-Made-Simple-with-TensorFlow.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Binary classification is a fundamental task in machine learning, where the goal is to categorize data into one of two classes or categories. </p>
<p>Binary classification is used in a wide range of applications, such as spam email detection, medical diagnosis, sentiment analysis, fraud detection, and many more.</p>
<p>In this article, we'll explore binary classification using TensorFlow, one of the most popular deep learning libraries.</p>
<p>Before getting into the Binary Classification, let's discuss a little about classification problem in Machine Learning.</p>
<h2 id="heading-what-is-classification-problem">What is Classification problem?</h2>
<p>A Classification problem is a type of machine learning or statistical problem in which the goal is to assign a category or label to a set of input data based on their characteristics or features. The objective is to learn a mapping between input data and predefined classes or categories, and then use this mapping to predict the class labels of new, unseen data points.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-89.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sample Multi Classification</em></p>
<p>The above diagram represents a multi-classification problem in which the data will be classified into more than two (three here) types of classes.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-90.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sample Binary Classification</em></p>
<p>This diagram defines Binary Classification, where data is classified into two type of classes.</p>
<p>This simple concept is enough to understand classification problems. Let's explore this with a real-life example.</p>
<h2 id="heading-heart-attack-analytics-prediction-using-binary-classification">Heart Attack Analytics Prediction Using Binary Classification</h2>
<p>In this article, we will embark on the journey of constructing a predictive model for heart attack analysis utilizing straightforward deep learning libraries. </p>
<p>The model that we'll be building, while being a relatively simple neural network, is capable of achieving an accuracy level of approximately 80%.</p>
<p>Solving real-world problems through the lens of machine learning entails a series of essential steps:</p>
<ol>
<li>Data Collection and Analytics</li>
<li>Data preprocessing</li>
<li>Building ML Model</li>
<li>Train the Model</li>
<li>Prediction and Evaluation</li>
</ol>
<h2 id="heading-data-collection-and-analytics">Data Collection and Analytics</h2>
<p>It's worth noting that for this project, I obtained the dataset from <a target="_blank" href="https://www.kaggle.com/datasets/rashikrahmanpritom/heart-attack-analysis-prediction-dataset">Kaggle</a>, a popular platform for data science competitions and datasets. </p>
<p>I encourage you to take a closer look at its contents. Understanding the dataset is crucial as it allows you to grasp the nuances and intricacies of the data, which can help you make informed decisions throughout the machine learning pipeline.</p>
<p>This dataset is well-structured, and there's no immediate need for further analysis. However, if you are collecting the dataset on your own, you will need to perform data analytics and visualization independently to achieve better accuracy.</p>
<p>Let's put on our coding shoes. </p>
<p>Here I am using Google Colab. You can use your own machine (in which case you will need to create a <code>.ipynb</code> file) or Google Colab on your account to run the notebook. You can find my source code <a target="_blank" href="https://colab.research.google.com/drive/1-LBbym1bcTP6qF9tiENCzUVLGoY_NWMj?usp=sharing">here</a>.</p>
<p>As the first step, let's import the required libraries.</p>
<pre><code><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np
<span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt
<span class="hljs-keyword">from</span> sklearn.model_selection <span class="hljs-keyword">import</span> train_test_split
<span class="hljs-keyword">import</span> sklearn
<span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd
<span class="hljs-keyword">import</span> keras
<span class="hljs-keyword">from</span> keras.models <span class="hljs-keyword">import</span> Sequential
<span class="hljs-keyword">from</span> keras.layers <span class="hljs-keyword">import</span> Dense
<span class="hljs-keyword">import</span> tensorflow <span class="hljs-keyword">as</span> tf
<span class="hljs-keyword">from</span> sklearn.metrics <span class="hljs-keyword">import</span> confusion_matrix,ConfusionMatrixDisplay
<span class="hljs-keyword">from</span> sklearn.preprocessing <span class="hljs-keyword">import</span> MinMaxScaler
</code></pre><p>I have the dataset in my drive and I'm reading it from my drive. You can download the same dataset <a target="_blank" href="https://www.kaggle.com/datasets/rashikrahmanpritom/heart-attack-analysis-prediction-dataset">here</a>. </p>
<p>Remember the replace the path of your file in the <code>read_csv</code> method:</p>
<pre><code>df = pd.read_csv(<span class="hljs-string">"/content/drive/MyDrive/Datasets/heart.csv"</span>)
df.head()
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-91.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sample 5 record in the dataset</em></p>
<p>The dataset contains thirteen input columns (age, sex, cp, and so on) and one output column (<code>output</code>), which will contain the data as either <code>0</code> or <code>1</code>.</p>
<p>Considering the input readings, <code>0</code> in the <code>output</code> represents the person will not get heart attack, while the <code>1</code> represents the person will be affected by heart attack.</p>
<p>Let's split our input and output from the above dataset to train our model:</p>
<pre><code>target_column = <span class="hljs-string">"output"</span>
numerical_column = df.columns.drop(target_column)
output_rows = df[target_column]
df.drop(target_column,axis=<span class="hljs-number">1</span>,inplace=True)
</code></pre><p>Since our objective is to predict the likelihood of a heart attack (0 or 1), represented by the target column, we split that into a separate dataset.</p>
<h2 id="heading-data-preprocessing">Data preprocessing</h2>
<p>Data preprocessing is a crucial step in the machine learning pipeline, and binary classification is no exception. It involves the cleaning, transformation, and organization of raw data into a format that is suitable for training machine learning models.</p>
<p>A dataset will contain multiple type of data such as Numerical Data, Categorical Data, Timestamp Data, and so on. </p>
<p>But most of the Machine Learning algorithms are designed to work with numerical data. They require input data to be in a numeric format for mathematical operations, optimization, and model training.</p>
<p>In this dataset, all the columns contain numerical data, so we don't need to encode the data. We can proceed with simple normalization. </p>
<p>Remember if you have any non-numerical columns in your dataset, you may have to convert it into numerical by performing one-hot encoding or using other encoding algorithms.</p>
<p>There are lot of normalization strategies. Here I am using Min-Max Normalization:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-92.png" alt="Image" width="600" height="400" loading="lazy">
<em>Min-Max Scaling Formula</em></p>
<p>Don't worry  – we don't need to apply this formula manually. We have some machine learning libraries to do this. Here I am using MinMaxScaler from sklearn:</p>
<pre><code>scaler = MinMaxScaler()
scaler.fit(df)
t_df = scaler.transform(df)
</code></pre><p><code>scaler.fit(df)</code>  computes the mean and standard deviation (or other scaling parameters) necessary to perform the scaling operation. The <code>fit</code> method essentially learns these parameters from the data.</p>
<p><code>t_df = scaler.transform(df)</code>: After fitting the scaler, we need to transform the dataset. The transformation typically scales the features to have a mean of 0 and a standard deviation of 1 (standardization) or scales them to a specific range (for example, [0, 1] with Min-Max scaling) depending on the scaler used.</p>
<p>We have completed the preprocessing. The next crucial step is to split the dataset into training and testing sets.</p>
<p>To accomplish this, I will utilize the <code>train_test_split</code> function from <code>scikit-learn</code>.</p>
<p><code>X_train</code> and <code>X_test</code> are the variables that hold the independent variables.</p>
<p><code>y_train</code> and <code>y_test</code> are the variables that hold the dependent variable, which represents the output we are aiming to predict.</p>
<pre><code>X_train, X_test, y_train, y_test = train_test_split(t_df, output_rows, test_size=<span class="hljs-number">0.25</span>, random_state=<span class="hljs-number">0</span>)
</code></pre><pre><code>print(<span class="hljs-string">'X_train:'</span>,np.shape(X_train))
print(<span class="hljs-string">'y_train:'</span>,np.shape(y_train))
print(<span class="hljs-string">'X_test:'</span>,np.shape(X_test))
print(<span class="hljs-string">'y_test:'</span>,np.shape(y_test))
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-93.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sample training and testing dataset size</em></p>
<p>We split the dataset by 75% and 25%, where 75% goes for training our model and 25% goes for testing our model.</p>
<h2 id="heading-building-ml-model">Building ML Model</h2>
<p>A machine learning model is a computational representation of a problem or a system that is designed to learn patterns, relationships, and associations from data. It serves as a mathematical and algorithmic framework capable of making predictions, classifications, or decisions based on input data. </p>
<p>In essence, a model encapsulates the knowledge extracted from data, allowing it to generalize and make informed responses to new, previously unseen data.</p>
<p>Here, I am building a simple sequential model with one input layer and one output layer. Being a simple model, I am not using any hidden layer as it might increase the complexity of the concept.</p>
<h3 id="heading-initialize-sequential-model">Initialize Sequential Model</h3>
<pre><code>basic_model = Sequential()
</code></pre><p><code>Sequential</code> is a type of model in Keras that allows you to create neural networks layer by layer in a sequential manner. Each layer is added on top of the previous one.</p>
<h3 id="heading-input-layer">Input Layer</h3>
<pre><code>basic_model.add(Dense(units=<span class="hljs-number">16</span>, activation=<span class="hljs-string">'relu'</span>, input_shape=(<span class="hljs-number">13</span>,)))
</code></pre><p><code>Dense</code> is a type of layer in Keras, representing a fully connected layer. It has 16 units, which means it has 16 neurons.</p>
<p><code>activation='relu'</code> specifies the Rectified Linear Unit (ReLU) activation function, which is commonly used in input or hidden layers of neural networks.</p>
<p><code>input_shape=(13,)</code> indicates the shape of the input data for this layer. In this case, we are using 13 input features (columns).</p>
<h3 id="heading-output-layer">Output Layer</h3>
<pre><code>basic_model.add(Dense(<span class="hljs-number">1</span>, activation=<span class="hljs-string">'sigmoid'</span>))
</code></pre><p>This line adds the output layer to the model. </p>
<p>It's a single neuron (1 unit) because this appears to be a binary classification problem, where you're predicting one of two classes (0 or 1). </p>
<p>The activation function used here is <code>'sigmoid'</code>, which is commonly used for binary classification tasks. It squashes the output to a range between 0 and 1, representing the probability of belonging to one of the classes.</p>
<h3 id="heading-optimizer">Optimizer</h3>
<pre><code>adam = keras.optimizers.Adam(learning_rate=<span class="hljs-number">0.001</span>)
</code></pre><p>This line initializes the Adam optimizer with a learning rate of 0.001. The optimizer is responsible for updating the model's weights during training to minimize the defined loss function.</p>
<h3 id="heading-compile-model">Compile Model</h3>
<pre><code>basic_model.compile(loss=<span class="hljs-string">'binary_crossentropy'</span>, optimizer=adam, metrics=[<span class="hljs-string">"accuracy"</span>])
</code></pre><p>Here, we'll compile the model.</p>
<p><code>loss='binary_crossentropy'</code> is the loss function used for binary classification. It measures the difference between the predicted and actual values and is minimized during training.</p>
<p><code>metrics=["accuracy"]</code>: During training, we want to monitor the accuracy metric, which tells you how well the model is performing in terms of correct predictions.</p>
<h3 id="heading-train-model-with-dataset">Train model with dataset</h3>
<p>Hurray, we built the model. Now it's time to train the model with our training dataset.</p>
<pre><code>basic_model.fit(X_train, y_train, epochs=<span class="hljs-number">100</span>)
</code></pre><p><code>X_train</code> represents the training data, which consists of the independent variables (features). The model will learn from these features to make predictions or classifications.</p>
<p><code>y_train</code> are the corresponding target labels or dependent variables for the training data. The model will use this information to learn the patterns and relationships between the features and the target variable.</p>
<p><code>epochs=100</code>: The <code>epochs</code> parameter specifies the number of times the model will iterate over the entire training dataset. Each pass through in the dataset is called an epoch. In this case, we have 100 epochs, meaning the model will see the entire training dataset 100 times during training.</p>
<pre><code>loss_and_metrics = basic_model.evaluate(X_test, y_test)
print(loss_and_metrics)
print(<span class="hljs-string">'Loss = '</span>,loss_and_metrics[<span class="hljs-number">0</span>])
print(<span class="hljs-string">'Accuracy = '</span>,loss_and_metrics[<span class="hljs-number">1</span>])
</code></pre><p>The <code>evaluate</code> method is used to assess how well the trained model performs on the test dataset. It computes the loss (often the same loss function used during training) and any specified metrics (for example, accuracy) for the model's predictions on the test data.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-94.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sample output to find the Loss and Accuracy</em></p>
<p>Here we got around 82% accuracy.</p>
<h2 id="heading-prediction-and-evaluation">Prediction and Evaluation</h2>
<pre><code>predicted = basic_model.predict(X_test)
</code></pre><p>The <code>predict</code> method is used to generate predictions from the model based on the input data (<code>X_test</code> in this case). The output (<code>predicted</code>) will contain the model's predictions for each data point in the training dataset. </p>
<p>Since I have only minimum dataset I am using the test dataset for prediction. However, it is a  recommend practice to split a part of dataset (say 10%) to use as a validation dataset.</p>
<h3 id="heading-evaluation">Evaluation</h3>
<p>Evaluating predictions in machine learning is a crucial step to assess the performance of a model. </p>
<p>One commonly tool used for evaluating classification models is the confusion matrix. Let's explore what a confusion matrix is and how it's used for model evaluation:</p>
<p>In a binary classification problem (two classes, for example, "positive" and "negative"), a confusion matrix typically looks like this:</p>
<table><tbody><tr><td></td><td>Predicted Negative (0)</td><td>Predicted Positive (1)</td></tr><tr><td>Actual Negative (0)</td><td>True Negative</td><td>False Positive</td></tr><tr><td>Actual Positive (1)</td><td>False Negative</td><td>True Positive</td></tr></tbody></table>

<p>Here's the code to plot the confusion matrix from the predicted data of our model:</p>
<pre><code>predicted = tf.squeeze(predicted)
predicted = np.array([<span class="hljs-number">1</span> <span class="hljs-keyword">if</span> x &gt;= <span class="hljs-number">0.5</span> <span class="hljs-keyword">else</span> <span class="hljs-number">0</span> <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> predicted])
actual = np.array(y_test)
conf_mat = confusion_matrix(actual, predicted)
displ = ConfusionMatrixDisplay(confusion_matrix=conf_mat)
displ.plot()
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-95.png" alt="Image" width="600" height="400" loading="lazy">
<em>Confusion matrix for the predicted output</em></p>
<p>Bravo! We've made significant progress toward obtaining the required output, with approximately 84% of the data appearing to be correct. </p>
<p>It's worth noting that we can further optimize this model by leveraging a larger dataset and fine-tuning the hyper-parameters. However, for a foundational understanding, what we've accomplished so far is quite impressive.</p>
<p>Given that this dataset and the corresponding machine learning models are at a very basic level, it's important to acknowledge that real-world scenarios often involve much more complex datasets and machine learning tasks. </p>
<p>While this model may perform adequately for simple problems, it may not be suitable for tackling more intricate challenges.</p>
<p>In real-world applications, datasets can be vast and diverse, containing a multitude of features, intricate relationships, and hidden patterns. Consequently, addressing such complexities often demands a more sophisticated approach.</p>
<p>Here are some key factors to consider when working with complex datasets.</p>
<ol>
<li>Complex Data Preprocessing</li>
<li>Advanced Data Encoding</li>
<li>Understanding Data Correlation</li>
<li>Multiple Neural Network Layers</li>
<li>Feature Engineering</li>
<li>Regularization</li>
</ol>
<p>If you're already familiar with building a basic neural network, I highly recommend delving into these concepts to excel in the world of Machine Learning.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, we embarked on a journey into the fascinating world of machine learning, starting with the basics. </p>
<p>We explored the fundamentals of binary classification—a fundamental machine learning task. From understanding the problem to building a simple model, we've gained insights into the foundational concepts that underpin this powerful field.</p>
<p>So, whether you're just starting or already well along the path, keep exploring, experimenting, and pushing the boundaries of what's possible with machine learning. I'll see you in another exciting article!</p>
<p>If you wish to learn more about artificial intelligence / machine learning / deep learning, subscribe to my article by visiting my <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_binary_classification">site</a>, which has a consolidated list of all my articles. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Linear Regression Model – Machine Learning Example ]]>
                </title>
                <description>
                    <![CDATA[ Ever since the launch of OpenAI's ChatGPT, everyone wants to learn about AI and ML.  Not only that – everyone wants to build and release an AI product on their own to mark their position in the global competition.  And if you already own a SaaS produ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-linear-regression-model-with-an-example/</link>
                <guid isPermaLink="false">66ba1097f602a81788fe2193</guid>
                
                    <category>
                        <![CDATA[ Artificial Intelligence ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Wed, 06 Sep 2023 13:53:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/09/Linear-Regression-with-an-Example---Banner.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Ever since the launch of OpenAI's ChatGPT, everyone wants to learn about AI and ML. </p>
<p>Not only that – everyone wants to build and release an AI product on their own to mark their position in the global competition. </p>
<p>And if you already own a SaaS product, you may want to integrate AI and ML features into it to retain your customers and be competitive in the global market. </p>
<p>In this tutorial, you'll learn how to build a Linear Regression Model. This is one of the first things you'll learn how to do when studying Machine Learning, so it'll help you take your first step into this competitive market. </p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul><li><a href="#prerequisites">Prerequisites</a></li><li><a href="#what-is-linear-regression">What is Linear Regression?</a></li><li><a href="#evaluation-metrics">Evaluation Metrics</a></li><li><a href="#linear-regression-example-car-price-prediction-model">Linear Regression Example – Car Price Prediction Model</a></li><li><a href="#how-to-build-the-model">How to Build the Model</a></li><li><a href="#conclusion">Conclusion</a></li></ul>

<h2 id="heading-prerequisites">Prerequisites</h2>
<ol>
<li>Medium level experience using an IDE (preferably VS Code)</li>
<li>Basic understanding of Python Notebook (.pynb) files</li>
<li>Good understanding of the Python programming language</li>
<li>Basic knowledge of Pandas (to handle dataframes), Numpy, Scikit Learn, and Matplot libraries</li>
<li>Some knowledge of statistics is helpful for analyzing the data</li>
</ol>
<h2 id="heading-what-is-linear-regression">What is Linear Regression?</h2>
<p>Linear Regression is a Supervised Learning method, where the predicted output will be continuous in nature. For example, things like price prediction, marks prediction, and so on. </p>
<p>Linear Regression is a fundamental statistical and machine learning technique used for modeling the relationship between a dependent variable (also known as the target or response variable) and one or more independent variables (predictors or features). </p>
<p>It aims to establish a linear equation that best represents the association between these variables, allowing us to make predictions and draw insights from the data.</p>
<p>The primary goal of linear regression is to find the "best-fit" line (or hyperplane in higher dimensions) that minimizes the difference between the predicted values and the actual observed values. </p>
<p>This best-fit line is defined by a linear equation of the form:</p>
<p>Y = b0 ​+ b1​X1 ​+ b2​X2 ​+...+ bn​Xn​</p>
<p>In this equation:</p>
<ol>
<li>Y represents the dependent variable we want to predict.</li>
<li>X1,X2,...,Xn are the independent variables or features.</li>
<li>b0 is the intercept (the value of Y when all X values are zero).</li>
<li>b1,b2,...,bn are the coefficients that determine the relationship between each independent variable and the dependent variable.</li>
</ol>
<p>Linear regression assumes that there is a linear relationship between the predictors and the target variable.</p>
<p>The goal of the model is to estimate the coefficients (b0,b1,...,bn) that minimize the sum of the squared differences between the predicted values and the actual values in the training data. This process is often referred to as "fitting the model." </p>
<h2 id="heading-evaluation-metrics">Evaluation Metrics</h2>
<p>The evaluation metrics for a Linear Regression model are:</p>
<ol>
<li>Coefficient of Determination or R-Squared (R2)</li>
<li>Root Mean Squared Error (RSME)</li>
</ol>
<p>Let's see what each of these are.</p>
<h3 id="heading-r-squared">R-Squared</h3>
<p>R-Squared describes the amount of variation that is captured by the developed model. It always ranges between 0 and 1. The higher the value of R-squared, the better the model fits with the data. </p>
<h3 id="heading-root-mean-squared-error">Root Mean Squared Error</h3>
<p>RMSE measures the average magnitude of the errors or residuals between the predicted values generated by a model and the actual observed values in a dataset. It always ranges between 0 and positive infinity. Lower RMSE values indicate better predictive performance. </p>
<h2 id="heading-linear-regression-example-car-price-prediction-model">Linear Regression Example – Car Price Prediction Model</h2>
<p>In this example, we'll try to predict the car price by building a Linear Regression model. I found <a target="_blank" href="https://www.kaggle.com/datasets/nehalbirla/vehicle-dataset-from-cardekho">this problem</a> and the dataset in Kaggle. I noticed that there's a <a target="_blank" href="https://www.kaggle.com/code/farzadnekouei/polynomial-regression-regularization-assumptions/notebook">submission</a> for this problem, which was perfect. In fact I built my solution by taking a part of that solution. </p>
<p>Let's dive into the problem. </p>
<p>We're given a dataset of used cars, which contains the name of the car, year, selling price, present price, number of kilometers it has driven, type of fuel, type of the seller, transmission, and if the seller is the owner. Our goal is to predict the selling price of the car.</p>
<p>Let's explore the solution. </p>
<h3 id="heading-import-the-required-packages">Import the required packages:</h3>
<p>You'll need various packages to work through this problem. Here's how you can import them all:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np
<span class="hljs-keyword">import</span> pandas <span class="hljs-keyword">as</span> pd
<span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt
<span class="hljs-keyword">import</span> seaborn <span class="hljs-keyword">as</span> sns
<span class="hljs-keyword">from</span> sklearn.model_selection <span class="hljs-keyword">import</span> train_test_split
<span class="hljs-keyword">from</span> sklearn.preprocessing <span class="hljs-keyword">import</span> StandardScaler
<span class="hljs-keyword">from</span> sklearn.linear_model <span class="hljs-keyword">import</span> LinearRegression
<span class="hljs-keyword">from</span> sklearn <span class="hljs-keyword">import</span> metrics
<span class="hljs-keyword">from</span> sklearn.model_selection <span class="hljs-keyword">import</span> KFold
<span class="hljs-keyword">from</span> sklearn.pipeline <span class="hljs-keyword">import</span> make_pipeline
<span class="hljs-keyword">from</span> statsmodels.stats.diagnostic <span class="hljs-keyword">import</span> normal_ad
<span class="hljs-keyword">from</span> statsmodels.stats.outliers_influence <span class="hljs-keyword">import</span> variance_inflation_factor
<span class="hljs-keyword">from</span> statsmodels.stats.stattools <span class="hljs-keyword">import</span> durbin_watson
<span class="hljs-keyword">from</span> scipy <span class="hljs-keyword">import</span> stats
</code></pre>
<h3 id="heading-import-the-dataset">Import the dataset</h3>
<p>You can download the dataset (car data.csv) from <a target="_blank" href="https://www.kaggle.com/datasets/nehalbirla/vehicle-dataset-from-cardekho">Kaggle</a> or you can download it from my <a target="_blank" href="https://github.com/5minslearn/Car-Price-Prediction-using-Linear-Regression/blob/master/car%20data.csv">Github repo</a>. </p>
<pre><code class="lang-python">df = pd.read_csv(<span class="hljs-string">'./car data.csv'</span>)
</code></pre>
<h3 id="heading-pre-process-the-dataset">Pre-process the dataset</h3>
<p>The below code shows the columns and their datatype and the number of rows. Our dataset has 9 columns and 301 rows. </p>
<pre><code class="lang-python">df.info()
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-12.png" alt="Image" width="600" height="400" loading="lazy">
<em>Datatype of columns in the dataset</em></p>
<p>The "Car_Name" column describes the car name. This field should be ignored from our dataset. This is because, only the features of the car matters and not its name. </p>
<p>The below code returns the number of unique car names in our dataset. </p>
<pre><code class="lang-python">df[<span class="hljs-string">'Car_Name'</span>].nunique()
</code></pre>
<p>We have 98 unique car names in our dataset. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-28.png" alt="Image" width="600" height="400" loading="lazy">
<em>Number of unique car names</em></p>
<p>Clearly, it does not add any meaning to our dataset, since there are so many categories. Let's drop that column. </p>
<pre><code class="lang-python">df.drop(<span class="hljs-string">'Car_Name'</span>, axis=<span class="hljs-number">1</span>, inplace=<span class="hljs-literal">True</span>)
</code></pre>
<p>The dataset has the column named "Year". Ideally, we need the age of car over the year it was bought / sold. So, let's convert that to "Age" and remove the "Year" column. </p>
<pre><code class="lang-python">df.insert(<span class="hljs-number">0</span>, <span class="hljs-string">"Age"</span>, df[<span class="hljs-string">"Year"</span>].max()+<span class="hljs-number">1</span>-df[<span class="hljs-string">"Year"</span>] )
df.drop(<span class="hljs-string">'Year'</span>, axis=<span class="hljs-number">1</span>, inplace=<span class="hljs-literal">True</span>)
</code></pre>
<p>"Age" is calculated by finding the difference between the maximum year available in our dataset and the year of that particular car. This is because, our calculations will be specific to that particular time period and to this dataset. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-27.png" alt="Image" width="600" height="400" loading="lazy">
<em>Visualize the data in the dataset</em></p>
<h3 id="heading-how-to-find-outliers">How to find outliers</h3>
<p>An outlier is a data point that differs significantly from other observations. They can cause the performance of the model to drop. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-26.png" alt="Image" width="600" height="400" loading="lazy">
<em>How to determine Outliers?</em></p>
<p>Categorical columns will have the datatype as "object". Let's group the numerical columns and categorical columns in a NumPy array. The first 5 elements in the array will be numerical columns and the rest 3 will be categorical columns. </p>
<p>We can plot the data in the columns using the <code>seaborn</code> library. Categorical columns will contain multiple bars, whereas numerical columns will contain single bars. </p>
<p>Let's try to find the outliers in our dataset using the following code:</p>
<pre><code class="lang-python">sns.set_style(<span class="hljs-string">'darkgrid'</span>)
colors = [<span class="hljs-string">'#0055ff'</span>, <span class="hljs-string">'#ff7000'</span>, <span class="hljs-string">'#23bf00'</span>]
CustomPalette = sns.set_palette(sns.color_palette(colors))

OrderedCols = 
np.concatenate([df.select_dtypes(exclude=<span class="hljs-string">'object'</span>).columns.values,  df.select_dtypes(include=<span class="hljs-string">'object'</span>).columns.values])

fig, ax = plt.subplots(<span class="hljs-number">2</span>, <span class="hljs-number">4</span>, figsize=(<span class="hljs-number">15</span>,<span class="hljs-number">7</span>),dpi=<span class="hljs-number">100</span>)

<span class="hljs-keyword">for</span> i,col <span class="hljs-keyword">in</span> enumerate(OrderedCols):
    x = i//<span class="hljs-number">4</span>
    y = i%<span class="hljs-number">4</span>
    <span class="hljs-keyword">if</span> i&lt;<span class="hljs-number">5</span>:
        sns.boxplot(data=df, y=col, ax=ax[x,y])
        ax[x,y].yaxis.label.set_size(<span class="hljs-number">15</span>)
    <span class="hljs-keyword">else</span>:
        sns.boxplot(data=df, x=col, y=<span class="hljs-string">'Selling_Price'</span>, ax=ax[x,y])
        ax[x,y].xaxis.label.set_size(<span class="hljs-number">15</span>)
        ax[x,y].yaxis.label.set_size(<span class="hljs-number">15</span>)

plt.tight_layout()    
plt.show()
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-25.png" alt="Image" width="600" height="400" loading="lazy">
<em>Outliers determination in the dataset</em></p>
<p>Let's try to find the outliers using the <strong>InterQuartile Range rule</strong>. </p>
<p>This is based on the concept of quartiles, which divide a dataset into four equal parts. The IQR (InterQuartile Range rule) rule specifically focuses on the range of values within the middle 50% of the data and uses this range to identify potential outliers.</p>
<p>We have to find the minimum and maximum quantile values for each unique value in the categorical columns and filter the outlier samples which do not fit into the 25th and 75th percentile of our target column (Selling Price). </p>
<p>On the other hand, the outliers in numerical columns can be filtered by the 25th and 75th percentiles of the same column. We don't need to filter out with respect to the target column. </p>
<pre><code class="lang-python">outliers_indexes = []
target = <span class="hljs-string">'Selling_Price'</span>

<span class="hljs-keyword">for</span> col <span class="hljs-keyword">in</span> df.select_dtypes(include=<span class="hljs-string">'object'</span>).columns:
    <span class="hljs-keyword">for</span> cat <span class="hljs-keyword">in</span> df[col].unique():
        df1 = df[df[col] == cat]
        q1 = df1[target].quantile(<span class="hljs-number">0.25</span>)
        q3 = df1[target].quantile(<span class="hljs-number">0.75</span>)
        iqr = q3-q1
        maximum = q3 + (<span class="hljs-number">1.5</span> * iqr)
        minimum = q1 - (<span class="hljs-number">1.5</span> * iqr)
        outlier_samples = df1[(df1[target] &lt; minimum) | (df1[target] &gt; maximum)]
        outliers_indexes.extend(outlier_samples.index.tolist())


<span class="hljs-keyword">for</span> col <span class="hljs-keyword">in</span> df.select_dtypes(exclude=<span class="hljs-string">'object'</span>).columns:
    q1 = df[col].quantile(<span class="hljs-number">0.25</span>)
    q3 = df[col].quantile(<span class="hljs-number">0.75</span>)
    iqr = q3-q1
    maximum = q3 + (<span class="hljs-number">1.5</span> * iqr)
    minimum = q1 - (<span class="hljs-number">1.5</span> * iqr)
    outlier_samples = df[(df[col] &lt; minimum) | (df[col] &gt; maximum)]
    outliers_indexes.extend(outlier_samples.index.tolist())

outliers_indexes = list(set(outliers_indexes))
print(<span class="hljs-string">'{} outliers were identified, whose indices are:\n\n{}'</span>.format(len(outliers_indexes), outliers_indexes))
</code></pre>
<p>By running the above code, we found that there are 38 outliers in our dataset. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-24.png" alt="Image" width="600" height="400" loading="lazy">
<em>List of initial outliers indices</em></p>
<p>But keep in mind that it's not always the right decision to remove the outliers. They can be legitimate observations and it’s important to investigate the nature of the outlier before deciding whether to drop it or not. </p>
<p>We can delete outliers in two cases: </p>
<ol>
<li>Outlier is due to incorrectly entered or measured data</li>
<li>Outlier creates a significant association</li>
</ol>
<p>Let's dig even more and find the perfect outliers. </p>
<p>To do that, let's assume that if the selling price is more than 33 Lakhs or if the car has been driven more than 400,000 Kilometers, those are outliers. We'll mark them in green. Save all the indices in the <code>removing_indices</code> variable. Plot them in the scatterplot format using <code>seaborn</code> library, comparing each column against our target column. </p>
<pre><code class="lang-python"><span class="hljs-comment"># Outliers Labeling</span>
df1 = df.copy()
df1[<span class="hljs-string">'label'</span>] = <span class="hljs-string">'Normal'</span>
df1.loc[outliers_indexes,<span class="hljs-string">'label'</span>] = <span class="hljs-string">'Outlier'</span>

<span class="hljs-comment"># Removing Outliers</span>
removing_indexes = []
removing_indexes.extend(df1[df1[target]&gt;<span class="hljs-number">33</span>].index)
removing_indexes.extend(df1[df1[<span class="hljs-string">'Kms_Driven'</span>]&gt;<span class="hljs-number">400000</span>].index)
df1.loc[removing_indexes,<span class="hljs-string">'label'</span>] = <span class="hljs-string">'Removing'</span>

<span class="hljs-comment"># Plot</span>
target = <span class="hljs-string">'Selling_Price'</span>
features = df.columns.drop(target)
colors = [<span class="hljs-string">'#0055ff'</span>,<span class="hljs-string">'#ff7000'</span>,<span class="hljs-string">'#23bf00'</span>]
CustomPalette = sns.set_palette(sns.color_palette(colors))
fig, ax = plt.subplots(nrows=<span class="hljs-number">3</span> ,ncols=<span class="hljs-number">3</span>, figsize=(<span class="hljs-number">15</span>,<span class="hljs-number">12</span>), dpi=<span class="hljs-number">200</span>)

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(len(features)):
    x=i//<span class="hljs-number">3</span>
    y=i%<span class="hljs-number">3</span>
    sns.scatterplot(data=df1, x=features[i], y=target, hue=<span class="hljs-string">'label'</span>, ax=ax[x,y])
    ax[x,y].set_title(<span class="hljs-string">'{} vs. {}'</span>.format(target, features[i]), size = <span class="hljs-number">15</span>)
    ax[x,y].set_xlabel(features[i], size = <span class="hljs-number">12</span>)
    ax[x,y].set_ylabel(target, size = <span class="hljs-number">12</span>)
    ax[x,y].grid()

ax[<span class="hljs-number">2</span>, <span class="hljs-number">1</span>].axis(<span class="hljs-string">'off'</span>)
ax[<span class="hljs-number">2</span>, <span class="hljs-number">2</span>].axis(<span class="hljs-string">'off'</span>)
plt.tight_layout()
plt.show()
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-23.png" alt="Image" width="600" height="400" loading="lazy">
<em>Outliers marked in Green color</em></p>
<p>Let's see the perfect outliers:</p>
<pre><code class="lang-python">removing_indexes = list(set(removing_indexes))
removing_indexes
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-22.png" alt="Image" width="600" height="400" loading="lazy">
<em>List of original outliers indices</em></p>
<p>We got 2. We have to remove them. But before that, we have to check if there's any null data in our dataset. </p>
<pre><code class="lang-python">df.isnull().sum()
</code></pre>
<p>There are no null values in our dataset. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-21.png" alt="Image" width="600" height="400" loading="lazy">
<em>No null values in the dataset</em></p>
<p>Let's remove the identified outliers and reset the index of the dataframe. </p>
<pre><code class="lang-python">df1 = df.copy()
df1.drop(removing_indexes, inplace=<span class="hljs-literal">True</span>)
df1.reset_index(drop=<span class="hljs-literal">True</span>, inplace=<span class="hljs-literal">True</span>)
</code></pre>
<h3 id="heading-analyze-the-dataset">Analyze the Dataset</h3>
<p>Let's analyze the data to see how much each field/category is correlated with the selling price of the car. We need to do some analysis on our dataset to be able to come to some conclusions about it. </p>
<p>To do that, we have to identify the numerical and categorical fields in our dataset, as the way to plot this differs for each type.</p>
<pre><code class="lang-python">NumCols = [<span class="hljs-string">'Age'</span>, <span class="hljs-string">'Selling_Price'</span>, <span class="hljs-string">'Present_Price'</span>, <span class="hljs-string">'Kms_Driven'</span>, <span class="hljs-string">'Owner'</span>]
CatCols = [<span class="hljs-string">'Fuel_Type'</span>, <span class="hljs-string">'Seller_Type'</span>, <span class="hljs-string">'Transmission'</span>]
</code></pre>
<h3 id="heading-bivariate-analysis">Bivariate Analysis</h3>
<p>If you're not familiar what bivariate analysis is, <a target="_blank" href="https://en.wikipedia.org/wiki/Bivariate_analysis">here's a basic definition</a>: </p>
<blockquote>
<p>Bivariate analysis is one of the simplest forms of quantitative analysis. It involves the analysis of two variables, for the purpose of determining the empirical relationship between them. Bivariate analysis can be helpful in testing simple hypotheses of association.</p>
</blockquote>
<p>Let's compare the Selling Price with the other columns using Bivariate Analysis and try to derive some conclusions out of that data. </p>
<h3 id="heading-selling-price-vs-numerical-features-bivariate-analysis">Selling Price vs Numerical Features Bivariate Analysis</h3>
<p>Let's compare the numerical features with the Selling Price using Bivariate analysis. The Numerical columns will be plotted in a scatter graph. </p>
<pre><code class="lang-python">fig, ax = plt.subplots(nrows=<span class="hljs-number">2</span> ,ncols=<span class="hljs-number">2</span>, figsize=(<span class="hljs-number">10</span>,<span class="hljs-number">10</span>), dpi=<span class="hljs-number">90</span>)
num_features = [<span class="hljs-string">'Present_Price'</span>, <span class="hljs-string">'Kms_Driven'</span>, <span class="hljs-string">'Age'</span>, <span class="hljs-string">'Owner'</span>]
target = <span class="hljs-string">'Selling_Price'</span>
c = <span class="hljs-string">'#0055ff'</span>

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(len(num_features)):
    row = i//<span class="hljs-number">2</span>
    col = i%<span class="hljs-number">2</span>
    ax[row,col].scatter(df1[num_features[i]], df1[target], color=c, edgecolors=<span class="hljs-string">'w'</span>, linewidths=<span class="hljs-number">0.25</span>)
    ax[row,col].set_title(<span class="hljs-string">'{} vs. {}'</span>.format(target, num_features[i]), size = <span class="hljs-number">12</span>)
    ax[row,col].set_xlabel(num_features[i], size = <span class="hljs-number">12</span>)
    ax[row,col].set_ylabel(target, size = <span class="hljs-number">12</span>)
    ax[row,col].grid()

plt.suptitle(<span class="hljs-string">'Selling Price vs. Numerical Features'</span>, size = <span class="hljs-number">20</span>)
plt.tight_layout()
plt.show()
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-20.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selling Price vs Numerical Features Bivariate Analysis</em></p>
<h3 id="heading-selling-price-vs-categorical-features-bivariate-analysis">Selling Price vs Categorical Features Bivariate Analysis</h3>
<p>Let's compare the categorical features with the Selling Price using Bivariate analysis. The Categorical columns will be plotted in a stripplot graph. This gives the comparison among multiple values in a category. </p>
<pre><code class="lang-python">fig, axes = plt.subplots(nrows=<span class="hljs-number">1</span> ,ncols=<span class="hljs-number">3</span>, figsize=(<span class="hljs-number">12</span>,<span class="hljs-number">5</span>), dpi=<span class="hljs-number">100</span>)
cat_features = [<span class="hljs-string">'Fuel_Type'</span>, <span class="hljs-string">'Seller_Type'</span>, <span class="hljs-string">'Transmission'</span>]
target = <span class="hljs-string">'Selling_Price'</span>
c = <span class="hljs-string">'#0055ff'</span>

<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(len(cat_features)):
    sns.stripplot(ax=axes[i], x=cat_features[i], y=target, data=df1, size=<span class="hljs-number">6</span>, color=c)
    axes[i].set_title(<span class="hljs-string">'{} vs. {}'</span>.format(target, cat_features[i]), size = <span class="hljs-number">13</span>)
    axes[i].set_xlabel(cat_features[i], size = <span class="hljs-number">12</span>)
    axes[i].set_ylabel(target, size = <span class="hljs-number">12</span>)
    axes[i].grid()

plt.suptitle(<span class="hljs-string">'Selling Price vs. Categorical Features'</span>, size = <span class="hljs-number">20</span>)
plt.tight_layout()
plt.show()
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-19.png" alt="Image" width="600" height="400" loading="lazy">
<em>Selling Price vs Categorical Features Bivariate Analysis</em></p>
<p>Here are the conclusions we can make from our data analysis:</p>
<ol>
<li>As Present Price increases, Selling Price increases as well. They're directly proportional.</li>
<li>Selling Price is inversely proportional to Kilometers Driven.</li>
<li>Selling Price is inversely proportional to the car's age.</li>
<li>As the number of previous car owners increases, its Selling Price decreases. So Selling Price is inversely proportional to Owner.</li>
<li>Diesel Cars &gt; CNG Cars &gt; Petrol Cars in terms of Selling Price.</li>
<li>The Selling Price of cars sold by individuals is lower than the price of cars sold by dealers.</li>
<li>Automatic cars are more expensive than manual cars.</li>
</ol>
<h3 id="heading-categorical-variables-encoding">Categorical Variables Encoding</h3>
<p>We can't use the Categorical fields as they are. They have to be converted to numbers because machines can only understand numbers. </p>
<p>For an example, let's take the Fuel column. As per our dataset, we have cars running on two types of fuel. They are Petrol and Diesel. The categorical variable encoding will split the fuel column into 2 columns (Fuel_Type_Petrol and Fuel_Type_Diesel). </p>
<p>Let's assume a car runs on Petrol. For this car, the data will be converted as Fuel_Type_Petrol column set to 1 (True), and Fuel_Type_Diesel column set to 0 (False). Computers can understand 1 and 0 rather than "Petrol" and "Diesel". </p>
<p>To do that, we'll perform one-hot encoding for the categorical columns. Pandas offers the <code>get_dummies</code> method to encode the columns. </p>
<pre><code class="lang-python">CatCols = [<span class="hljs-string">'Fuel_Type'</span>, <span class="hljs-string">'Seller_Type'</span>, <span class="hljs-string">'Transmission'</span>]

df1 = pd.get_dummies(df1, columns=CatCols, drop_first=<span class="hljs-literal">True</span>)
df1.head(<span class="hljs-number">5</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-18.png" alt="Image" width="600" height="400" loading="lazy">
<em>Categorical Variables Encoding</em></p>
<p>Assume <code>True</code> and <code>False</code> are <code>0</code> and <code>1</code>, respectively. </p>
<h3 id="heading-correlation-analysis">Correlation Analysis</h3>
<p>A correlation matrix is a matrix that summarizes the strength and direction of the linear relationships between pairs of variables in a dataset. It is a crucial tool in statistics and data analysis, used to examine the patterns of association between variables and understand how they may be related. </p>
<p>The correlation is directly proportional if the values are positive, and inversely proportional if the values are negative. </p>
<p>Here's the code to find the correlation matrix with relation to Selling Price. </p>
<pre><code class="lang-python">target = <span class="hljs-string">'Selling_Price'</span>
cmap = sns.diverging_palette(<span class="hljs-number">125</span>, <span class="hljs-number">28</span>, s=<span class="hljs-number">100</span>, l=<span class="hljs-number">65</span>, sep=<span class="hljs-number">50</span>, as_cmap=<span class="hljs-literal">True</span>)
fig, ax = plt.subplots(figsize=(<span class="hljs-number">9</span>, <span class="hljs-number">8</span>), dpi=<span class="hljs-number">80</span>)
ax = sns.heatmap(pd.concat([df1.drop(target,axis=<span class="hljs-number">1</span>), df1[target]],axis=<span class="hljs-number">1</span>).corr(), annot=<span class="hljs-literal">True</span>, cmap=cmap)
plt.show()
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-17.png" alt="Image" width="600" height="400" loading="lazy">
<em>Correlation Matrix</em></p>
<p>From the above matrix, we can infer that the target variable "Selling Price" is highly correlated with Present Price, Seller Type, and Fuel Type. </p>
<h2 id="heading-how-to-build-the-model">How to Build the Model</h2>
<p>We have come to the final stage. Let's train and test our model. </p>
<p>Let's remove the "Selling_Price" from input and set it to output. This means that it has to be predicted. </p>
<pre><code class="lang-python">X = df1.drop(<span class="hljs-string">'Selling_Price'</span>, axis=<span class="hljs-number">1</span>)
y = df1[<span class="hljs-string">'Selling_Price'</span>]
</code></pre>
<p>Let's split our dataset by taking 70% of data for training and 30% of data for testing. </p>
<pre><code class="lang-python">X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=<span class="hljs-number">0.3</span>, random_state=<span class="hljs-number">0</span>)
</code></pre>
<p>Let's make a backup of our test data. We need this for the final comparison. </p>
<pre><code class="lang-python">y_test_actual = y_test
</code></pre>
<h3 id="heading-normalize-the-dataset">Normalize the dataset</h3>
<p>The <code>StandardScaler</code> is a preprocessing technique commonly used in machine learning and data analysis to standardize or normalize the features (variables) of a dataset. Its primary purpose is to transform the data such that each feature has a mean (average) of 0 and a standard deviation of 1. </p>
<p>Let's normalize our dataset using <code>StandardScaler</code>. </p>
<pre><code class="lang-python">scaler = StandardScaler()
scaler.fit(X_train)
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)
</code></pre>
<p>It is very important that <code>StandardScaler</code> transformation should only be gotten from the training set, otherwise it will lead to data leakage. </p>
<h3 id="heading-train-the-model">Train the model</h3>
<pre><code class="lang-python">linear_reg = LinearRegression()
linear_reg.fit(X_train_scaled, y_train)
</code></pre>
<p>Let's find the intercept and co-efficient for each column in our training dataset. </p>
<pre><code class="lang-python">pd.DataFrame(data = np.append(linear_reg.intercept_ , linear_reg.coef_), index = [<span class="hljs-string">'Intercept'</span>]+[col+<span class="hljs-string">" Coef."</span> <span class="hljs-keyword">for</span> col <span class="hljs-keyword">in</span> X.columns], columns=[<span class="hljs-string">'Value'</span>]).sort_values(<span class="hljs-string">'Value'</span>, ascending=<span class="hljs-literal">False</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-16.png" alt="Image" width="600" height="400" loading="lazy">
<em>Slope and Intercept values</em></p>
<h3 id="heading-how-to-evaluate-the-model">How to evaluate the model</h3>
<p>Scikit Learn provides a metrics feature which helps us to measure the metrics of our model. We can use that to determine metrics include Mean Squared Error, Mean Absolute Error, Root Mean Squared Error, and R2-Score. </p>
<p>Now it's time to evaluate the model:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">model_evaluation</span>(<span class="hljs-params">model, X_test, y_test, model_name</span>):</span>
    y_pred = model.predict(X_test)

    MAE = metrics.mean_absolute_error(y_test, y_pred)
    MSE = metrics.mean_squared_error(y_test, y_pred)
    RMSE = np.sqrt(MSE)
    R2_Score = metrics.r2_score(y_test, y_pred)

    <span class="hljs-keyword">return</span> pd.DataFrame([MAE, MSE, RMSE, R2_Score], index=[<span class="hljs-string">'MAE'</span>, <span class="hljs-string">'MSE'</span>, <span class="hljs-string">'RMSE'</span> ,<span class="hljs-string">'R2-Score'</span>], columns=[model_name])

model_evaluation(linear_reg, X_test_scaled, y_test, <span class="hljs-string">'Linear Reg.'</span>)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-15.png" alt="Image" width="600" height="400" loading="lazy">
<em>Evaluation of the model</em></p>
<h3 id="heading-evaluate-the-model-using-k-fold-cross-validation">Evaluate the model using K-fold Cross-Validation</h3>
<p>In k-fold cross-validation, the dataset is divided into k roughly equal-sized subsets or "folds." The model is trained and evaluated k times, each time using a different fold as the validation set and the remaining folds as the training set. </p>
<p>The results (for example accuracy, error) of these k runs are then averaged to obtain a more robust estimate of the model's performance. </p>
<p>The advantage is that each data point is used for both training and validation, reducing the risk of bias in the evaluation. </p>
<pre><code class="lang-python">linear_reg_cv = LinearRegression()
scaler = StandardScaler()
pipeline = make_pipeline(StandardScaler(),  LinearRegression())

kf = KFold(n_splits=<span class="hljs-number">6</span>, shuffle=<span class="hljs-literal">True</span>, random_state=<span class="hljs-number">0</span>) 
scoring = [<span class="hljs-string">'neg_mean_absolute_error'</span>, <span class="hljs-string">'neg_mean_squared_error'</span>, <span class="hljs-string">'neg_root_mean_squared_error'</span>, <span class="hljs-string">'r2'</span>]
result = cross_validate(pipeline, X, y, cv=kf, return_train_score=<span class="hljs-literal">True</span>, scoring=scoring)

MAE_mean = (-result[<span class="hljs-string">'test_neg_mean_absolute_error'</span>]).mean()
MAE_std = (-result[<span class="hljs-string">'test_neg_mean_absolute_error'</span>]).std()
MSE_mean = (-result[<span class="hljs-string">'test_neg_mean_squared_error'</span>]).mean()
MSE_std = (-result[<span class="hljs-string">'test_neg_mean_squared_error'</span>]).std()
RMSE_mean = (-result[<span class="hljs-string">'test_neg_root_mean_squared_error'</span>]).mean()
RMSE_std = (-result[<span class="hljs-string">'test_neg_root_mean_squared_error'</span>]).std()
R2_Score_mean = result[<span class="hljs-string">'test_r2'</span>].mean()
R2_Score_std = result[<span class="hljs-string">'test_r2'</span>].std()

pd.DataFrame({<span class="hljs-string">'Mean'</span>: [MAE_mean,MSE_mean,RMSE_mean,R2_Score_mean], <span class="hljs-string">'Std'</span>: [MAE_std,MSE_std,RMSE_std,R2_Score_std]},
             index=[<span class="hljs-string">'MAE'</span>, <span class="hljs-string">'MSE'</span>, <span class="hljs-string">'RMSE'</span> ,<span class="hljs-string">'R2-Score'</span>])
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-14.png" alt="Image" width="600" height="400" loading="lazy">
<em>Model Evaluation using Cross-Validation</em></p>
<h3 id="heading-results-visualization">Results Visualization</h3>
<p>Let's create a dataframe with the actual and predicted values. </p>
<pre><code class="lang-python">y_test_pred = linear_reg.predict(X_test_scaled)
df_comp = pd.DataFrame({<span class="hljs-string">'Actual'</span>:y_test_actual, <span class="hljs-string">'Predicted'</span>:y_test_pred})
</code></pre>
<p>Let's compare the actual and predicted target values for the test data with the help of a bar plot. </p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">compare_plot</span>(<span class="hljs-params">df_comp</span>):</span>
    df_comp.reset_index(inplace=<span class="hljs-literal">True</span>)
    df_comp.plot(y=[<span class="hljs-string">'Actual'</span>,<span class="hljs-string">'Predicted'</span>], kind=<span class="hljs-string">'bar'</span>, figsize=(<span class="hljs-number">20</span>,<span class="hljs-number">7</span>), width=<span class="hljs-number">0.8</span>)
    plt.title(<span class="hljs-string">'Predicted vs. Actual Target Values for Test Data'</span>, fontsize=<span class="hljs-number">20</span>)
    plt.ylabel(<span class="hljs-string">'Selling_Price'</span>, fontsize=<span class="hljs-number">15</span>)
    plt.show()

compare_plot(df_comp)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/09/image-13.png" alt="Image" width="600" height="400" loading="lazy">
<em>Comparison between actual and predicted values</em></p>
<p>In the above graph, the blue lines indicates the actual price and orange lines indicate the predicted price of the cars. You can see that some predicted values are negative. But in most of our cases, our model has predicted it pretty well. </p>
<p>This is not the perfect model. But if you want to fine tune it to make better predictions, let me know via my <a target="_blank" href="mailto:arun@gogosoon.com">email</a>. I'll write a tutorial about that if I receive more requests. </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, you learned about Linear Regression with a practical example. I hope it helps you to make progress in your ML journey. You can access the above dataset and the code for it in from this <a target="_blank" href="https://github.com/5minslearn/Car-Price-Prediction-using-Linear-Regression">Github repo</a>. </p>
<p>Hope you enjoyed reading this article. If you wish to learn more about artificial intelligence / machine learning / deep learning, subscribe to my article by visiting my <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_linear_regression_model">site</a> which has a consolidated list of all my blogs. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build and Release a Flutter App in Google Play ]]>
                </title>
                <description>
                    <![CDATA[ In the rapidly evolving world of mobile app development, Flutter has gained immense popularity for its ability to create stunning and high-performance apps across multiple platforms.  Flutter's framework allows developers to build beautiful user inte... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-and-release-flutter-app-in-google-play/</link>
                <guid isPermaLink="false">66ba109a9065919bb4e84cac</guid>
                
                    <category>
                        <![CDATA[ android app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Flutter ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Wed, 30 Aug 2023 14:23:42 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/08/Build-and-Release-the-Flutter-App-in-Google-Play.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In the rapidly evolving world of mobile app development, Flutter has gained immense popularity for its ability to create stunning and high-performance apps across multiple platforms. </p>
<p>Flutter's framework allows developers to build beautiful user interfaces, deliver native performance, and streamline development. </p>
<p>In this tutorial, I will walk you through building and releasing a Flutter app on the Android platform, from setting up your development environment to distributing your app on the Google Play Store.</p>
<h2 id="heading-prerequisites">Prerequisites:</h2>
<ol>
<li><strong>Install Flutter and Dart:</strong> Make sure you have Flutter and Dart installed on your machine. Follow the <a target="_blank" href="https://docs.flutter.dev/get-started/install">official Flutter installation guide</a> for your platform.</li>
<li><strong>Android Studio:</strong> Download and install Android Studio, which comes with useful tools for Android app development.</li>
<li><strong>Google Play Developer Account:</strong> Create an account on the Google Play Console to publish your app on the Play Store.</li>
</ol>
<h2 id="heading-how-to-develop-your-app">How to Develop your app</h2>
<p>In this guide, I'll be building and releasing a <a target="_blank" href="https://www.freecodecamp.org/news/learn-state-management-in-flutter/">simple todo app</a> I built in one of my earlier blogs.</p>
<p>However, you can follow along with this tutorial and release your own app based on what you build. </p>
<p>As a learner, and if you want to experience the app releasing process, this will be good practice for you.</p>
<p>Run the following command to clone my repo:</p>
<pre><code>git clone https:<span class="hljs-comment">//github.com/5minslearn/Flutter-Todo-App</span>
</code></pre><p>Before proceeding with the app-building process, it's crucial to ensure that our app runs smoothly on a simulator or a physical device, without encountering any errors. </p>
<p>Open the repo in VS Code and press F5 to run the app on your phone / emulator. </p>
<h2 id="heading-how-to-customize-the-default-launcher-icon-in-flutter">How to Customize the Default Launcher Icon in Flutter</h2>
<p>When a new Flutter app is created, it has a default launcher icon. </p>
<p>To customize this icon we need to follow the steps below: </p>
<ol>
<li>You can create your own icon by following this <a target="_blank" href="https://m3.material.io/styles/icons">guideline</a>.</li>
<li>In the <code>[project]/android/app/src/main/res/</code> directory, place your icon files in folders. The default <code>mipmap-</code> folders demonstrate the correct naming convention.</li>
<li>In <code>AndroidManifest.xml, update the application tags</code> <code>android:icon</code> attribute to reference icons from the previous step (for example, <code>&lt;application android:icon="@mipmap/custom_icon" ...</code>).</li>
</ol>
<p>I created an icon named <code>custom_icon.xml</code> with multiple resolutions (<code>mdpi</code> , <code>hdpi</code>, <code>xhdpi</code>, <code>xxhdpi</code>, <code>xxxhdpi</code>):</p>
<pre><code><span class="hljs-number">48</span> × <span class="hljs-number">48</span> (mdpi)
<span class="hljs-number">72</span> × <span class="hljs-number">72</span> (hdpi)
<span class="hljs-number">96</span> × <span class="hljs-number">96</span> (xhdpi)
<span class="hljs-number">144</span> × <span class="hljs-number">144</span> (xxhdpi)
<span class="hljs-number">192</span> × <span class="hljs-number">192</span> (xxxhdpi)
</code></pre><p>I also placed each icon in the respective <code>mipmap-</code> folder. And finally, I mentioned them in the <code>AndroidManifest.xml</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/image-169.png" alt="Image" width="600" height="400" loading="lazy">
_Updating custom<em>icon in AndroidManifest.xml</em></p>
<pre><code>&lt;manifest xmlns:android=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span> package=<span class="hljs-string">"com.example.todo"</span> &gt;
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">application</span>
        <span class="hljs-attr">android:label</span>=<span class="hljs-string">"todo"</span>
        <span class="hljs-attr">android:name</span>=<span class="hljs-string">"${applicationName}"</span>
        <span class="hljs-attr">android:icon</span>=<span class="hljs-string">"@mipmap/custom_icon"</span>&gt;</span>
        .....
        .....
    <span class="hljs-tag">&lt;/<span class="hljs-name">application</span>&gt;</span></span>
&lt;/manifest&gt;
</code></pre><p>I am utilizing <code>ColorControlNormal</code> in my custom icon file (<code>custom_icon.xml</code>):</p>
<pre><code>&lt;vector xmlns:android=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span>
    <span class="hljs-attr">android</span>:width=<span class="hljs-string">"48dp"</span>
    <span class="hljs-attr">android</span>:height=<span class="hljs-string">"48dp"</span>
    <span class="hljs-attr">android</span>:viewportWidth=<span class="hljs-string">"960"</span>
    <span class="hljs-attr">android</span>:viewportHeight=<span class="hljs-string">"960"</span>
    <span class="hljs-attr">android</span>:tint=<span class="hljs-string">"?attr/colorControlNormal"</span>&gt;
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">path</span>
      <span class="hljs-attr">android:fillColor</span>=<span class="hljs-string">"@android:color/white"</span>
      <span class="hljs-attr">android:pathData</span>=<span class="hljs-string">"M380,....,453.5Q592,463 613,483Z"</span>/&gt;</span></span>
&lt;/vector&gt;
</code></pre><p><strong><code>colorControlNormal</code></strong> is a value that refers to a color attribute that is resolved at runtime, allowing the drawable to match the color theme of the app.</p>
<p>As I'm using an older API version, this function isn't accessible within the older API. </p>
<p>As a solution, I've included the <code>appcompat</code> library in my <code>app/build.gradle</code> file: </p>
<pre><code>...
dependencies {
    ....
    implementation <span class="hljs-string">'androidx.appcompat:appcompat:1.3.1'</span>
    ....
}
....
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/08/image-146.png" alt="Image" width="600" height="400" loading="lazy">
<em>Implement appcombat library in <code>build.gradle</code></em></p>
<p>That's it. Our configurations are done. Let's try to run the app and look at the icon in the device.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/image-168.png" alt="Image" width="600" height="400" loading="lazy">
<em>App Icon Changed for Todo App</em></p>
<p>The one with the rabbit's face is the one I created. It has been successfully applied to our app. </p>
<p>Without any delay, let's get into building our Android application.</p>
<h2 id="heading-what-is-a-keystore-and-why-do-you-need-it-in-flutter">What is a Keystore and Why DO You Need it in Flutter?</h2>
<p>A keystore in Flutter, specifically for Android, is a secure container used to store cryptographic keys and certificates. </p>
<p>It's important to maintain the security of your app, especially when dealing with sensitive information such as API keys, authentication tokens, and encryption keys. </p>
<p>The keystore ensures that these sensitive assets are stored in a way that makes them difficult to extract from the device.</p>
<h3 id="heading-security">Security</h3>
<p>Storing sensitive information in a Keystore ensures that it is protected from unauthorized access, even if the device is compromised.</p>
<h3 id="heading-compliance">Compliance</h3>
<p>Many regulations require apps to protect sensitive data. A keystore helps you meet compliance standards.</p>
<h3 id="heading-encryption">Encryption</h3>
<p>If your app uses encryption, the keystore provides a secure location for storing encryption keys.</p>
<h3 id="heading-credentials">Credentials</h3>
<p>If your app communicates with APIs or services that require credentials, using a keystore can prevent those credentials from being easily extracted.</p>
<h2 id="heading-how-to-create-a-keystore-in-flutter">How to Create a Keystore in Flutter</h2>
<p>To create a Keystore, you typically use the keytool utility that comes with the Java Development Kit (JDK):</p>
<pre><code>keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize <span class="hljs-number">2048</span> -validity <span class="hljs-number">10000</span> -alias my-key
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/08/image-170.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sample output for generate a keystore file</em></p>
<h2 id="heading-how-to-generate-apk-or-aab-in-flutter"><strong>How to Generate APK or AAB in Flutter</strong></h2>
<p>APK (Android Package) and AAB (Android App Bundle) are distribution formats used to package and distribute Android applications. </p>
<p>It is recommended to build an app as AAB over APK due to the following benefits:</p>
<ul>
<li>Smaller downloads and faster installations due to optimized APKs</li>
<li>Improved efficiency in resource usage and reduced storage consumption</li>
<li>Dynamic feature delivery support for delivering features on-demand</li>
<li>Enhanced optimization for specific device configurations</li>
</ul>
<pre><code>flutter build appbundle
or
flutter build apk
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/08/image-171.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sample output to build abb</em></p>
<p>We cannot directly install an Android App Bundle (AAB) file on a mobile device.</p>
<p>An AAB is not an executable package like an APK (Android Package) file that can be directly installed on a device. </p>
<p>Instead, the AAB is a publishing format designed for optimized delivery on the Google Play Store.</p>
<p>When you publish your app on the Google Play Store using an AAB, the Play Store uses it to generate APKs that are tailored to each user's device configuration. </p>
<p>This dynamic generation allows the Play Store to deliver only the necessary resources and code for a specific device, reducing the app's size and improving performance during installation.</p>
<h2 id="heading-how-to-release-a-flutter-app-on-google-play-store">How to Release a Flutter App on Google Play Store</h2>
<p>To release our app on the Google Play Store, we'll require a Google Play developer account. We can create an account by visiting this <a target="_blank" href="https://play.google.com/console">link</a>. </p>
<p>Please be aware that there is a registration fee of at least $25 associated with the process.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/image-150.png" alt="Image" width="600" height="400" loading="lazy">
<em>Google play dashboard to create a new App</em></p>
<p>Click on the Create app button in the <code>All apps</code> section. Enter the app details in the "Create app" form.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/image-149.png" alt="Image" width="600" height="400" loading="lazy">
<em>Creating an app in Google play for release</em></p>
<p>After creating the app, we have to go through multiple tasks to release the application. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/image-151.png" alt="Image" width="600" height="400" loading="lazy">
<em>Steps to testing the app in Goole Play Console</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/image-152.png" alt="Image" width="600" height="400" loading="lazy">
<em>Steps to setting up the app in Goole Play Console</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/image-153.png" alt="Image" width="600" height="400" loading="lazy">
<em>Steps to release the app in Goole Play Console</em></p>
<p>However, all these steps will be self-explanatory. </p>
<p>At each step, you'll be prompted for information about your application, advertisements, privacy policy, and more. </p>
<p>It's important to note that you can proceed to publish only after completing these steps. </p>
<p>Make sure to mention everything clearly. Especially the questions about data collection. Because, at any time if Google found that your prescribed information is wrong, your app will not be published or will be taken out, if it's published. </p>
<p>After completing these steps, we have to send the app for review. Our app will be published once the review is completed from Google Play team. </p>
<p>It's important to note that there's a higher chance of the app getting rejected if it has security or advertising-related issues. </p>
<p>Therefore, make sure to thoroughly review your app to ensure that it doesn't have any potential problems in data collection. This will contribute to a smoother and more successful app release experience.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Throughout this tutorial, we've covered the process of changing the app icon and building a Flutter app for Android. </p>
<p>While this example provides a foundational understanding of Flutter app development, it's important to note that real-world app complexities may require additional custom configurations in Android. </p>
<p>For further insights, I encourage you to explore the official <a target="_blank" href="https://docs.flutter.dev/deployment/android">documentation</a>, which offers comprehensive guidance on more advanced aspects.</p>
<p>I hope this tutorial has provided you with valuable insights in your Flutter journey.</p>
<p>Thank you for investing your time, and best of luck in your app development endeavors! </p>
<p>If you wish to learn more about Flutter, subscribe to my article by visiting my <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_flutter_publish_app">site</a> which has a consolidated list of all my blogs.</p>
<p>Cheers! </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Add Two Numbers – The Machine Learning Way ]]>
                </title>
                <description>
                    <![CDATA[ In the world of machine learning, we often encounter complex problems, from image recognition to natural language processing.  But let's take a step back and explore something more elementary yet equally intriguing: addition! Yes, you read that right... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-add-two-numbers-using-machine-learning/</link>
                <guid isPermaLink="false">66ba10b179b7f411df58deaf</guid>
                
                    <category>
                        <![CDATA[ Deep Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Tue, 01 Aug 2023 19:51:50 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/Sum-of-2-numbers-using-ML---Banner.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In the world of machine learning, we often encounter complex problems, from image recognition to natural language processing. </p>
<p>But let's take a step back and explore something more elementary yet equally intriguing: addition! Yes, you read that right – addition. </p>
<p>In this tutorial, we'll build a neural network that can learn the art of adding two numbers together.</p>
<p>A quick note before we get into this: I don't recommend using machine learning to find the sum of two numbers in practice. I tried this out of curiosity when I started learning machine learning. And I just wished to share this with you all to make learning fun. </p>
<p>You can use this tutorial as a sort of starter guide in your machine learning journey. Sometimes its hard to find good, clean datasets as a beginner machine learning engineer. This makes it harder to work on and learn about machine learning problems if you don't have a solid dataset.</p>
<p>But don't worry – in this tutorial, we'll be creating our own dataset (pairs of numbers to add) and cleaning the data. So it'll give you a good dataset you can use in your own problems and with your own models. </p>
<p>Alright, before diving in, let's brush up on some machine learning and deep learning basics.</p>
<h2 id="heading-deep-learning-basics">Deep Learning Basics</h2>
<p>There are a few machine and deep learning terms which I'll be using in the exercise. So, it's better to understand them on a high level in a couple of sentences before diving in.</p>
<h3 id="heading-what-is-a-neural-network">What is a Neural Network?</h3>
<p>A neural network is a computational model inspired by the structure and functions of the human brain. It consists of interconnected nodes (neurons) organized in layers. Neural networks are trained on data to learn patterns and make predictions.</p>
<h3 id="heading-what-is-an-activation-function">What is an Activation Function?</h3>
<p>An activation function is applied to the output of a neuron to introduce non-linearity. It allows neural networks to learn complex relationships in data. Common activation functions include ReLU (Rectified Linear Unit) and Sigmoid.</p>
<h3 id="heading-what-is-a-loss-function">What is a Loss Function?</h3>
<p>A loss function is a measure of how well a model's predictions match the true target values. During training, the goal is to minimize the loss function, guiding the model to make better predictions.</p>
<h3 id="heading-what-is-gradient-descent">What is Gradient Descent?</h3>
<p>Gradient descent is an optimization algorithm used to minimize the loss function. It adjusts the model's parameters iteratively in the direction of steepest descent, guided by the gradients of the loss function with respect to the parameters.</p>
<h3 id="heading-what-is-backpropagation">What is Backpropagation?</h3>
<p>Backpropagation is a fundamental algorithm used in training neural networks. It calculates the gradients of the loss function with respect to each model parameter and propagates them backward through the network to update the weights during gradient descent.</p>
<h3 id="heading-what-is-batch-size">What is Batch Size?</h3>
<p>Batch size represents the number of training samples used in one forward/backward pass during training. Larger batch sizes can speed up training but require more memory.</p>
<h3 id="heading-what-is-an-epoch">What is an Epoch?</h3>
<p>An epoch represents one complete iteration through the entire training dataset during training.</p>
<p>These are just a few of the many terms you'll encounter in the vast field of machine and deep learning. But they're enough to help you understand the following exercise.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Here's a checklist to help you get started with machine learning basics. Before going through this tutorial, you should have them installed and ready (but it's not mandatory).</p>
<ol>
<li>Install Anaconda (it's packaged with many default machine learning libraries). </li>
<li>Create an environment in Anaconda: This is highly recommended, because only the created environment will be affected if something goes wrong. Your entire Anaconda installation will not be affected.</li>
<li>Make sure you have a good code editor/IDE like Visual Studio Code.</li>
<li>Install Keras (this requirement is specific to this exercise).</li>
</ol>
<p>Do you have all these items ready? Hope you're excited. Let's jump into our exercise.</p>
<h2 id="heading-how-to-sum-two-numbers-using-machine-learning">How to Sum Two Numbers using Machine Learning</h2>
<h3 id="heading-create-a-folder-and-a-file">Create a folder and a file</h3>
<p>Create a new folder with any name. Navigate into the folder and create a file named <code>addition.ipynb</code>. Open the folder in Visual Studio Code or whatever IDE you're using.</p>
<p>Next, create code blocks for each of the following sections by pressing the "+ Code" button at the top left in VS Code.</p>
<h3 id="heading-import-libraries">Import libraries</h3>
<p>Import the <code>numpy</code> and <code>keras</code> libraries with these commands:</p>
<pre><code class="lang-py"><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np
<span class="hljs-keyword">from</span> keras.models <span class="hljs-keyword">import</span> Sequential
<span class="hljs-keyword">from</span> keras.layers <span class="hljs-keyword">import</span> Dense
</code></pre>
<h3 id="heading-prepare-the-data">Prepare the data</h3>
<p>The accuracy of your machine learning models depends on the data with which you train your model. </p>
<p>To create the addition data we'll need here, let's create pairs of 1000 random numbers which will be considered our input. The output will be the sum of the numbers in each pair.</p>
<pre><code class="lang-py">num_samples = <span class="hljs-number">1000</span>
X_train = np.random.rand(num_samples, <span class="hljs-number">2</span>)
y_train = X_train[:, <span class="hljs-number">0</span>] + X_train[:, <span class="hljs-number">1</span>]
</code></pre>
<h3 id="heading-define-the-neural-network">Define the neural network</h3>
<p>Let's build a neural network with two input layers – one hidden layer with 8 neurons, and an output layer with a single neuron. We'll use the "relu" activation function.</p>
<pre><code class="lang-py">model = Sequential()
model.add(Dense(<span class="hljs-number">8</span>, input_shape=(<span class="hljs-number">2</span>,), activation=<span class="hljs-string">'relu'</span>))
model.add(Dense(<span class="hljs-number">1</span>))
</code></pre>
<h3 id="heading-compile-the-model">Compile the model</h3>
<p>Compile the model using the MSE (Mean Squared Error) as the loss function and Adam optimizer.</p>
<pre><code class="lang-py">model.compile(loss=<span class="hljs-string">'mse'</span>, optimizer=<span class="hljs-string">'adam'</span>)
</code></pre>
<h3 id="heading-train-the-model">Train the model</h3>
<p>Train the model for 100 epochs, with a batch size of 32.</p>
<pre><code class="lang-py">batch_size = <span class="hljs-number">32</span>
epochs = <span class="hljs-number">100</span>
model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, verbose=<span class="hljs-number">1</span>)
</code></pre>
<p>This may take few seconds depending on your CPU configuration. It consumed around 10 to 15 seconds in my laptop to complete.</p>
<h3 id="heading-test-the-model">Test the model</h3>
<p>Now that we have trained our model, let's test it with a few custom inputs. I have taken two inputs but you can test your model with any number of inputs.</p>
<pre><code class="lang-python">test_input = np.array([[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>], [<span class="hljs-number">0.3</span>, <span class="hljs-number">0.4</span>]])
predicted_sum = model.predict(test_input)
</code></pre>
<h3 id="heading-print-the-values">Print the values</h3>
<p>The prediction is complete. Let's see if they're right by printing the predicted values:</p>
<pre><code class="lang-python">print(<span class="hljs-string">"Predicted sums:"</span>)
print(predicted_sum)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-187.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sample output of predicted values</em></p>
<p>Pretty close, right?</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, you learned how to build a neural network to perform addition.</p>
<p>If you're curious, though, you can try building a neural network to perform subtraction just for fun. Good luck :)</p>
<p>Hope you enjoyed reading this article. If you wish to learn more about artificial intelligence / machine learning / deep learning, subscribe to my article by visiting my <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_addition_nn">site</a> which has a consolidated list of all my blogs. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create Custom Animations in Flutter – A Step-by-Step Guide ]]>
                </title>
                <description>
                    <![CDATA[ Animations play a crucial role in enhancing user experience and making mobile apps more engaging.  Flutter, Google's UI toolkit for building natively compiled applications for mobile, web, and desktop, offers a powerful animation system that allows d... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/creating-custom-animations-in-flutter/</link>
                <guid isPermaLink="false">66ba10a1d14c87384322b69f</guid>
                
                    <category>
                        <![CDATA[ animations ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Flutter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mobile app development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Wed, 26 Jul 2023 17:44:21 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/Flutter-Animation.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Animations play a crucial role in enhancing user experience and making mobile apps more engaging. </p>
<p>Flutter, Google's UI toolkit for building natively compiled applications for mobile, web, and desktop, offers a powerful animation system that allows developers to create stunning custom animations. </p>
<p>In this step-by-step guide, we will explore how to build beautiful custom animations in Flutter to take your app's UI to the next level.</p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>Before we start, make sure you have Flutter installed on your system. It's also useful to have a basic understanding of the framework's fundamental concepts, such as widgets, state management, and gesture handling.</p>
<p>Finally, but most importantly, muster up a small spark of interest in learning animation! :) Because once you see the widgets come to life with animation magic, that spark's gonna grow into a blazing inferno of excitement.</p>
<p>In this guide, we are going to see how to implement animation in two kinds of tasks:</p>
<ol>
<li>Animated List</li>
<li>Animated Loader</li>
</ol>
<p>We are going to create a simple Todo app with Animated List and Animated Loader. So, saddle up, and let's ride into the world of animating lists and loaders in Flutter. 🤠🐴.</p>
<h2 id="heading-how-to-build-an-animated-list-in-flutter">How to Build an Animated List in Flutter</h2>
<p>First, we will create a simple Flutter list with animation. Animated List is a Flutter widget that allows developers to create dynamic and animated lists with smooth and visually appealing transitions. It is part of the Flutter animation framework and is an extension of the ListView widget. </p>
<p>The Animated List automatically animates changes to the list's content, such as inserting or removing items, providing an engaging and interactive user experience.</p>
<h3 id="heading-key-features">Key Features</h3>
<h4 id="heading-insertion-and-removal-animations">Insertion and Removal Animations</h4>
<p>When you add or remove items from the list, the Animated List animates these changes with predefined or custom animations, making the list's modifications visually seamless.</p>
<h4 id="heading-built-in-animation-controllers">Built-in Animation Controllers</h4>
<p>Animated List comes with built-in animation controllers that handle the timing and ease curves of the animations, simplifying the process of creating smooth and fluid transitions.</p>
<h4 id="heading-customizable-animations">Customizable Animations</h4>
<p>While Animated List provides default animations, developers can also customize the animations to fit the app's unique visual style and requirements.</p>
<p>Now, while theory is essential, practical examples bring concepts to life. So, let's dive into a practical example of using an Animated List in Flutter.</p>
<h3 id="heading-project-setup-and-dependencies">Project Setup and Dependencies</h3>
<p>To create our Flutter app, we'll use Visual Studio Code as our development environment. </p>
<p>If you're not familiar with setting up a new Flutter project, don't worry – you can refer to my previous <a target="_blank" href="https://www.freecodecamp.org/news/how-to-build-a-simple-login-app-with-flutter/">blogs</a> for step-by-step instructions. If you're already comfortable creating Flutter projects, skip this part and proceed with the app development.</p>
<p>No need to install any external plugin to create an Animated List.</p>
<h2 id="heading-how-to-create-a-task-model">How to Create a Task Model</h2>
<p>In this blog, we will focus more on animation so we can keep the functionalities simple. Define a Task class that represents a single task with a title and status.</p>
<p>I created a file called <code>todo_list.dart</code> in the <code>lib</code> folder that will contain the Animated List. First I created a simple class that represents a Task with title and status describing whether it's completed or not.</p>
<p><code>todo_list.dart</code></p>
<pre><code><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Task</span> </span>{
  <span class="hljs-built_in">String</span> title;
  bool isCompleted;
  Task(<span class="hljs-built_in">this</span>.title, <span class="hljs-built_in">this</span>.isCompleted);
}
</code></pre><h2 id="heading-how-to-create-a-simple-list-with-animation">How to Create a Simple List with Animation</h2>
<p>Technically our goal is to create a scrolling container that animates items when inserted or removed. This widget's <a target="_blank" href="https://api.flutter.dev/flutter/widgets/AnimatedListState-class.html">AnimatedListState</a> can be used to dynamically insert or remove items. </p>
<p>To refer to the AnimatedListState either provide a <a target="_blank" href="https://api.flutter.dev/flutter/widgets/GlobalKey-class.html">GlobalKey</a> or use the static <a target="_blank" href="https://api.flutter.dev/flutter/widgets/AnimatedList/of.html">of</a> method from an item's input callback.</p>
<p>To do that, let's create a StatefulWidget to create an Animated List.</p>
<p><code>todo_list.dart</code></p>
<pre><code class="lang-dart"><span class="hljs-comment">// todo_list.dart</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;
<span class="hljs-keyword">void</span> main() {
  runApp(TodoListApp());
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Task</span> </span>{
  <span class="hljs-built_in">String</span> title;
  <span class="hljs-built_in">bool</span> isCompleted;
  Task(<span class="hljs-keyword">this</span>.title, <span class="hljs-keyword">this</span>.isCompleted);
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TodoListApp</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatefulWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  _TodoListAppState createState() =&gt; _TodoListAppState();
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">_TodoListAppState</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">State</span>&lt;<span class="hljs-title">TodoListApp</span>&gt; </span>{
  <span class="hljs-built_in">List</span>&lt;Task&gt; tasks = [];
  <span class="hljs-built_in">bool</span> isLoading = <span class="hljs-keyword">false</span>;

  <span class="hljs-keyword">final</span> GlobalKey&lt;AnimatedListState&gt; _animatedListKey = GlobalKey();

  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: <span class="hljs-keyword">const</span> Text(<span class="hljs-string">'ToDo List'</span>)),
        body: AnimatedList(
          key: _animatedListKey,
          initialItemCount: tasks.length,
          itemBuilder: (context, index, animation) {
            <span class="hljs-keyword">return</span> _buildTaskItem(tasks[index], animation, index);
          },
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _addTask,
          child: <span class="hljs-keyword">const</span> Icon(Icons.add),
        ),
        backgroundColor: Colors.white60,
      ),
    );
  }

  Widget _buildTaskItem(Task task, Animation&lt;<span class="hljs-built_in">double</span>&gt; animation, <span class="hljs-built_in">int</span> index) {
    <span class="hljs-keyword">return</span> SizeTransition(
        sizeFactor: animation,
        child: Card(
          color: Colors.white,
          child: ListTile(
            title: Text(task.title),
            onLongPress: () =&gt; _removeTask(index),
          ),
        ));
  }

  <span class="hljs-keyword">void</span> _addTask() <span class="hljs-keyword">async</span> {
    Task newTask = Task(<span class="hljs-string">'New Task <span class="hljs-subst">${tasks.length + <span class="hljs-number">1</span>}</span>'</span>, <span class="hljs-keyword">false</span>);
    tasks.add(newTask);
    _animatedListKey.currentState!.insertItem(tasks.length - <span class="hljs-number">1</span>);
  }

  <span class="hljs-keyword">void</span> _removeTask(<span class="hljs-built_in">int</span> index) <span class="hljs-keyword">async</span> {
    _animatedListKey.currentState!.removeItem(index,
        (context, animation) =&gt; _buildTaskItem(tasks[index], animation, index));
    tasks.removeAt(index);
  }
}
</code></pre>
<p>Here, we used <code>AnimatedList</code> (a default Flutter package ). The <code>AnimatedList</code> class in Flutter is a powerful widget that allows us to create dynamic and animated lists with smooth transitions. It is an extension of the ListView widget, providing built-in animation support for adding, removing, and updating items in the list. </p>
<p>The primary goal of  <code>AnimatedList</code> is to enhance the user experience by animating changes to the list's content, making the app feel more interactive and visually engaging.</p>
<p><code>AnimatedList</code> has multiple properties or parameters that control various aspects of the widget's behavior, appearance, and animations. Understanding and using these props correctly is crucial to achieving the desired behavior and visual effects in an <code>AnimatedList</code>. </p>
<p>To know about the properties and behavior of <code>AnimatedList</code> please refer to the official <a target="_blank" href="https://api.flutter.dev/flutter/widgets/AnimatedList-class.html">documentation</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/flutter_animated_list_demo.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Simple Animated List in Flutter</em></p>
<p>In this tutorial, we will be focusing on Animated List and Animated Loader. If you are not familiar with Flutter basics (like widgets, states, and so on) I would recommend that you read my previous <a target="_blank" href="https://www.freecodecamp.org/news/learn-state-management-in-flutter/">tutorial</a>.</p>
<h2 id="heading-how-to-build-the-animated-loader">How to Build the Animated Loader</h2>
<p>A loader is commonly used to provide visual feedback to users while waiting for data to load, processing content, or completing network requests. Loaders help improve the user experience by giving a sense of activity and preventing the app from appearing unresponsive during waiting periods.</p>
<p>There are various ways to implement loaders in Flutter, including using built-in widgets, third-party packages, or creating custom loaders. Additionally, "animated loaders" add an extra touch of dynamism to the loading process by incorporating smooth animations.</p>
<p>Let's add an animated loader in our TodoApp while creating and deleting a task.</p>
<h3 id="heading-how-to-add-the-flutter-loader-package">How to Add the Flutter Loader Package</h3>
<p>You'll need to install the package with the following command:</p>
<pre><code>flutter pub add loading_animation_widget
</code></pre><p>Then you should see the following screen:</p>
<p><img src="https://www.gogosoon.com/wp-content/uploads/2023/07/image-28-1024x208.png" alt="Image" width="600" height="400" loading="lazy">
<em>Installing loading animation package in Flutter</em></p>
<p>Now your package should be ready for use.</p>
<h3 id="heading-how-to-implement-animatedloader">How to Implement <code>AnimatedLoader</code></h3>
<p>The <code>loading_animation_widget</code> package offers various loader animations that we can use to display loading indicators in our app. By importing the package, we gain access to these loader animations and can utilize them to enhance the user experience during loading operations or any other asynchronous tasks.</p>
<p>All loading animation APIs follow the same straightforward implementation. There is a static method for each animation inside the LoadingAnimationWidget class, which returns the Object of that animation. Both <code>size</code> and <code>color</code> are required some animations need more than one color.</p>
<p><code>loading_animation_widget</code> offers multiple animated loaders with customized animation. Let's explore a few of those and integrate into our Todo App.</p>
<p>Now I created a file called <code>animated_loader.dart</code>, which has AnimatedLoader Widget.</p>
<pre><code class="lang-dart"><span class="hljs-comment">// animated_loader.dart</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:loading_animation_widget/loading_animation_widget.dart'</span>;

<span class="hljs-keyword">void</span> main() {
  runApp(AnimatedLoader());
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AnimatedLoader</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> MaterialApp(
      home: MyLoaderScreen(),
    );
  }
}
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyLoaderScreen</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> Scaffold(
      body: Center(
        child: LoadingAnimationWidget.staggeredDotsWave(
            size: <span class="hljs-number">75</span>, color: Colors.deepPurple),
      ),
      backgroundColor: Colors.transparent,
    );
  }
}
</code></pre>
<p>Let's show this animated loader in our animated list while adding or removing a task.</p>
<p><code>todo_list.dart</code></p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter_animation/animated_loader.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:loader_overlay/loader_overlay.dart'</span>;

<span class="hljs-keyword">void</span> main() {
  runApp(TodoListApp());
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Task</span> </span>{
  <span class="hljs-built_in">String</span> title;
  <span class="hljs-built_in">bool</span> isCompleted;
  Task(<span class="hljs-keyword">this</span>.title, <span class="hljs-keyword">this</span>.isCompleted);
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TodoListApp</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatefulWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  _TodoListAppState createState() =&gt; _TodoListAppState();
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">_TodoListAppState</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">State</span>&lt;<span class="hljs-title">TodoListApp</span>&gt; </span>{
  <span class="hljs-built_in">List</span>&lt;Task&gt; tasks = [];
  <span class="hljs-built_in">bool</span> isLoading = <span class="hljs-keyword">false</span>;

  <span class="hljs-keyword">final</span> GlobalKey&lt;AnimatedListState&gt; _animatedListKey = GlobalKey();

  Future&lt;<span class="hljs-keyword">void</span>&gt; loadData() <span class="hljs-keyword">async</span> {
    setState(() {
      isLoading = <span class="hljs-keyword">true</span>;
    });
    <span class="hljs-keyword">await</span> Future.delayed(<span class="hljs-keyword">const</span> <span class="hljs-built_in">Duration</span>(seconds: <span class="hljs-number">2</span>));
    setState(() {
      isLoading = <span class="hljs-keyword">false</span>;
    });
  }

  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: <span class="hljs-keyword">const</span> Text(<span class="hljs-string">'ToDo List'</span>)),
        body: Stack(
          children: [
            AnimatedList(
              key: _animatedListKey,
              initialItemCount: tasks.length,
              itemBuilder: (context, index, animation) {
                <span class="hljs-keyword">return</span> _buildTaskItem(tasks[index], animation, index);
              },
            ),
            <span class="hljs-keyword">if</span> (isLoading)
              <span class="hljs-keyword">const</span> Opacity(
                opacity: <span class="hljs-number">0</span>,
                child: ModalBarrier(dismissible: <span class="hljs-keyword">false</span>, color: Colors.black),
              ),
            <span class="hljs-keyword">if</span> (isLoading)
              Center(
                child: Center(child: AnimatedLoader()),
              ),
          ],
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _addTask,
          child: <span class="hljs-keyword">const</span> Icon(Icons.add),
        ),
        backgroundColor: Colors.white60,
      ),
    );
  }

  Widget _buildTaskItem(Task task, Animation&lt;<span class="hljs-built_in">double</span>&gt; animation, <span class="hljs-built_in">int</span> index) {
    <span class="hljs-keyword">return</span> SizeTransition(
        sizeFactor: animation,
        child: Card(
          color: Colors.white,
          child: ListTile(
            title: Text(task.title),
            onLongPress: () =&gt; _removeTask(index),
          ),
        ));
  }

  <span class="hljs-keyword">void</span> _addTask() <span class="hljs-keyword">async</span> {
    Task newTask = Task(<span class="hljs-string">'New Task <span class="hljs-subst">${tasks.length + <span class="hljs-number">1</span>}</span>'</span>, <span class="hljs-keyword">false</span>);
    <span class="hljs-keyword">await</span> loadData();
    tasks.add(newTask);
    _animatedListKey.currentState!.insertItem(tasks.length - <span class="hljs-number">1</span>);
  }

  <span class="hljs-keyword">void</span> _removeTask(<span class="hljs-built_in">int</span> index) <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">await</span> loadData();
    _animatedListKey.currentState!.removeItem(index,
        (context, animation) =&gt; _buildTaskItem(tasks[index], animation, index));
    tasks.removeAt(index);
  }
}
</code></pre>
<p>To explore more about the Loader you can refer to the <a target="_blank" href="https://pub.dev/packages/loading_animation_widget">docs</a>. It has multiple loaders with customization options.</p>
<p><img src="https://www.gogosoon.com/wp-content/uploads/2023/07/flutter_animation_with_loader-2.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Animated List with Animated Loader in Flutter</em></p>
<p>Hurray! We can see that the Animation Loader and Animation List are rendering very smoothly, and they look even better.</p>
<p>If you are implementing this from scratch, that's great and it'll really help you learn. But if you prefer, you can also clone the repo from <a target="_blank" href="https://github.com/5minslearn/flutter_animation">GitHub</a>. Either way, I'm excited to see the Animation Loader and Animation List in action from you.</p>
<p>Note: In the context of creating a task in real time, a loader might not be necessary since the creation of a task typically happens quickly and doesn't involve any lengthy processes like fetching data from an API or performing complex computations. But adding a loader during task creation can still be a useful visual cue to indicate that the task is being processed and provide immediate feedback to the user.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>We explored the world of creating beautiful custom animations in Flutter, focusing on the implementation of Animated List and Animated Loader. By understanding the Animated List, we learned how to create dynamic and interactive lists with smooth item insertions and removals.</p>
<p>Through these examples, you saw Flutter's ability to make animation implementation enjoyable and straightforward. By incorporating custom animations into your apps, you can create engaging and visually appealing interfaces that captivate users and set your apps apart.</p>
<p>If you wish to learn more about Flutter, subscribe to my <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_flutter_animation">email newsletter</a> (<a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_flutter_animation">https://5minslearn.gogosoon.com/</a>) and follow me on social media.</p>
<p>Happy Animating and Fluttering! 🚀 </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Deploy a Next.js App with Custom Domain on AWS Using SST ]]>
                </title>
                <description>
                    <![CDATA[ Serverless architectures have transformed the way we build and deploy applications in the cloud, bringing in more efficiency and scalability. In this article, we'll dive into the Serverless Stack Toolkit (SST), a framework for building serverless app... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-deploy-a-next-js-app-with-custom-domain-on-aws-using-sst/</link>
                <guid isPermaLink="false">66ba10bc90067134b63982c3</guid>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Next.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ serverless ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Mon, 24 Jul 2023 07:18:19 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/AWS---SST---Banner.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Serverless architectures have transformed the way we build and deploy applications in the cloud, bringing in more efficiency and scalability.</p>
<p>In this article, we'll dive into the Serverless Stack Toolkit (SST), a framework for building serverless applications. We'll deploy a Next.js application and set up a custom domain, all without visiting the AWS console. </p>
<p>Let's begin this journey!</p>
<h2 id="heading-what-does-serverless-mean">What Does Serverless Mean?</h2>
<p>The term "serverless" refers to a cloud computing model where developers can build and deploy applications without the need to manage servers. In a serverless architecture, the cloud provider handles server provisioning, scaling, and maintenance. This allows developers to focus solely on writing code for their applications.</p>
<p>With serverless, developers are billed based on actual usage rather than fixed server costs, making it a cost-effective and scalable solution. It offers increased flexibility and agility, as resources are automatically allocated and released based on demand. This eliminates the need for developers to worry about infrastructure management.</p>
<p>Now that we have a good idea of what serverless means, let's see what the Serverless Stack Toolkit (SST) is.</p>
<h2 id="heading-understanding-serverless-stack-toolkit-sst">Understanding Serverless Stack Toolkit (SST)</h2>
<p>The Serverless Stack Toolkit, or SST in short, is a flexible, open-source framework designed to enable faster development and reliable deployment of serverless applications on AWS.</p>
<p>It aims to make it easier for developers to define their application's infrastructure using AWS CDK (Cloud Development Kit).</p>
<p>You can use it to test applications in real-time with Live Lambda Development, debug code in Visual Studio Code, manage applications through a web-based dashboard, and deploy to multiple environments and regions seamlessly.</p>
<h2 id="heading-benefits-of-using-sst">Benefits of Using SST</h2>
<p>Here are some benefits of using the SST stack:</p>
<h3 id="heading-infrastructure-as-code">Infrastructure as Code</h3>
<p>With SST, developers can define their application's infrastructure programmatically using AWS CDK. This improves version control and collaboration among team members.</p>
<h3 id="heading-efficient-testing-and-debugging">Efficient Testing and Debugging</h3>
<p>SST enables live Lambda development, making it easier to test and debug serverless applications locally before deployment to AWS. This reduces potential issues and ensures smoother deployment.</p>
<h3 id="heading-simplified-deployment">Simplified Deployment</h3>
<p>SST simplifies the deployment process, allowing developers to deploy applications to multiple environments and regions effortlessly.</p>
<h3 id="heading-language-flexibility">Language Flexibility</h3>
<p>SST supports multiple programming languages, including JavaScript, TypeScript, Go, Python, C#, and F#, providing developers with the flexibility to use their preferred language for building serverless applications.</p>
<p>Now that we have understood what SST is and some of its benefits, let's see the power of SST in action.</p>
<h2 id="heading-how-to-configure-aws">How to Configure AWS</h2>
<p>Before we add SST we have to configure some AWS credentials. To do that, type the below command in your terminal:</p>
<pre><code>aws configure
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/07/Screenshot-from-2023-07-18-02-29-05.png" alt="Image" width="600" height="400" loading="lazy">
<em>AWS Configure</em></p>
<p>You'll be required to enter your AWS Access Key ID, Secret Access Key, Region name and output format. If you don't have these keys, please <a target="_blank" href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html">create an IAM user</a> and enter the credentials.</p>
<h2 id="heading-how-to-add-sst-to-your-nextjs-app">How to Add SST to Your Next.js App</h2>
<p>We can use SST in an existing Next.js app in <em><a target="_blank" href="https://docs.sst.dev/what-is-sst#drop-in-mode">drop-in mode</a></em> or inside a monorepo app in <em><a target="_blank" href="https://docs.sst.dev/what-is-sst#standalone-mode">standalone mode</a></em>.</p>
<p>In this article, we'll create new Next.js project and add SST which follows drop-in mode installation using the commands below:</p>
<pre><code>yarn create next-app
cd my-app
yarn create sst
yarn install
</code></pre><p><strong>Note</strong>: You should ensure that you have the <code>index.tsx</code> file inside the <code>/pages</code> folder. Without the file, you'll get errors while deploying your app using SST. You don't need to make any changes to this file.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-100.png" alt="Image" width="600" height="400" loading="lazy">
<em>Folder structure</em></p>
<p>Once you run the above commands, SST will create two new files —<code>sst.config.ts</code> and <code>sst-env.d.ts</code></p>
<p>We have to define all our infrastructure and stacks in the <code>sst.config.ts</code> file.</p>
<p>You can use these commands to run the app locally:</p>
<pre><code># Start SST locally
yarn sst dev

# Start Next.js locally
yarn dev
</code></pre><p>On executing the <code>yarn sst dev</code> command, you'll be asked to enter the stage name. Please enter your environment name. I'll use <code>dev</code> for this project's stage name.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-96.png" alt="Image" width="600" height="400" loading="lazy">
<em>Start SST locally</em></p>
<p>Just sit back and watch. It will automatically create the necessary IAM roles, permissions and CloudFormation stacks.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-97.png" alt="Image" width="600" height="400" loading="lazy">
<em>SST - Creating the neccessary IAM roles, permissions and stack</em></p>
<p>Notice in the image above that you can see the Console URL, <code>https://console.sst.dev/sst-demo/dev</code>. With the Console URL, you can view real-time logs, invoke functions, replay invocations, make queries, run migrations, view uploaded files, query your GraphQL APIs, and more!</p>
<p>Just awesome right? I would recommend you to visit the official <a target="_blank" href="https://docs.sst.dev/console">documentation</a> to learn more about the services they offer.</p>
<p>Next, start the Next.js site by running <code>yarn dev</code>. You should see the default page after that.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-98.png" alt="Image" width="600" height="400" loading="lazy">
<em>Next.js default page</em></p>
<p>Our Next.js app is now ready to be deployed to AWS! Just run the following command and see the magic.</p>
<pre><code>yarn sst deploy --stage prod
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-99.png" alt="Image" width="600" height="400" loading="lazy">
<em>OpenNext building the Next.js App</em></p>
<p>It will automatically start building the app using <a target="_blank" href="https://open-next.js.org/">OpenNext</a> , deploy it to AWS using <a target="_blank" href="https://docs.aws.amazon.com/cdk/v2/guide/home.html">CDK</a>, and output the CloudFront URL. Click on the link and you should be able to see your app up and running.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-102.png" alt="Image" width="600" height="400" loading="lazy">
<em>SST - Deployed changes and outputs CloudFront url</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-101.png" alt="Image" width="600" height="400" loading="lazy">
<em>The Next.js app up and running</em></p>
<h2 id="heading-how-to-create-infrastructure-using-sst">How to Create Infrastructure using SST</h2>
<p>To create an infrastructure, we simply need to edit <code>sst.config.ts</code> and import any AWS services like S3 bucket, RDS, API Gateway, and so on from <code>sst/constructs</code></p>
<p>Let's add a simple S3 file upload feature. Open <code>sst.config.ts</code> file and add the code below:</p>
<pre><code><span class="hljs-keyword">import</span> { SSTConfig } <span class="hljs-keyword">from</span> <span class="hljs-string">"sst"</span>;
<span class="hljs-keyword">import</span> {Bucket, NextjsSite } <span class="hljs-keyword">from</span> <span class="hljs-string">"sst/constructs"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  config(_input) {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">name</span>: <span class="hljs-string">"sst-tutorial"</span>,
      <span class="hljs-attr">region</span>: <span class="hljs-string">"us-east-1"</span>,
    };
  },
  stacks(app) {
    app.stack(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Site</span>(<span class="hljs-params">{ stack }</span>) </span>{
      <span class="hljs-keyword">const</span> bucket = <span class="hljs-keyword">new</span> Bucket(stack, <span class="hljs-string">"public"</span>);
      <span class="hljs-keyword">const</span> site = <span class="hljs-keyword">new</span> NextjsSite(stack, <span class="hljs-string">"site"</span>,{
        <span class="hljs-attr">bind</span>:[bucket],
      });
      stack.addOutputs({
        <span class="hljs-attr">SiteUrl</span>: site.url,
      });
    });
  },
} satisfies SSTConfig;
</code></pre><p>Here, we're creating a new public S3 bucket and binding it with our <code>NextjsSite</code>. </p>
<p>Let's edit our index page to add file upload feature.</p>
<h3 id="heading-how-to-upload-files-to-s3-using-sst">How to Upload Files to S3 using SST</h3>
<p>To upload a file to S3, we need to generate a pre-signed URL. To do that, we need to add this package <code>@aws-sdk/s3-request-presigner</code> in our repo.</p>
<pre><code>yarn add @aws-sdk/s3-request-presigner
</code></pre><p>Open <code>index.tsx</code> file and create a function called <code>getServerSideProps</code> above the Home function, as shown in the below code snippet.</p>
<pre><code>...
import { Bucket } <span class="hljs-keyword">from</span> <span class="hljs-string">"sst/node/bucket"</span>;
<span class="hljs-keyword">import</span> { getSignedUrl } <span class="hljs-keyword">from</span> <span class="hljs-string">"@aws-sdk/s3-request-presigner"</span>;
<span class="hljs-keyword">import</span> { S3Client, PutObjectCommand } <span class="hljs-keyword">from</span> <span class="hljs-string">"@aws-sdk/client-s3"</span>;
...
export <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getServerSideProps</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> command = <span class="hljs-keyword">new</span> PutObjectCommand({
    <span class="hljs-attr">ACL</span>: <span class="hljs-string">"public-read"</span>,
    <span class="hljs-attr">Key</span>: crypto.randomUUID(),
    <span class="hljs-attr">Bucket</span>: Bucket.public.bucketName,
  });
  <span class="hljs-keyword">const</span> url = <span class="hljs-keyword">await</span> getSignedUrl(<span class="hljs-keyword">new</span> S3Client({}), command);
  <span class="hljs-keyword">const</span> bucketName = Bucket.public.bucketName
  <span class="hljs-built_in">console</span>.log(bucketName)
  <span class="hljs-keyword">return</span> { <span class="hljs-attr">props</span>: { url } };
}
</code></pre><p>Update the <code>Home()</code> function with the following code.</p>
<pre><code><span class="hljs-keyword">import</span> styles <span class="hljs-keyword">from</span> <span class="hljs-string">"@/styles/Home.module.css"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params">{ url }: { url: string }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{styles.main}</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{styles.center}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">a</span>
          <span class="hljs-attr">href</span>=<span class="hljs-string">"https://5minslearn.gogosoon.com/?ref=github_sst_app"</span>
          <span class="hljs-attr">className</span>=<span class="hljs-string">{styles.card}</span>
          <span class="hljs-attr">target</span>=<span class="hljs-string">"_blank"</span>
          <span class="hljs-attr">rel</span>=<span class="hljs-string">"noopener noreferrer"</span>
        &gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{inter.className}</span>&gt;</span>
            5minslearn <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>-<span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{inter.className}</span>&gt;</span>Learn tech in 5mins<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span>
        <span class="hljs-attr">className</span>=<span class="hljs-string">{styles.form}</span>
        <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{async</span> (<span class="hljs-attr">e</span>) =&gt;</span> {
          e.preventDefault();

          const file = (e.target as HTMLFormElement).file.files?.[0]!;

          const image = await fetch(url, {
            body: file,
            method: "PUT",
            headers: {
              "Content-Type": file.type,
              "Content-Disposition": `attachment; filename="${file.name}"`,
            },
          });

          window.location.href = image.url.split("?")[0];
        }}
      &gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"file"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"file"</span> <span class="hljs-attr">accept</span>=<span class="hljs-string">"image/png, image/jpeg"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{inter.className}</span>&gt;</span>
          Upload
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
  );
}
</code></pre><p>I added an input with a file <code>type</code> and a button for submitting the form. The selected image will be uploaded to S3 when the form is submitted. It's time to deploy the changes.</p>
<p>To deploy the changes, run the <code>yarn sst deploy</code> command.</p>
<p>Once deployed you'll see a page like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-103.png" alt="Image" width="600" height="400" loading="lazy">
<em>Next.js up and running with updated changes</em></p>
<p>Now you can upload any image and check your S3. The selected file will be uploaded to your S3 bucket.</p>
<p>Great, we have successfully deployed the changes. But we still have the random URL generated by CloudFront which may be difficult to memorize for humans. Let's configure a custom domain.</p>
<h2 id="heading-how-to-configure-custom-domains">How to Configure Custom Domains</h2>
<p>To configure custom domains, we need a valid domain or sub-domain. You can create one using Route 53 or your preferred domain provider like GoDaddy, Namecheap, and so on.</p>
<p>If you have a domain on an external DNS provider, you'll need to create an SSL certificate on AWS Certificate Manager (ACM).</p>
<p>I have my domain on Cloudflare. If you have yours with other providers like Namecheap or GoDaddy, then the steps below should still work for you. </p>
<h3 id="heading-how-to-point-cname-to-cloudfront">How to Point CNAME to CloudFront</h3>
<ol>
<li>Login into your DNS provider.</li>
<li>Add a CNAME. In my case, I used <code>aws</code> as the name because my domain is <code>aws.gogosoon.com</code>, and target as the CloudFront URL without <code>https</code>.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-104.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We've successfully pointed our CNAME to CloudFront. Now let's create an SSL certificate for our domain.</p>
<h3 id="heading-how-to-create-acm-certificate">How to Create ACM Certificate</h3>
<p>ACM certificates are managed SSL/TLS certificates that can be used with a variety of AWS services, including CloudFront.</p>
<p>However, there is a specific requirement for using ACM certificates with CloudFront: the certificate must be created in the <strong>US East (N. Virginia) region (us-east-1)</strong>. The reason for this is that CloudFront has all of its provisioning/administrative infrastructure based in <strong>us-east-1</strong>. </p>
<p>Quoting from their <a target="_blank" href="https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cnames-and-https-requirements.html#https-requirements-aws-region">documentation</a>:</p>
<blockquote>
<p>To use a certificate in AWS Certificate Manager (ACM) to require HTTPS between viewers and CloudFront, make sure you request (or import) the certificate in the US East (N. Virginia) Region (us-east-1).</p>
</blockquote>
<p>Here are the steps to follow to create an ACM:</p>
<ol>
<li>Login into AWS console.</li>
<li>Search for certificate manager, switch to <strong>us-east-1</strong> and click on "Request Certificate" in the sidebar.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-105.png" alt="Image" width="600" height="400" loading="lazy">
<em>AWS ACM - Request Certificate</em></p>
<ol start="3">
<li>Enter the domain name you pointed to in your DNS provider configuration. Under "Validation method", select "Email validation" and click next.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-114.png" alt="Image" width="600" height="400" loading="lazy">
<em>AWS ACM - Request Certificate</em></p>
<ol start="4">
<li>A certificate with the status of "Pending Validation" will be created. You'll receive an email from AWS with a link to validate the request.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-106.png" alt="Image" width="600" height="400" loading="lazy">
<em>ACM certificate with pending status</em></p>
<ol start="5">
<li>Once you click on the link in the email, the status of the certificate will be changed to "Issued". Copy the ARN – we'll need it in the next steps.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-111.png" alt="Image" width="600" height="400" loading="lazy">
<em>AWS ACM certificate issued</em></p>
<p>Now that we've created the certificate successfully, let's create the alternate domain for CloudFront.</p>
<h3 id="heading-how-to-create-an-alternate-domain-for-cloudfront-distribution">How to Create an Alternate Domain for CloudFront Distribution</h3>
<ol>
<li>Log into the AWS Console and search for CloudFront.</li>
<li>Click on the distribution created by SST.</li>
<li>In the "General" tab, click the "Edit" button.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-115.png" alt="Image" width="600" height="400" loading="lazy">
<em>Edit CloudFront distribution</em></p>
<ol start="4">
<li>Enter the alternate domain name and select the certificate that we created. Leave all other options as default and click on the "Save changes" button.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-108.png" alt="Image" width="600" height="400" loading="lazy">
<em>Add alternate domain for CloudFront distribution</em></p>
<p>All set! Let's edit our app to deploy the changes to our custom domain.</p>
<h3 id="heading-how-to-configure-external-custom-domain-using-sst">How to Configure External Custom Domain using SST</h3>
<p>Update the <code>sst.config.ts</code> file with the following code. Paste the ARN you copied while creating the certificate as a value for the variable <code>certArn</code>. Replace the <code>domainName</code> with your domain:</p>
<pre><code><span class="hljs-keyword">import</span> { SSTConfig } <span class="hljs-keyword">from</span> <span class="hljs-string">"sst"</span>;
<span class="hljs-keyword">import</span> {Bucket, NextjsSite } <span class="hljs-keyword">from</span> <span class="hljs-string">"sst/constructs"</span>;
<span class="hljs-keyword">import</span> { Certificate } <span class="hljs-keyword">from</span> <span class="hljs-string">"aws-cdk-lib/aws-certificatemanager"</span>;


<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  config(_input) {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">name</span>: <span class="hljs-string">"sst-tutorial"</span>,
      <span class="hljs-attr">region</span>: <span class="hljs-string">"us-east-1"</span>,
    };
  },
  stacks(app) {
    app.stack(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Site</span>(<span class="hljs-params">{ stack }</span>) </span>{
      <span class="hljs-keyword">const</span> bucket = <span class="hljs-keyword">new</span> Bucket(stack, <span class="hljs-string">"public"</span>);
      <span class="hljs-keyword">const</span> certArn = <span class="hljs-string">'Paste the certificate arn'</span>
      <span class="hljs-keyword">const</span> site = <span class="hljs-keyword">new</span> NextjsSite(stack, <span class="hljs-string">"site"</span>,{
        <span class="hljs-attr">bind</span>:[bucket],
        <span class="hljs-attr">customDomain</span>: {
          <span class="hljs-attr">isExternalDomain</span>: <span class="hljs-literal">true</span>,
          <span class="hljs-attr">domainName</span>: <span class="hljs-string">"aws.gogosoon.com"</span>,
          <span class="hljs-attr">cdk</span>: {
            <span class="hljs-attr">certificate</span>: Certificate.fromCertificateArn(stack, <span class="hljs-string">"MyCert"</span>, certArn),
          },
        },
      });
      stack.addOutputs({
        <span class="hljs-attr">SiteUrl</span>: site.customDomainUrl || site.url,
      });
    });
  },
} satisfies SSTConfig;
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-110.png" alt="Image" width="600" height="400" loading="lazy">
<em>sst.config.ts - File changes</em></p>
<p>Run <code>yarn sst deploy</code> to deploy the changes to a custom domain. Once deployed, you should have the app running on the custom URL. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-113.png" alt="Image" width="600" height="400" loading="lazy">
<em>Next.js deployed with custom domain using SST</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-112.png" alt="Image" width="600" height="400" loading="lazy">
<em>Next.js app up and running with custom domain</em></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Voila! Our Next.js app is now deployed to AWS, and we've connected it with our custom domain. Please check out the source code <a target="_blank" href="https://github.com/5minslearn/sst-demo">here</a>.</p>
<p>The SST framework provides an excellent toolset for deploying serverless applications, contributing significantly to development speed, scalability, and error handling.</p>
<p>Feel free to explore more about <a target="_blank" href="https://docs.sst.dev/">SST</a> and its potential in transforming your cloud development experience. Happy coding!</p>
<p>If you wish to learn more about AWS Services, subscribe to my <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_aws_sst_nextjs_deploy">email newsletter</a> (<a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_aws_sst_nextjs_deploy">https://5minslearn.gogosoon.com/</a>) and follow me on social media.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Fine-Tune spaCy Models for NLP Use Cases ]]>
                </title>
                <description>
                    <![CDATA[ spaCy is an open-source software library for advanced natural language processing. It's written in the programming languages Python and Cython, and is published under the MIT license.  spaCy excels at large-scale information extraction tasks. It's wr... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-fine-tune-spacy-for-nlp-use-cases/</link>
                <guid isPermaLink="false">66ba10bf228e16bed602a89c</guid>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ natural language processing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Tue, 11 Jul 2023 14:11:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/Fine-tune-Spacy---Banner.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>spaCy is an open-source software library for advanced natural language processing. It's written in the programming languages Python and Cython, and is published under the MIT license. </p>
<p>spaCy excels at large-scale information extraction tasks. It's written from the ground up in carefully memory-managed Cython.</p>
<p>spaCy is designed to help us build real products, or gather real insights. It's built with 73+ languages, and supports custom models built with Pytorch and Tensorflow. It's robust and has rigorously evaluated accuracy.</p>
<p>You may not know much about Cython. So let's have a quick look at it. </p>
<h2 id="heading-what-is-cython">What is Cython?</h2>
<p>Cython is a Python compiler that makes writing C extensions for Python as easy as Python itself. Cython is based on Pyrex, but supports more cutting edge functionality and optimizations. </p>
<p>To put in simple words, it's a Python to C compiler. </p>
<p>Quoting from Wikipedia, </p>
<blockquote>
<p>Cython is a programming language, a superset of the Python programming language, designed to give C-like performance with code that is written mostly in Python with optional additional C-inspired syntax. </p>
</blockquote>
<p>So you might be wondering if you need to learn Cython to help you fine-tune your spaCy models.</p>
<p>Well, don't worry. You don't need to learn Cython to to work with spaCy. I just wanted to make sure you're aware of what it is to help you get the most out of this tutorial.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<h3 id="heading-basic-knowledge-of-spacy">Basic knowledge of spaCy</h3>
<p>The <a target="_blank" href="https://spacy.io/usage/spacy-101">official documentation site</a> of spaCy provides a lot of information about the tool. Alternatively, you can read my <a target="_blank" href="https://www.freecodecamp.org/news/getting-started-with-nlp-using-spacy/">other tutorial</a> which gives some basic information about spaCy. </p>
<h3 id="heading-basic-knowledge-of-how-to-gather-data">Basic knowledge of how to gather data</h3>
<p>In order to fine-tune any model, you need to have the data ready. And it should be good quality data. </p>
<p>In this tutorial, let's assume we've built a event management software. We want to add voice assistance to our software. We have a module that converts voice input into text. Our next step is to process this text and extract data from the given sentence using spaCy. </p>
<p>We have to gather some basic sentences that we hear from people trying to schedule a event. Here are a few examples:</p>
<ol>
<li>Schedule event for visit to Trivandrum on July 18</li>
<li>Create event happening tomorrow on AI</li>
<li>Schedule Pongal celebration event in Oaks HOA at June 20, 2023</li>
</ol>
<p>Similarly, we have to collect prompts related to event scheduling. The more data you collect and input, more accurate your model will be. </p>
<p>I created 7 sentences, which is much too small for a event management software company to train its model. But from a demo standpoint, it should be enough. </p>
<h2 id="heading-how-to-pre-process-the-data">How to Pre-Process the Data</h2>
<p>Collecting data covers just one part of the equation. We need to pre-process the data and transform it in a way that spaCy can easily understand. We should also define what kind of data (tags) should be identified from the given sentences. </p>
<p>Let's take the following sentence as an example:</p>
<blockquote>
<p>"Schedule event for visit to Trivandrum on July 18". </p>
</blockquote>
<p>Let's try to split out some tags from above sentence:</p>
<ul>
<li>Schedule – this belongs to the "action" tag</li>
<li>event – this belongs to the "domain" tag</li>
<li>visit to Trivandrum – this belongs to the "name" tag</li>
<li>July 18 – this belongs to the "date" tag</li>
</ul>
<p>Every tag defined above may contain alternatives in other sentences. For an example, we may input the following sentences:</p>
<ol>
<li>Cancel client meeting scheduled tomorrow</li>
<li>Change time of mall visit to 6 PM</li>
</ol>
<p>From the above sentences, the action tags are "Cancel" and "Change". Similarly data for each tag may vary for each sentence. </p>
<p>Our next step is to teach spaCy about the words for each tag. We need to prepare a JSON file that contains examples with the tags and their indices. </p>
<p>For example, in the above sentence ("Schedule event for visit to Trivandrum on July 18"), the index for the "action" tag starts from 0 (indices always start from 0 in Python) and ends at 7. </p>
<p>Similarly for all 7 sentences I've chosen, I've prepared the index for each tag and created the JSON file. </p>


<h2 id="heading-how-to-fine-tune-the-spacy-model">How to Fine-Tune the spaCy Model</h2>
<p>Let's try to fine-tune spaCy with the data that we have. </p>
<p>Create a folder and download the above JSON file and place it into the folder. Create a new file named <code>custom_model.ipynb</code>. </p>
<p>All the following sections below need a code block to be created. Create a code block wherever you see a heading. Here's a sample screenshot. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-61.png" alt="Image" width="600" height="400" loading="lazy">
<em>Creating and running blocks of code</em></p>
<h3 id="heading-import-spacy">Import spaCy</h3>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> spacy
</code></pre>
<h3 id="heading-load-the-pre-trained-model">Load the pre-trained model</h3>
<pre><code class="lang-python">nlp = spacy.load(<span class="hljs-string">"en_core_web_lg"</span>)
</code></pre>
<h3 id="heading-import-the-json-file">Import the JSON file</h3>
<p>Import the above downloaded JSON file. </p>
<pre><code><span class="hljs-keyword">import</span> json

<span class="hljs-keyword">with</span> open(<span class="hljs-string">'./event_schedule_data.json'</span>, <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> f:
    data = json.load(f)
</code></pre><h3 id="heading-convert-the-data">Convert the data</h3>
<p>Convert the data read from JSON file into tuple of dictionaries containing original text and entities. </p>
<pre><code>training_data = []
<span class="hljs-keyword">for</span> example <span class="hljs-keyword">in</span> data[<span class="hljs-string">'examples'</span>]:
    temp_dict = {}
    temp_dict[<span class="hljs-string">'text'</span>] = example[<span class="hljs-string">'content'</span>]
    temp_dict[<span class="hljs-string">'entities'</span>] = []
    <span class="hljs-keyword">for</span> annotation <span class="hljs-keyword">in</span> example[<span class="hljs-string">'annotations'</span>]:
        start = annotation[<span class="hljs-string">'start'</span>]
        end = annotation[<span class="hljs-string">'end'</span>] + <span class="hljs-number">1</span>
        label = annotation[<span class="hljs-string">'tag_name'</span>].upper()
        temp_dict[<span class="hljs-string">'entities'</span>].append((start, end, label))
    training_data.append(temp_dict)
print(training_data[<span class="hljs-number">0</span>])
</code></pre><p>The above code will convert the data to the required format and print the first dictionary in the tuple, which will look something like below: </p>
<pre><code class="lang-json">{'text': 'Schedule a calendar event in Teak oaks HOA about competitions happening tomorrow', 'entities': [(<span class="hljs-number">0</span>, <span class="hljs-number">8</span>, 'ACTION'), (<span class="hljs-number">11</span>, <span class="hljs-number">25</span>, 'DOMAIN'), (<span class="hljs-number">29</span>, <span class="hljs-number">42</span>, 'HOA'), (<span class="hljs-number">49</span>, <span class="hljs-number">71</span>, 'EVENT'), (<span class="hljs-number">72</span>, <span class="hljs-number">80</span>, 'DATE')]}
</code></pre>
<h3 id="heading-import-training-libraries">Import training libraries</h3>
<pre><code><span class="hljs-keyword">from</span> spacy.tokens <span class="hljs-keyword">import</span> DocBin
<span class="hljs-keyword">from</span> tqdm <span class="hljs-keyword">import</span> tqdm
<span class="hljs-keyword">from</span> spacy.util <span class="hljs-keyword">import</span> filter_spans

nlp = spacy.blank(<span class="hljs-string">'en'</span>)
</code></pre><h3 id="heading-train-the-model">Train the model</h3>
<p>The below code will create a custom model with the data that we give. A binary file  named <code>train.spacy</code> will be generated at the end. </p>
<pre><code class="lang-python">doc_bin = DocBin()
<span class="hljs-keyword">for</span> training_example <span class="hljs-keyword">in</span> tqdm(training_data):
    text = training_example[<span class="hljs-string">'text'</span>]
    labels = training_example[<span class="hljs-string">'entities'</span>]
    doc = nlp.make_doc(text)
    ents = []
    <span class="hljs-keyword">for</span> start, end, label <span class="hljs-keyword">in</span> labels: 
        span = doc.char_span(start, end, label=label, alignment_mode=<span class="hljs-string">"contract"</span>)
        <span class="hljs-keyword">if</span> span <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
            print(<span class="hljs-string">"Skipping entity"</span>)
        <span class="hljs-keyword">else</span>:
            ents.append(span)
    filtered_ents = filter_spans(ents)
    doc.ents = filtered_ents
    doc_bin.add(doc)

doc_bin.to_disk(<span class="hljs-string">"train.spacy"</span>)
</code></pre>
<h3 id="heading-create-config-files">Create config files</h3>
<p>Create a new file named <code>base_config.cfg</code> and copy the below code into it. </p>


<p>Create another file named <code>config.cfg</code> and copy the below code into it. </p>


<p>Don't worry. These are default configurations that I've taken from their official documentation and I've not made any changes to it. </p>
<h3 id="heading-initialize-spacy-with-the-config-files">Initialize spaCy with the config files</h3>
<p>Run the following command in the notebook code block to initialize spaCy with the config file. This config file will be used to train the spaCy model with our generated custom model. </p>
<pre><code class="lang-python">!python -m spacy init fill-config base_config.cfg config.cfg
</code></pre>
<h3 id="heading-train-spacy-model">Train spaCy model</h3>
<p>Run the following command to train the spaCy model:</p>
<pre><code>!python -m spacy train config.cfg --output ./ --paths.train ./train.spacy --paths.dev ./train.spacy
</code></pre><p>This may take some time depending on your system configuration. Ideally not too long (around 5 to 10 minutes). At the end, it'll generate 2 folders named <code>model-best</code> and <code>model-last</code>. </p>
<h3 id="heading-load-the-best-model">Load the best model</h3>
<pre><code>nlp_ner = spacy.load(<span class="hljs-string">"model-best"</span>)
</code></pre><h3 id="heading-test-our-model">Test our model</h3>
<p>Let's test our model with the following input. </p>
<p>"Could you please reserve a team brainstorming session on coming Wednesday at 11 AM?"</p>
<pre><code class="lang-python">doc = nlp_ner(<span class="hljs-string">"Could you please reserve a team brainstorming session on coming Wednesday at 11 AM?"</span>)

spacy.displacy.render(doc, style=<span class="hljs-string">"ent"</span>)
</code></pre>
<p>You should be surprised to see the output. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-45.png" alt="Image" width="600" height="400" loading="lazy">
<em>Entity representation of our input sentence</em></p>
<p>That's great right? </p>
<p>Eventually, you may have a question: as a programmer, how can I get this data in my backend code? </p>
<p>Well, that's something everyone asks. </p>
<p>spaCy has an answer for it. You can expose the above data as JSON. </p>
<h3 id="heading-convert-extracted-data-to-json">Convert extracted data to JSON</h3>
<pre><code class="lang-python">json_obj = doc.to_json()
json_obj
</code></pre>
<p>This will show a similar output like the one below. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-46.png" alt="Image" width="600" height="400" loading="lazy">
<em>JSON of our test sentence input</em></p>
<p>Write a REST API and expose this data as JSON. That's it. But remember, spaCy will give you only the indices, you have parse your sentence and extract words in between those indices. </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, we learnt about how to customize and fine-tune a pre-trained spaCy model with the data that corresponds to our domain knowledge. </p>
<p>Similarly you can also train with your domain specific data. The model that you fine-tune will be private to you unless you expose it to the public. So it's best suited for training with the domain data that is not publicly available. </p>
<p>If you wish to learn more about NLP/Machine Learning, subscribe to my <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_fine_tune_spacy">email newsletter</a> (<a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_fine_tune_spacy">https://5minslearn.gogosoon.com/</a>) and follow me on social media.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up Firebase Cloud Messaging in Flutter Using Firebase ]]>
                </title>
                <description>
                    <![CDATA[ In today's highly competitive mobile app landscape, effectively engaging your app's users and delivering timely information is key.  Firebase Cloud Messaging (FCM) is a powerful push notification service provided by Firebase. It offers a seamless way... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/set-up-firebase-cloud-messaging-in-flutter/</link>
                <guid isPermaLink="false">66ba10f07282cc17abcf0c68</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Firebase ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Flutter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mobile app development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Wed, 05 Jul 2023 16:38:21 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/A-Complete-Guide-to-FCM-Integration-in-Flutter-Using-Firebase.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In today's highly competitive mobile app landscape, effectively engaging your app's users and delivering timely information is key. </p>
<p>Firebase Cloud Messaging (FCM) is a powerful push notification service provided by Firebase. It offers a seamless way to connect with your app's users and keep them engaged. </p>
<p>In this tutorial, we will delve into the integration of FCM in Flutter. We'll explore its benefits and showcase real-world examples of how it can enhance user engagement and improve app performance. </p>
<h2 id="heading-what-is-firebase-cloud-messaging">What is Firebase Cloud Messaging?</h2>
<p>Firebase Cloud Messaging (FCM) provides a reliable and battery-efficient connection between your server and devices. It allows you to deliver and receive messages and notifications on iOS, Android, and the web at no cost. </p>
<p>In this tutorial, we will explore the process of setting up and using Firebase Cloud Messaging (FCM) in Flutter using Firebase as the backend service. While the main focus will be on Android implementation, it's worth noting that the process is similar for iOS and Android (with a few configuration differences).</p>
<p>Here is what we'll cover:</p>
<ol>
<li>How to create an app in Firebase</li>
<li>How to set up Firebase in Flutter</li>
<li>How to implement push notifications using FCM tokens</li>
</ol>
<p>In this tutorial, you'll learn how to send a simple notification using Firebase to the app running in Flutter. Let's get started.</p>
<h2 id="heading-how-to-create-an-app-in-firebase">How to Create an App in Firebase</h2>
<p>I'll create a new project in the Firebase console to get started. I'll walk through the necessary steps, including project setup, how to configure Firebase Cloud Messaging, and how to get the required credentials and configuration files for our Flutter app.</p>
<p>Before creating the app you need to signup for the Firebase <a target="_blank" href="https://console.firebase.google.com/">console</a> if you don't have an account. After sign up, try to create a project.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-292.png" alt="Image" width="600" height="400" loading="lazy">
<em>Create a Project in Firebase</em></p>
<p>It will take a little time to create a project.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-293.png" alt="Image" width="600" height="400" loading="lazy">
<em>Creating project in Firebase</em></p>
<p>After creating the project, it will redirect you to the project dashboard.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Project Overview in Firebase Console</em></p>
<p>Once you've created the project in Firebase console, it's time to get started with our Flutter app.</p>
<h2 id="heading-how-to-set-up-firebase-in-flutter">How to Set Up Firebase in Flutter</h2>
<p>I have created a simple Flutter project using Visual Studio Code. If you are unfamiliar with building a Flutter project, you can refer to my <a target="_blank" href="https://www.freecodecamp.org/news/how-to-build-a-simple-login-app-with-flutter/">previous tutorial</a>. (If you are already familiar, you can skip this step.)</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-296.png" alt="Image" width="600" height="400" loading="lazy">
<em>Simple Flutter Application running on Android Device</em></p>
<p>Let's integrate Firebase into our Flutter project. To do this, we need a Firebase CLI command line tool. I have already installed the Firebase CLI. If you haven't done this, you can refer to the official <a target="_blank" href="https://firebase.google.com/docs/cli#setup_update_cli">documentation</a>.</p>
<p>Then we need to log in to Firebase using Firebase CLI.</p>
<pre><code>firebase login
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-305.png" alt="Image" width="600" height="400" loading="lazy">
<em>Login to Firebase using FirebaseCLI</em></p>
<p>This will navigate you to the browser to log in to Firebase. You'll be navigated back once the authentication is successfully completed.</p>
<p>After successful login, we need to install FlutterFire CLI. We can use the FlutterFire CLI to configure our Flutter apps to connect to Firebase. Run the following command to activate the FlutterFire CLI:</p>
<pre><code>dart pub <span class="hljs-built_in">global</span> activate flutterfire_cli
</code></pre><p>The FlutterFire CLI is a command-line interface tool that simplifies the integration of Firebase services into Flutter applications. It provides a convenient way to add, configure, and manage Firebase plugins in our Flutter project.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-306.png" alt="Image" width="600" height="400" loading="lazy">
<em>Installing FlutterFireCLI</em></p>
<p>The next step is to add <code>firebase_core</code> library to our Flutter project.</p>
<p>The following command will automatically add the <code>firebase_core</code> package as a dependency in your project's <code>pubspec.yaml</code> file and fetch the latest version of the package from <code>pub.dev</code>. After running this command, you can import the <code>firebase_core</code> package into the Dart files and use Firebase services in our Flutter app.</p>
<pre><code>flutter pub add firebase_core
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-307.png" alt="Image" width="600" height="400" loading="lazy">
<em>Installing Firebase Core package</em></p>
<p>The <code>flutterfire configure</code> command is used to configure Firebase services in our Flutter project using the FlutterFire CLI. This command helps us set up Firebase authentication, Firestore, Cloud Messaging, and other Firebase services easily and efficiently.</p>
<pre><code>flutterfire configure
</code></pre><p>The first step is to choose the project,</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-308.png" alt="Image" width="600" height="400" loading="lazy">
<em>Connect Flutter App with Firebase app</em></p>
<p>The next is to choose the platform. I am using it for Android here, so I choose Android.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-309.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choosing platform</em></p>
<p>After the successful configuration, the Firebase App Id will be displayed.</p>
<p>Finally, we need to add some code changes to our <code>main.dart</code> file.</p>
<p>Import the following packages:</p>
<pre><code><span class="hljs-keyword">import</span> <span class="hljs-string">'package:firebase_core/firebase_core.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'firebase_options.dart'</span>;
</code></pre><p>Add the following configuration to initialize the Firebase config inside the main function of the <code>main.dart</code> file.</p>
<pre><code><span class="hljs-keyword">await</span> Firebase.initializeApp(
  options: DefaultFirebaseOptions.currentPlatform,
);
</code></pre><p>Alright, we have successfully completed the Firebase configuration in our Flutter app! Let's take a moment to celebrate this milestone. Configuring Firebase services is a crucial step in building powerful and feature-rich applications.</p>
<h2 id="heading-how-to-implement-push-notification-using-fcm-tokens">How to Implement Push Notification using FCM Tokens</h2>
<p>We'll implement the process of registering devices for push notifications and retrieving the unique FCM tokens assigned to each device. This step is crucial for sending targeted notifications to specific devices.</p>
<p>We'll dive into the implementation of sending push notifications to devices using Firebase Cloud Messaging. We'll explore how to structure and send notification messages from the Firebase console and demonstrate how to handle these messages within our Flutter app.</p>
<pre><code>flutter pub add firebase_messaging
</code></pre><p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-310.png" alt="Image" width="600" height="400" loading="lazy">
<em>Installing firebse messaging Package</em></p>
<p>Next, we need to trigger the <code>setAutoInitEnabled</code> function to enable automatic initialization of Firebase Cloud Messaging (FCM) in our Flutter app. This means that FCM will automatically initialize and retrieve a device token when the app starts. </p>
<p>Add the following function call in the <code>main</code> method:</p>
<pre><code><span class="hljs-keyword">import</span> <span class="hljs-string">'package:firebase_messaging/firebase_messaging.dart'</span>;
...
...
await FirebaseMessaging.instance.setAutoInitEnabled(<span class="hljs-literal">true</span>);
</code></pre><p>Let's run our Flutter app and verify if we receive the notification.</p>
<p>Navigate to the Firebase <a target="_blank" href="https://console.firebase.google.com/project/_/messaging/?_gl=1*gqfrc0*_ga*NDUwNTM5NDI0LjE2ODgwNTc3NjQ.*_ga_CW55HF8NVT*MTY4ODA5ODkyMC4yLjEuMTY4ODEwMjY2NS4wLjAuMA..">messaging console</a>. As it is our first message, we need to select "Create your first campaign". Select "Firebase Notification messages" and click "Create".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-311.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sample test messaging template</em></p>
<p>Now we need to enter the notification title, text, and name for the message.</p>
<p>Then we can get the FCM token manually for testing purposes using the code below. To retrieve the current registration token for an app instance, call <code>getToken()</code> in the <code>main()</code> method. This method will ask the user for notification permissions if notification permission has not been granted. Otherwise, it returns a token or rejects if there's any error.</p>
<pre><code>final fcmToken = <span class="hljs-keyword">await</span> FirebaseMessaging.instance.getToken();
log(<span class="hljs-string">"FCMToken $fcmToken"</span>);
</code></pre><p>Copy the FCM token printed on the console and paste it into the "Add an FCM registration token" input box.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sent test message using FCM Token</em></p>
<p>Click on the Test button. The targeted client device (with the app in the background) should receive the notification.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/07/image.png" alt="Image" width="600" height="400" loading="lazy">
<em>Received push notification in android device</em></p>
<p>Hurray! We got the notification on our Android device. If we click on the notification it will open the app by default.</p>
<p>When we tap a notification, the default behavior on both Android and iOS is to open the application. If the application is terminated, it will be started. If it is in the background, it will be brought to the foreground.</p>
<p>Here, we can see the basic configuration to initialize Firebase messaging.</p>
<p><code>main.dart</code></p>
<pre><code>
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:firebase_core/firebase_core.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:firebase_messaging/firebase_messaging.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'firebase_options.dart'</span>;

<span class="hljs-keyword">void</span> main() <span class="hljs-keyword">async</span> {
  runApp(<span class="hljs-keyword">const</span> MyApp());
  <span class="hljs-keyword">await</span> Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  final fcmToken = <span class="hljs-keyword">await</span> FirebaseMessaging.instance.getToken();
  <span class="hljs-keyword">await</span> FirebaseMessaging.instance.setAutoInitEnabled(<span class="hljs-literal">true</span>);
  log(<span class="hljs-string">"FCMToken $fcmToken"</span>);
}
</code></pre><h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial we have covered the essential steps for implementing push notifications in Flutter using Firebase Cloud Messaging (FCM). </p>
<p>By following the outlined steps, you can set up Firebase, integrate it into your Flutter project, and implement push notification functionality. </p>
<p>With the ability to send and receive notifications seamlessly, you can enhance the user experience and engage with your app's users effectively. Stay tuned for more advanced topics and features in future tutorials.</p>
<p>If you wish to learn more about Flutter, subscribe to my <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_flutter_firebase">email newsletter</a> (<a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_flutter_firebase">https://5minslearn.gogosoon.com/</a>) and follow me on social media. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ NLP using spaCy – How to Get Started with Natural Language Processing ]]>
                </title>
                <description>
                    <![CDATA[ In today's data-driven world, vast amounts of unstructured text data are generated every day. And to help handle all that data, Natural Language Processing (NLP) has emerged as a transformative technology.  NLP is a sub-field of artificial intelligen... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/getting-started-with-nlp-using-spacy/</link>
                <guid isPermaLink="false">66ba10af052fa53219e0a374</guid>
                
                    <category>
                        <![CDATA[ Machine Learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ natural language processing ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Mon, 26 Jun 2023 23:10:31 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/NLP-using-Spacy---Banner.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In today's data-driven world, vast amounts of unstructured text data are generated every day. And to help handle all that data, Natural Language Processing (NLP) has emerged as a transformative technology. </p>
<p>NLP is a sub-field of artificial intelligence. It focuses on enabling machines to understand, interpret, and generate human language. </p>
<p>In this tutorial, we'll explore the fundamental concepts of NLP and we'll look at a particular implementation with spaCy. This will showcase its immense potential to revolutionize various industries.</p>
<p>Let's have a quick look at Natural Language Processing before we begin with spaCy.</p>
<h2 id="heading-what-is-natural-language-processing">What is Natural Language Processing?</h2>
<p>NLP involves the intersection of linguistics, computer science, and machine learning. Its primary objective is to bridge the gap between human language and machine understanding. </p>
<p>NLP encompasses a wide range of tasks, including Text Classification, Named Entity Recognition (NER), Sentiment Analysis, and more.</p>
<h3 id="heading-text-classification">Text Classification</h3>
<p>This involves categorizing text into predefined classes or categories based on its content. </p>
<p>This has applications in sentiment analysis, spam detection, topic classification, and more.</p>
<h3 id="heading-named-entity-recognition-ner">Named Entity Recognition (NER)</h3>
<p>This involves identifying and extracting named entities such as names, organizations, locations, and dates from text. </p>
<p>NER is crucial for information extraction, question answering systems, and recommendation engines. </p>
<h3 id="heading-sentiment-analysis">Sentiment Analysis</h3>
<p>This involves determining the sentiment or emotion expressed in a piece of text, whether it's positive, negative, or neutral. </p>
<p>Sentiment analysis is extensively used for brand monitoring, customer feedback analysis, and social media monitoring. </p>
<h2 id="heading-challenges-in-natural-language-processing">Challenges in Natural Language Processing</h2>
<p>While NLP has made significant advancements, several challenges persist:</p>
<ol>
<li>Human language is inherently ambiguous, making it challenging sometimes for machines to accurately understand and interpret meaning.</li>
<li>Different languages, dialects, slang, and cultural nuances add complexity to NLP tasks, requiring models to be language-specific and adaptable.</li>
<li>Capturing contextual information and understanding the underlying semantics of text remains a significant challenge for NLP algorithms.</li>
<li>NLP models heavily rely on training data, and biased or low-quality data can result in biased or inaccurate predictions, leading to potential ethical concerns.</li>
</ol>
<h2 id="heading-what-is-spacy">What is spaCy?</h2>
<p>In the world of Natural Language Processing (NLP), spaCy has emerged as a powerful and efficient library, revolutionizing the way developers and researchers work with text data. </p>
<p>spaCy is an open-source Python library designed specifically for NLP tasks such as part-of-speech tagging, named entity recognition, dependency parsing, and more. </p>
<p>It was developed with the goal of providing industrial-strength performance, while still being easy to use and integrate into existing workflows. </p>
<p>spaCy is built on the latest research and implements state-of-the-art techniques, making it an ideal choice for both beginners and experienced NLP practitioners.</p>
<h2 id="heading-key-features-of-spacy">Key Features of spaCy</h2>
<h3 id="heading-linguistic-annotations">Linguistic Annotations</h3>
<p>spaCy provides a wide range of pre-trained models that can quickly analyze text and extract various linguistic features. These features include part-of-speech tags, named entities, syntactic dependencies, sentence boundaries, and more. </p>
<p>The pre-trained models are trained on large corpora and have high accuracy, allowing developers to focus on their specific NLP tasks without worrying about training models from scratch.</p>
<h3 id="heading-tokenization-and-sentence-segmentation">Tokenization and Sentence Segmentation</h3>
<p>Tokenization is a crucial step in NLP that breaks down text into individual words or subwords. spaCy's tokenization algorithms are highly efficient and language-specific, allowing for accurate and customizable tokenization. </p>
<p>spaCy can also automatically segment text into sentences, making it easy to work with text data at a granular level. </p>
<h3 id="heading-entity-recognition">Entity Recognition</h3>
<p>Named Entity Recognition (NER) is the task of identifying and classifying named entities such as persons, organizations, locations, dates, and more. </p>
<p>spaCy's NER capabilities are exceptional, providing out-of-the-box support for multiple languages. It allows developers to train custom NER models using their own labeled data, enabling domain-specific entity recognition. </p>
<h3 id="heading-dependency-parsing">Dependency Parsing</h3>
<p>Dependency parsing involves analyzing the grammatical structure of a sentence by determining the relationships between words. </p>
<p>spaCy's dependency parsing is based on efficient algorithms and achieves high accuracy. It provides a rich set of syntactic annotations, including the head of each word, the dependency label, and the subtree structure. </p>
<p>This information is invaluable for tasks like information extraction, question answering, and sentiment analysis.</p>
<h3 id="heading-customization-and-extensibility">Customization and Extensibility</h3>
<p>One of spaCy's major strengths is its flexibility and extensibility. Developers can easily customize and fine-tune spaCy's models to adapt to specific domains or improve performance on specific tasks. </p>
<p>The library also provides a straightforward API for adding custom components, such as new tokenizers, entity recognizers, or syntactic parsers, making it a versatile tool for research and development. </p>
<h3 id="heading-performance-and-scalability">Performance and Scalability</h3>
<p>spaCy is known for its exceptional performance and scalability. The library is implemented in Cython, a programming language that compiles Python-like code into highly efficient C/C++ modules. This allows spaCy to process text data blazingly fast, making it suitable for large-scale NLP applications and real-time systems. </p>
<h2 id="heading-named-entity-recognition-example-in-spacy">Named Entity Recognition Example in spaCy</h2>
<p>Let's try to implement NER using spaCy. </p>
<p>I'll be using Google Colab. Google Colab is a hosted Jupyter Notebook service that requires no setup to use and provides free access to computing resources, including GPUs and TPUs. </p>
<p>You can use Kaggle instead or run it on your own computer if you'd like. Since spaCy is a pre-trained model, it does not required much computing power to get started. </p>
<p>But I'd advise that you setup Anaconda on your machine if you're working on Machine learning problems. </p>
<p>Navigate to <a target="_blank" href="https://colab.research.google.com">https://colab.research.google.com</a> and click on the "New Notebook" button. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-244.png" alt="Image" width="600" height="400" loading="lazy">
<em>Google Colab Console</em></p>
<p>On the header, enter a name of your file. Ensure your file name ends with <code>.pynb</code> extension. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-245.png" alt="Image" width="600" height="400" loading="lazy">
<em>Change file name and create a code block</em></p>
<p>Click on the "+ Code" button to create a code block. </p>
<p>By default, Google Colab is packed with some machine tools and Python libraries pre-installed. So, we don't have to worry about installations and getting our development environment ready. </p>
<p>But it doesn't come with the <code>spacy</code> library. </p>
<p>Run the following command inside the code block to install the <code>spacy</code> library. </p>
<pre><code class="lang-bash">!pip install -U spacy
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-246.png" alt="Image" width="600" height="400" loading="lazy">
<em>Install <code>spacy</code> library</em></p>
<p>Choose whichever option you want and proceed. The major difference between each one of them is the amount of data it has been trained with. </p>
<ul>
<li>Small – <a target="_blank" href="https://www.freecodecamp.org/news/p/eb6f9486-7030-463a-9ec3-30a1f7858d94/spacy.io/models/en#en_core_web_sm">en_core_web_sm</a></li>
<li>Medium – <a target="_blank" href="https://www.freecodecamp.org/news/p/eb6f9486-7030-463a-9ec3-30a1f7858d94/spacy.io/models/en#en_core_web_md">en_core_web_md</a></li>
<li>Large – <a target="_blank" href="https://www.freecodecamp.org/news/p/eb6f9486-7030-463a-9ec3-30a1f7858d94/spacy.io/models/en#en_core_web_lg">en_core_web_lg</a></li>
<li>Transformer – <a target="_blank" href="https://www.freecodecamp.org/news/p/eb6f9486-7030-463a-9ec3-30a1f7858d94/spacy.io/models/en#en_core_web_trf">en_core_web_trf</a></li>
</ul>
<p>Our next step is to download one of these models. Add a code block and choose any of the ones from the above list and run the following command. I'll be downloading the large model.</p>
<pre><code class="lang-bash">!python -m spacy download en_core_web_lg
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-247.png" alt="Image" width="600" height="400" loading="lazy">
<em>Download pre-trained model</em></p>
<p>Add a code block and run the following command to load the model. </p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> spacy
nlp = spacy.load(<span class="hljs-string">"en_core_web_lg"</span>)
</code></pre>
<p>Alright. We're all set. </p>
<p>Let's try to split entities from a sentence. Add a code block and run the following block of code:</p>
<pre><code class="lang-python">doc = nlp(<span class="hljs-string">"Apple is looking at buying U.K. startup for $1 billion"</span>)

<span class="hljs-keyword">for</span> ent <span class="hljs-keyword">in</span> doc.ents:
    print(ent.text, ent.start_char, ent.end_char, ent.label_)
</code></pre>
<p>In the above code, we're asking the spaCy model to find the entities from the sentence "Apple is looking at buying U.K. startup for $1 billion". </p>
<p>We're then iterating through each entity, and displaying the entity, start and end characters index in the sentence, and the entity label.</p>
<p>You should be seeing the following output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-248.png" alt="Image" width="600" height="400" loading="lazy">
<em>Named Entity Recognition example 1 from <code>spaCy</code></em></p>
<p>The above output describes that "Apple" is an entity and it is present from index 0 to index 5 in the given sentence and it is an Organisation (ORG). </p>
<p>If you're confused about the index, remember that it starts from 0. The first 5 characters in our given input text is "Apple". So, it is from 0 to 5. </p>
<p>Similarly it figures out "U.K." as an entity and describes it as a Geopolitical entity (GPE). It labels "$1 billion" as a Money (MONEY) entity. </p>
<p>Let's try a different sentence this time. </p>
<p>"Prime Minister of India Narendra Modi met US President Joe Biden at Washington DC". </p>
<p>Let's see what are the entities it finds out. Add a code block and run the following code:</p>
<pre><code class="lang-python">doc = nlp(<span class="hljs-string">"Prime Minister of India Narendra Modi met US President Joe Biden at Washington DC"</span>)

<span class="hljs-keyword">for</span> ent <span class="hljs-keyword">in</span> doc.ents:
    print(ent.text, ent.start_char, ent.end_char, ent.label_)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-249.png" alt="Image" width="600" height="400" loading="lazy">
<em>Named Entity Recognition example 2 from <code>spaCy</code></em></p>
<p>That's awesome, isn't it? </p>
<p>It has identified "India", "US", and "Washington DC" as Geopolitical entities (GPE). It has also identified "Narendra Modi" and "Joe Biden" as Person entities (PERSON). </p>
<p>Try to input different sentences and play around with it. I'm sure you'll be amazed at its capabilities in identifying entities. </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, we learnt about NLP with a simple implementation using the spaCy library. </p>
<p>Natural Language Processing holds immense potential to transform the way we interact with machines and analyze vast amounts of textual data. spaCy has become a go-to library for many NLP practitioners due to its powerful features, ease of use, and exceptional performance. </p>
<p>If you wish to learn more about NLP/Machine Learning, subscribe to my <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_getting_started_nlp_spacy">email newsletter</a> (<a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_getting_started_nlp_spacy">https://5minslearn.gogosoon.com/</a>) and follow me on social media. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Offer Custom APIs to Your Users with AWS API Gateway ]]>
                </title>
                <description>
                    <![CDATA[ In the world of cloud computing and serverless architecture, AWS API Gateway is a powerful tool that helps you build robust, secure, and scalable APIs.  In this tutorial, I'll introduce you to API Gateway and explain the benefits of using this helpfu... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-offer-custom-apis-to-your-users-aws-api-gateway/</link>
                <guid isPermaLink="false">66ba10cda1a94b68c6ae94b2</guid>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AWS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Cloud Computing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ serverless ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arunachalam B ]]>
                </dc:creator>
                <pubDate>Wed, 21 Jun 2023 13:56:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/06/AWS-API-Gateway-Banner.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In the world of cloud computing and serverless architecture, AWS API Gateway is a powerful tool that helps you build robust, secure, and scalable APIs. </p>
<p>In this tutorial, I'll introduce you to API Gateway and explain the benefits of using this helpful tool. Then I'll show you how to create and deploy a Rest API, and create usage plans to offer API keys. Alright, let's get started. </p>
<h2 id="heading-what-is-api-gateway">What is API Gateway?</h2>
<p>AWS API Gateway is a fully managed service provided by Amazon Web Services (AWS) that simplifies the creation, deployment, and management of APIs at any scale. </p>
<p>It acts as a front door for applications, and allows you to create APIs that act as bridges between clients and back-end services. This enables secure and efficient communication.</p>
<h2 id="heading-why-do-you-need-api-gateway">Why Do You Need API Gateway?</h2>
<p>AWS API Gateway offers many benefits for businesses and developers. Here are a few benefits of using API Gateway. </p>
<h3 id="heading-scalability-and-high-availability">Scalability and High Availability</h3>
<p>With AWS API Gateway, scaling your APIs becomes much easier. It seamlessly handles traffic spikes by automatically scaling the underlying infrastructure. This results in high availability and helps prevent service disruptions.</p>
<h3 id="heading-security-and-authentication">Security and Authentication</h3>
<p>API Gateway offers robust security features, including built-in authentication and authorization mechanisms. </p>
<p>It supports User Authentication through IAM Roles for internal applications, Cognito for external applications (for example Mobile users), and it also supports custom authorizers. </p>
<h3 id="heading-integration-with-other-aws-services">Integration with other AWS Services</h3>
<p>As part of the AWS ecosystem, API Gateway seamlessly integrates with a range of other AWS services. This enables you to leverage additional functionalities like AWS Lambda functions, AWS Cognito for user management, and AWS CloudWatch for monitoring and logging.</p>
<h3 id="heading-api-lifecycle-management">API Lifecycle Management</h3>
<p>With API Gateway, you can easily version, deploy, and manage different stages of your APIs. This simplifies the process of rolling out updates, testing new features, and managing different environments such as development, staging, and production.</p>
<p>I hope by now you understood what API Gateway is and why it's valuable. Let's dive into creating our very own API Gateway.</p>
<h2 id="heading-how-to-create-an-aws-api-gateway">How to Create an AWS API Gateway</h2>
<p>In this section, we will:</p>
<ul>
<li>Create a Rest API with the GET method</li>
<li>Integrate it with a simple hello world lambda function and deploy it</li>
</ul>
<p>Let's begin with creating a lambda function</p>
<h2 id="heading-how-to-create-an-aws-lambda-function">How to Create an AWS Lambda Function</h2>
<p>Log in to the AWS Management <a target="_blank" href="https://console.aws.amazon.com/">Console</a> and search for "Lambda" in the AWS Management Console search bar. Click on Create Function. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-145.png" alt="Image" width="600" height="400" loading="lazy">
<em>Navigate to AWS Lambda Console</em></p>
<p>Select the "Author from scratch" option, enter a name for your lambda function, select the "Python" runtime, and click the Create Function button at the bottom right. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-146.png" alt="Image" width="600" height="400" loading="lazy">
<em>Create a AWS Lambda Function</em></p>
<p>Once the function is created, update the following code and deploy the changes:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> json

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">lambda_handler</span>(<span class="hljs-params">event, context</span>):</span>
    body = <span class="hljs-string">"Hello from 5minslearn!"</span>
    statusCode = <span class="hljs-number">200</span>
    <span class="hljs-keyword">return</span> {
        <span class="hljs-string">"statusCode"</span>: statusCode,
        <span class="hljs-string">"body"</span>: json.dumps(body),
        <span class="hljs-string">"headers"</span>: {
            <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>
        }
    }
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-147.png" alt="Image" width="600" height="400" loading="lazy">
<em>Deploy a Lambda Function</em></p>
<p>Congratulations! You have successfully created an AWS Lambda function. Now let's create the Rest API. </p>
<h2 id="heading-how-to-create-a-rest-api-and-integrate-it-with-aws-lambda">How to Create a Rest API and Integrate it with AWS Lambda</h2>
<p>Search for API Gateway in the search bar. In the REST API section, click on the Build button. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-183.png" alt="Image" width="600" height="400" loading="lazy">
<em>Create a Rest API</em></p>
<p>Choose the Protocol as Rest and select New API in the Create new API section. In the settings section enter the API name of your choice and leave Endpoint Type as the default. Then click the Create API button. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-148.png" alt="Image" width="600" height="400" loading="lazy">
<em>Configure creating a Rest API</em></p>
<p>Click the Actions Button on the top left. Next, Click Method and select the method as GET and click the Tick icon. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-149.png" alt="Image" width="600" height="400" loading="lazy">
<em>Create a Method</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-150.png" alt="Image" width="600" height="400" loading="lazy">
<em>Choose "GET" method</em></p>
<p>Select Lambda Function as the Integration type and enter the name of the Lambda function you created previously. Then save the function. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-151.png" alt="Image" width="600" height="400" loading="lazy">
<em>Select Method configuration</em></p>
<p>Once you click save, "Add Permission to Lambda Function" will prompt for confirmation. This basically means that you're allowing the API Gateway to invoke a Lambda function. In this case, it is "DemoFunction" Lambda function. Accept the confirmation and proceed to the next step. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-152.png" alt="Image" width="600" height="400" loading="lazy">
<em>Allow Permission to invoke Lambda Function from API Gateway</em></p>
<p>Click on Test. It will take you to a new page. Click on the "Test" button. You'll be able to see the response from the Lambda function on the right side panel. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-153.png" alt="Image" width="600" height="400" loading="lazy">
<em>Our API Architecture</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-184.png" alt="Image" width="600" height="400" loading="lazy">
<em>Test our API Gateway</em></p>
<p>As you have successfully tested your API, you're ready to deploy the API. To deploy the API, click on the Actions button once again and click on Deploy API. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-185.png" alt="Image" width="600" height="400" loading="lazy">
<em>Deploy the API Gateway</em></p>
<p>The Deploy API dialogue will popup. Select New Stage for Deployment stage and name it whatever you want. Click the Deploy button. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-155.png" alt="Image" width="600" height="400" loading="lazy">
<em>Configure API Gateway deployment</em></p>
<p>Click on Invoke URL shown at the top. You can see the response from the Lambda function. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-156.png" alt="Image" width="600" height="400" loading="lazy">
<em>API Gateway Created</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-186.png" alt="Image" width="600" height="400" loading="lazy">
<em>Test our API</em></p>
<p>Great! We successfully created the Rest API, integrated it with the Lambda function, and deployed it.</p>
<p>But you can do this with multiple services available on the market. Why would you choose AWS API Gateway? </p>
<p>Well. That's a interesting question. First of all, you can configure the usage plan for your API. The best part is you don't have to write any code for it. </p>
<p>Now let's create a Usage Plan, generate an API key, and make our Rest API accessible only by passing the API key in the Header. </p>
<h2 id="heading-how-to-create-an-api-gateway-usage-plan">How to Create an API Gateway Usage Plan</h2>
<p>In the left side bar click on Usage Plans and click the Create button. Enter the Name of your plan – I chose "Basic". Enter the Throttling and Quota sections as per your requirements and click Next. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-159.png" alt="Image" width="600" height="400" loading="lazy">
<em>Create AWS API Gateway usage plan</em></p>
<p>Click on the Add API Stage button. Select the API and its stage. Click on the tick icon at right corner and select Next. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/Screenshot-from-2023-06-19-10-46-19.png" alt="Image" width="600" height="400" loading="lazy">
<em>Create a Stage for our API</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-164.png" alt="Image" width="600" height="400" loading="lazy">
<em>Create a Stage for our API</em></p>
<p>Click on Create API Key and add to Usage Plan. A modal will pop up. Enter the Name for API Key. For the API key, I selected Auto Generate but if you want to give a custom key you can enter a custom key. Hit the Save button. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-160.png" alt="Image" width="600" height="400" loading="lazy">
<em>Create a API Key to access the service</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-161.png" alt="Image" width="600" height="400" loading="lazy">
<em>Configure the API Key</em></p>
<p>Select Resources from the Sidebar, click on the GET API you just created, and click the Method Request. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-162.png" alt="Image" width="600" height="400" loading="lazy">
<em>Select the method</em></p>
<p>In the Settings section, update the API Key Required field to true and click the Tick icon. Once updated, don't forget to deploy the changes by hitting the Action dropdown. Your changes will not be updated otherwise. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-187.png" alt="Image" width="600" height="400" loading="lazy">
<em>Enable API Key Required field</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-165.png" alt="Image" width="600" height="400" loading="lazy">
<em>Deploy the API</em></p>
<p>Hit the same URL now and see the magic. </p>
<p>Forbidden!</p>
<p>Because our API layer is protected now. You have to pass the API key in the header to access the data. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-163.png" alt="Image" width="600" height="400" loading="lazy">
<em>Forbidden access if no API Key is provided</em></p>
<p>Now Click on the Usage Plans from the Sidebar. Select your plan and navigate to the API Keys tab. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-166.png" alt="Image" width="600" height="400" loading="lazy">
<em>Access your API Key</em></p>
<p>Click on the API key you created in Step 3. Click Show. Copy the API key. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-188.png" alt="Image" width="600" height="400" loading="lazy">
<em>List of API Keys</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-167.png" alt="Image" width="600" height="400" loading="lazy">
<em>Reveal your API Key</em></p>
<p>You have to pass the API Key in the 'x-api-key' header. Let's switch to the terminal to test this out. </p>
<p>Verify your Rest API without passing the API key at first. Open the terminal, and enter the following curl command. You will once again see the forbidden message. </p>
<pre><code class="lang-bash">curl --location --request GET <span class="hljs-string">'[enter your invoke url]'</span>
--header <span class="hljs-string">'Content-Type: application/json</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-189.png" alt="Image" width="600" height="400" loading="lazy">
<em>Forbidden access without API Key in Terminal</em></p>
<p>Now pass the API key this time. Run the following curl command:</p>
<pre><code class="lang-bash">curl --location --request GET <span class="hljs-string">'[your invoke url]'</span> \
--header <span class="hljs-string">'x-api-key: [your api key]'</span> \
--header <span class="hljs-string">'Content-Type: application/json'</span> \
--data-raw <span class="hljs-string">''</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/06/image-190.png" alt="Image" width="600" height="400" loading="lazy">
<em>Data received on passing API Key in x-api-key Header</em></p>
<p>You can see the output of the Lambda function because you passed 'x-api-key' in the header. </p>
<p>Awesome! You have successfully created the Usage plan, generated the API key, and attached it to the Rest API method and verified the integration. </p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, you learned what AWS API gateway is and how to create Usage Plans for the Rest API. </p>
<p>If you wish to learn more about AWS Services, subscribe to my <a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_aws_api_gateway">email newsletter</a> (<a target="_blank" href="https://5minslearn.gogosoon.com/?ref=fcc_aws_api_gateway">https://5minslearn.gogosoon.com/</a>) and follow me on social media.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
