<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Sai Yerni Akhil's Blog]]></title><description><![CDATA[Sai Yerni Akhil's Blog]]></description><link>https://blog.saiyerniakhil.in</link><generator>RSS for Node</generator><lastBuildDate>Mon, 20 Apr 2026 12:49:54 GMT</lastBuildDate><atom:link href="https://blog.saiyerniakhil.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[RozAI: AI Literacy Without the Jargon]]></title><description><![CDATA[Roz, रोज़ Hindi (noun) - Everyday

This was the conversation between me and my dad a month ago,
(Here are some Telugu transcripts translated into English)

Dad: Arey edhaina manchi resource untey chood]]></description><link>https://blog.saiyerniakhil.in/rozai-ai-literacy-without-the-jargon</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/rozai-ai-literacy-without-the-jargon</guid><category><![CDATA[AI]]></category><category><![CDATA[learning]]></category><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Sun, 08 Mar 2026 08:23:39 GMT</pubDate><content:encoded><![CDATA[<blockquote>
<p><em>Roz, रोज़ Hindi (noun) -</em> Everyday</p>
</blockquote>
<p>This was the conversation between me and my dad a month ago,</p>
<p><em>(Here are some Telugu transcripts translated into English)</em></p>
<blockquote>
<p>Dad: Arey edhaina manchi resource untey choodu ra AI nerchukodaniki<br /><em>(Hey, find me a good resource to learn about AI)</em></p>
<p>Me: Okay, daddy nenu choosi cheptanu</p>
<p>(Okay, daddy let me find some)</p>
<p>Dad: Nerchukovali ra AI gurinchi improve avvali</p>
<p>(I have to learn AI, I need to improve)</p>
</blockquote>
<p>I saw his eagerness to improve and learn, adding to that there's a lot of <em>FOMO</em> (fear of missing out) out on the internet.</p>
<p>I quickly made a quick google search as usual and found some, but none of them I found are simple enough, they are either too technical and most of the content in them are not even needed in day to day activities. So I thought: "Why don't I build one?", So I rolled up my sleeves and started working on it.</p>
<h2>Background</h2>
<p>My dad is a mechanical engineer, running his own contracting firm, has a decent exposure to internet, messaging tools, social media and has good English skills.</p>
<p>When I looked around, there are people with similar skill-sets right in my family (my uncles and aunts). I'm a computer science graduate and been coding and building stuff from almost 10 years, it is also my responsibility to teach and simplify stuff for people, I did that back in school when I worked as a Tutor, a TA (at UWM). Let's dive in.</p>
<p>I initially sent out a form across my family circle to know what are the expectations and what are people afraid of.</p>
<img src="https://cdn.hashnode.com/uploads/covers/5f91a828c626a0545fb6129e/6eb05f57-6e2a-4623-bc8c-20778f696e12.png" alt="" style="display:block;margin:0 auto" />

<p>A quick glance at the results of the survey -</p>
<ul>
<li><p>Barriers</p>
<ul>
<li><p>Don't know where to start</p>
</li>
<li><p>Lack of time</p>
</li>
<li><p>Lack of Confidence</p>
</li>
<li><p>Too Technical</p>
</li>
</ul>
</li>
<li><p>Digital Literacy</p>
<ul>
<li><p>Most of them are comfortable with basic tasks (use a smartphone, search the internet for information, basic troubleshooting, install and signup for apps)</p>
</li>
<li><p>Most of them could follow instructions, but struggle when problems</p>
</li>
</ul>
</li>
<li><p>Security and Privacy Concerns</p>
<ul>
<li><p>Personal Information</p>
</li>
<li><p>Deepfake/Scam anxiety</p>
</li>
</ul>
</li>
</ul>
<h2>Philosophies</h2>
<p>There are a certain philosophies I considered before I started building the application -</p>
<ul>
<li><p>The users shouldn't probably visit the app again<br />Yes, This website is for empowering people and remove their fear for tech/AI. So if done right, they would probably be able to use AI and at the same time don't need any new courses/places to learn how to use AI from.</p>
</li>
<li><p>Learn by Doing, Not Reading<br />I can obviously can't fully have no reading content. The nature of the chat based UI, is making people habituated to reading. So I need to have interactive plus reading material, where the content pushes them to use AI apps.</p>
</li>
<li><p>No Jargon with Justification.<br />They don't know what is machine learning or AI is.</p>
</li>
<li><p>Healthy Skepticism over Blind Trust.<br />People blindly trusted Google search results for health info. AI is even more convincing for health, financial and legal info. So take them with a grain of salt.</p>
</li>
<li><p>Visual and Fun.<br />People easily get bored or overwhelmed with a lot of text The content needs to keep them engaged</p>
</li>
</ul>
<p>Now that I have my principles set, before I start building the application. I wanted to know if I'm missing anything. I need to wear my Product thinking hat, so I interviewed my mom, dad and my uncle to check what are some boring day to day tasks that could be automated.</p>
<p>Once I have the clear picture of what needs to be done, I summoned Claude Code agent to build out my application, carefully crafting the content, running out of my daily token limit, waiting for it to be reset. It took me some 2 odd weeks to finally announce - <a href="https://rozai.co.in">RozAI.</a></p>
<h2>What's more to come?</h2>
<ul>
<li><p>Indic languages support - Telugu, Hindi, and probably Tamil.</p>
</li>
<li><p>More chapters - AI for Work, More info on scams, optional video content for specific languages.</p>
</li>
</ul>
<p>Roz AI is just getting started. Hey, more is coming! Please do leave feedback!</p>
]]></content:encoded></item><item><title><![CDATA[404: Resume Not Found]]></title><description><![CDATA[I revamped my portfolio site from a plain old monochromatic one to a much more attractive one with Demon Slayer themed color palette. Another thought came into my mind - why don’t I update my dusty old resume too and didn’t want to do that every time...]]></description><link>https://blog.saiyerniakhil.in/404-resume-not-found</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/404-resume-not-found</guid><category><![CDATA[Python]]></category><category><![CDATA[GCP]]></category><category><![CDATA[Google Cloud Platform]]></category><category><![CDATA[Docker]]></category><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Mon, 26 Jan 2026 02:34:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/JpTY4gUviJM/upload/5febaf42ff603d20d7001ce5f1041570.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I revamped my portfolio site from a plain old monochromatic one to a much more attractive one with Demon Slayer themed color palette. Another thought came into my mind - why don’t I update my dusty old resume too and didn’t want to do that every time I update my website. I have recently been spending my time on GitHub Actions and Workflow Orchestration lately, so this came into my mind — “Why don’t I create a workflow which build and exposes a public URL whenever I update my work experience?”</p>
<p>Immediately, I vibe-coded a simple continuous integration service that keeps my resume up-to-date.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1769394507876/2f3d9c79-35e5-4f39-bc8f-1c056042f0f4.png" alt="Sequence diagram of how the resume CI interacts with other services" class="image--center mx-auto" /></p>
<p>The heart of the system is the Flask service, that handles Authentication, La-TeX generation, PDF parsing and uploading the parsed PDF to storage bucket.</p>
<h2 id="heading-resume-ci">Resume CI</h2>
<p>It only has a single endpoint <code>/generate</code> which takes in the Authentication key, validates it and upon validation proceeds to the next step to the service layer. The service layer handles most of the core operations - JSON to La-TeX conversion, saving to PDF. Then the saved PDF is upload by the service.</p>
<h3 id="heading-latex-generation">LaTeX Generation</h3>
<p>I initially wanted to build this using Go, but the tools weren’t much helpful (or at least easy to use). Hence I chose Python, PyLaTeX and <code>texlive</code> inside the Docker environment.</p>
<h3 id="heading-authentication">Authentication</h3>
<p>Why did I even need to auth? I’m very paranoid of my GCP bills exploding because I kept my endpoint exposed. Also, I don’t want to spend an entire week building only auth. Moreover, the GitHub Actions (or me from my local) would be only one invoking this API, so the auth needs to be kept simple. Thanks to <a class="user-mention" href="https://hashnode.com/@swap">Swapnil Agarwal</a>’s suggestion, I used the concept of API keys, I generated a simple UUID, which only two entities know, the caller and the resume service.</p>
<h3 id="heading-deployment">Deployment</h3>
<p>Since the CI service was dockerized, the obvious choice was - Google Cloud Run and the GCS Bucket.</p>
<h2 id="heading-why-github-actions">Why GitHub Actions?</h2>
<p>I very much wanted to avoid GitHub Actions, because I already use Netlify to deploy my portfolio site and research about post-build notifications, but sadly Netlify doesn’t allow a request body to be passed, hence I opted GitHub actions with its generous free tier.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1769394310393/8e76d32e-2b2f-401b-bdcb-e8204d1dcbb8.png" alt class="image--center mx-auto" /></p>
<p>You can checkout the resume CI service at <a target="_blank" href="https://github.com/saiyerniakhil/resume-ci">github/saiyerniakhil/resume-ci</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Akhil's Miscellany #1 - December 2025]]></title><description><![CDATA[It is almost the end of the year, and the end of what I call a fine year. This year has been tough, but it has also been a year of significant learning. A brief recap of this year - Got a job, moved to Seattle, started writing Go, joined the DX Club....]]></description><link>https://blog.saiyerniakhil.in/akhils-miscellany-1-december-2025</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/akhils-miscellany-1-december-2025</guid><category><![CDATA[Software Engineering]]></category><category><![CDATA[life]]></category><category><![CDATA[newsletter]]></category><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Wed, 31 Dec 2025 08:00:00 GMT</pubDate><content:encoded><![CDATA[<p>It is almost the end of the year, and the end of what I call a fine year. This year has been tough, but it has also been a year of significant learning. A brief recap of this year - Got a job, moved to Seattle, started writing <a target="_blank" href="https://go.dev/">Go</a>, joined the <a target="_blank" href="https://swap.notion.site/Invitation-to-Join-the-DX-Club-270a4d37f749806bb1a7f493f2385188">DX Club</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1767393932392/1d2aba00-03ae-4154-9cd7-91affc2f84c4.jpeg" alt="Seattle Downtown from Kerry Park" class="image--center mx-auto" /></p>
<p>December is obviously filled with <a target="_blank" href="https://www.imdb.com/title/tt4574334/">The Stranger Things: Season 5</a></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://tenor.com/en-IN/view/noah-schnapp-will-byers-will-stranger-things-stranger-things-will-will-the-wise-gif-12221998521689877609">https://tenor.com/en-IN/view/noah-schnapp-will-byers-will-stranger-things-stranger-things-will-will-the-wise-gif-12221998521689877609</a></div>
<p> </p>
<p>I grew tired of creating a new resume every time I updated my portfolio site, so I built a resume continuous integration service. This service generates a resume using LaTeX, creates a PDF from it, and uploads that to a GCS bucket (more details in another blog post).</p>
<p>I started reading <a target="_blank" href="https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215">"Domain-Driven Design" by Eric Evans; I'll provide</a> more details once I've completed reading it.</p>
<p>Looking forward to an amazing 2026!</p>
]]></content:encoded></item><item><title><![CDATA[Looking back at my CKA Preparation]]></title><description><![CDATA[I was first introduced to Kubernetes while working at Publicis Sapient on a Commerce Intelligence project, where a few hundred web scrapers were run using Kubernetes workflows to scrape e-commerce data. Then I didn’t pay much attention to it and most...]]></description><link>https://blog.saiyerniakhil.in/cka-prep</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/cka-prep</guid><category><![CDATA[Kubernetes]]></category><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Thu, 13 Nov 2025 06:50:26 GMT</pubDate><content:encoded><![CDATA[<p>I was first introduced to Kubernetes while working at Publicis Sapient on a Commerce Intelligence project, where a few hundred web scrapers were run using Kubernetes workflows to scrape e-commerce data. Then I didn’t pay much attention to it and mostly used the k8s UI in Google Cloud and explored the logs. Working at <a target="_blank" href="https://github.com/accuknox">AccuKnox</a>, I could see the amazing things being built, like <a target="_blank" href="https://github.com/kubearmor/KubeArmor">KubeArmor</a>, but I was mostly building their SaaS UI. But I saw a lot of potential in Kubernetes and wanted to learn more about Kubernetes. I would love to discuss the strategy I used to prepare for the CKA.</p>
<p>I had booked my examination slot for Jul 28 and had less than 60 days until the exam. While reviewing available resources, I reached out to my Product Manager at AccuKnox for tips and recommendations, and she suggested the KodeKloud pathways, especially the <a target="_blank" href="https://kodekloud.com/learning-path/kubernetes-administrator">CKA</a> pathway. Before this, I had no experience working with Kubernetes.</p>
<h2 id="heading-planning">Planning</h2>
<p>I used Trello to plan for my exam. Here’s a brief overview of the plan -</p>
<ol>
<li><p>Register for Certification Exam - Jun 2</p>
</li>
<li><p>Linux Basics - May 19</p>
</li>
<li><p>Docker Essentials - Jun 2</p>
</li>
<li><p>Kubernetes Basics - Jun 10</p>
</li>
<li><p>CKA Certification Course - Jul 7</p>
</li>
<li><p>Prep (2 days) - Jul 26</p>
</li>
<li><p>Exam day - Jul 28</p>
</li>
</ol>
<p>I really had to have most of the commands on my fingertips, so for practising, I used Docker, Minikube, and rarely K3S. To practice Linux commands, one can use WSL or <a target="_blank" href="https://multipass.run/docs/installing-on-macos#heading--use-brew">Multipass</a> to spin up a Linux Environment. Even more helpful is the hands-on lab environment on the Kodekloud.</p>
<p>Networking, ETCD Backup and Kubernetes Certificates were the parts I found harder to prepare for.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Linux</td></tr>
</thead>
<tbody>
<tr>
<td>Docker</td></tr>
<tr>
<td>Kubernetes Basics</td></tr>
<tr>
<td>Imperative commands with kubecti</td></tr>
<tr>
<td>Scheduling</td></tr>
<tr>
<td>Logging</td></tr>
<tr>
<td>Application Lifecycle Management</td></tr>
<tr>
<td>Cluster Maintenance</td></tr>
<tr>
<td>Security</td></tr>
<tr>
<td>Storage</td></tr>
<tr>
<td>Networking</td></tr>
<tr>
<td>Design and Install a K8S cluster</td></tr>
<tr>
<td>Install the "Kubeadm" cluster</td></tr>
<tr>
<td>Troubleshooting</td></tr>
<tr>
<td>IstioD</td></tr>
</tbody>
</table>
</div><h3 id="heading-day-of-the-exam">Day of the Exam</h3>
<p>I was confident on the day of the exam, with the basics all covered, and thanks to the practice, I achieved 92%.</p>
]]></content:encoded></item><item><title><![CDATA[Learning Compilers: How it made me a better Software Engineer]]></title><description><![CDATA[Today, I’m a software engineer at GEICO, with over 4 years of experience. When I look back at the subjects I studied that really helped me, I must go back to the first programming language I learnt: C, before I started my undergrad. I memorised the s...]]></description><link>https://blog.saiyerniakhil.in/learning-compilers-how-it-made-me-a-better-software-engineer</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/learning-compilers-how-it-made-me-a-better-software-engineer</guid><category><![CDATA[compiler]]></category><category><![CDATA[Software Engineering]]></category><category><![CDATA[tech ]]></category><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Sun, 09 Nov 2025 08:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/UMlT0bviaek/upload/a1665b91a60ba563906b3096ae2271e0.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Today, I’m a software engineer at GEICO, with over 4 years of experience. When I look back at the subjects I studied that really helped me, I must go back to the first programming language I learnt: C, before I started my undergrad. I memorised the syntax by heart, which made me dive right into thinking in C to solve any problem (although I haven’t solved many complex coding problems like the LeetCode style). It sure did give me a head start among my peers. I used to complete all the homework assignments and explain them to my friends (which is a story for another day on how I learned quickly and remember concepts well). But what subjects did I enjoy the most? It was the Theory of Computation and Compiler Design. I felt like solving puzzles, drawing all the state machines, and writing regular expressions for the BNF/eBNF grammar. I very much enjoyed them (I still feel rusty), although they were just theoretical. Then I spent some years working as a frontend software engineer and completely became rusty in those subjects, like everyone does. In 2024, I decided to return to school to get a Master’s Degree in Computer Science at the University of Wisconsin-Milwaukee. The first semester was great, with subjects like Computer Networks (CS530) and Machine Learning (CS711), but I didn’t enjoy them much. In the second semester, I enrolled in Programming Language Concepts (CS435), which I thought would be a basic intro to programming language. Still, all my peers suggested otherwise, and even then, I dared to continue, and to my surprise, it’s the best subject I took. It’s a combination of the Theory of Computation and Functional Programming, which made me really good at concepts like recursion (the inductive step and base case), generators, pattern matching, and I learned some interesting programming languages like SML and Scala, on top of the usual ones like JavaScript and Python.</p>
<p>The third semester was where the magic and everything began. At UWM, once every two years, Compiler Construction and Theory (CS754, plus a Hands-on Lab) is offered, and taught by <a target="_blank" href="https://uwm.edu/engineering/directory/boyland-john/">Dr John Boyland</a> (one of my favourite professors) and <a target="_blank" href="https://uwm.edu/engineering/directory/boyland-john/">Amir</a> (the TA and Instructor of the Lab), and is one of the difficult courses. Having already taken the PLC (CS435), I was ready to build a COOL (Classroom Object-Oriented Language) compiler by hand, which gave me insight into how programming languages work and behave. The compiler coursework consisted of understanding and building the basic components of a compiler: a lexer (using <a target="_blank" href="https://en.wikipedia.org/wiki/Yacc">yacc</a> and <a target="_blank" href="https://www.antlr.org/">antlr</a>), a parser (using <a target="_blank" href="https://github.com/djspiewak/scala-bison">scala-bison</a>), a semantic analyser, inheritance, code generation, and code optimisation.</p>
<p>The lexer and parser-related modules in the coursework helped me understand how some programming languages have specific syntax. It not only helped me with my research but also with my work (at the Division of Marketing and Communication at UWM). I recall an instance where I encountered a problem with a third-party PHP plugin on a WordPress website. I haven’t worked extensively with PHP before, but the knowledge I gained about the syntax and semantic paradigms helped me debug and fix a bug on a mature WordPress plugin with thousands of users. It gave me the confidence to approach any new programming language fearlessly.</p>
<p>The tree visitor style pattern introduced in the semantic analyser-related modules has given me a great understanding of tree data structures and how they could be traversed. During the type-checking phase of the coursework, the decorator design patterns used to build symbol tables (recalling the <em>Environment</em>, <em>NestedEnvironment</em> and <em>MethodEnvironment</em>) helped explain how decorators work. They were used as a base for Higher-Order Functions or Components in React, <code>@Annotators</code> in Java, and <code>@Decorators</code> in TypeScript. Even checking how casting and subtyping work within object-oriented languages and especially knowing how <em>type-lub</em> and <em>type-leq</em> work, helped a lot.</p>
<p>The implementation of inheritance, I think, makes the biggest difference in my software engineering skills. I have always hesitated to work with pure object-oriented languages like Java (and Scala), even though I used them at work, due to the boilerplate and initial setup required and tended to work more with programming languages like JavaScript and Python because they were simpler.  Now with the concepts I have learnt — like casting, multiple inheritance (and how it is a pain to implement and how different programming languages implement that), vtables and the object layout, I’m more confident than before that I can easily work with Java than before.</p>
<p>Having learnt assembly programming for an 8086 microprocessor as a part of the <em>Micro Processors and Micro Controllers</em> course in my undergraduate studies, I was able to write simple programs like arithmetic operations. The code generation seemed overwhelming at the start, but the handouts and lab sessions helped me understand topics such as the MIPS assembly, the calling sequence and register allocation.</p>
<p>Code Optimisation is the difficult part of the entire coursework to implement, but the techniques learnt were useful in writing better code and are not entirely dependent on the compiler.</p>
]]></content:encoded></item><item><title><![CDATA[Review of "Sapiens: A Brief History of Humankind" by Yuval Noah Harari]]></title><description><![CDATA[Picked it up last year but lost interest. But now picked this and I don't regret that. 
I have previously had history lessons in my school, but they're either just an account of a particular period. But this gives a brief (as already in its name) pic...]]></description><link>https://blog.saiyerniakhil.in/review-of-sapiens-a-brief-history-of-humankind-by-yuval-noah-harari</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/review-of-sapiens-a-brief-history-of-humankind-by-yuval-noah-harari</guid><category><![CDATA[books]]></category><category><![CDATA[history]]></category><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Sun, 30 Jan 2022 14:32:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/5IB1fLcHJtk/upload/v1643553012694/bGjpBazeI.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Picked it up last year but lost interest. But now picked this and I don't regret that. </p>
<p>I have previously had history lessons in my school, but they're either just an account of a particular period. But this gives a brief (as already in its name) picture/birdseye view of entire Humankind. Starting from Cognitive Revolution, Agricultural Revolution, Scientific Revolution to also the future of Sapiens. This book takes us to completely new perspectives of things we have been seeing until now a very good example is the cultivation of staple crops, we've been seeing it always as an advantage to the human beings giving us a lot of calories to spare but it makes us think that not the staple crop but it's the Sapiens who had been domesticated. It really helped me to view things totally in a different view. Another example would be how the empire and wars drove the scientific revolution during early 18th centuryand not the thought of bettering the lives of human kind. Its also touches briefly on the topics of biochemistry, bioengineering, bionic life and genetic engineering which might decide the future of Sapiens.</p>
<p>"Is there anything more dangerous than dissatisfied and irresponsible gods who don't know what they want?"</p>
<p>I would recommend this to anyone who wants to know more about the species that is reigning over the planet for the over 70 millenia.</p>
]]></content:encoded></item><item><title><![CDATA[Building a Scrollspy and more using React and IntersectionObserver API]]></title><description><![CDATA[What is an IntersectionObserver ?
An  IntersectionObserver is a utility in the native browser APIs which lets us check whether an element has intersected the viewport or any other ancestor.
I came across this while I was trying to build a scroll spy,...]]></description><link>https://blog.saiyerniakhil.in/building-a-scrollspy-and-more-using-react-and-intersectionobserver-api</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/building-a-scrollspy-and-more-using-react-and-intersectionobserver-api</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[animation]]></category><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Sun, 02 Jan 2022 16:00:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/wJTKGSl9W7E/upload/v1641138984207/Fp7vM_o7O.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4 id="heading-what-is-an-intersectionobserver">What is an IntersectionObserver ?</h4>
<p>An  <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API">IntersectionObserver</a> is a utility in the native browser APIs which lets us check whether an element has intersected the viewport or any other ancestor.</p>
<p>I came across this while I was trying to build a scroll spy, you might be wondering what a scroll spy is? If you have ever used/worked with Bootstrap,  <a target="_blank" href="https://getbootstrap.com/docs/5.1/components/scrollspy/">scroll spy</a>  implementation is available directly via Bootstrap’s utilities which are built on top of jQuery.</p>
<p>Check out this example and see how it works on Google Docs - 
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641124272967/if1_dnilO.gif" alt="okBSKyAI4T.gif" /></p>
<p>It becomes so easy with bootstrap, but at work, its a React.js project and we aren’t using Bootstrap over there, so I had to search for alternatives and one such library was  <a target="_blank" href="https://www.npmjs.com/package/react-scrollspy">react-scrollspy</a>  but I don’t have the luxury of installing the library in my project plus its deprecated anyways. So I had to roll my sleeves and build one, which serves the purpose. I was as usual googling stuff on how I could and I came across many solutions and one that I found interesting was  <a target="_blank" href="https://stackoverflow.com/questions/45514676/react-check-if-element-is-visible-in-dom/65008608#65008608">one</a>  by user  <a target="_blank" href="https://stackoverflow.com/users/3013279/creaforge">@Creaforge</a> on Stack Overflow using IntersectionObserver API. I have successfully built that feature and I have gone forward and learnt more about it since I found it very interesting. In this blog post, I’m going to share what I have learnt and also gonna give some examples in which we can use this API.</p>
<p>Here are some examples I have built using IntersectionObserver API - </p>
<h4 id="heading-1-implementing-a-scrollspy-in-react">1. Implementing a ScrollSpy in React</h4>
<p>I have written a hook from  <a target="_blank" href="https://stackoverflow.com/users/3013279/creaforge">@Creaforge</a>’s answer on Stack Overflow and took it forward from that. I made use of <code>ref</code> to get the component’s reference to the DOM.</p>
<pre><code><span class="hljs-keyword">import</span> { <span class="hljs-title">useEffect</span>, <span class="hljs-title">useMemo</span>, <span class="hljs-title">useState</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">'react'</span>;

<span class="hljs-comment">/**
 *
 * @param {ReactRef} ref reference to the DOM
 * @param {object} options (optional)
 * @returns {boolean} if the ref is intersecting the viewport
 *  - The `root` is the scrollable parent of which the ref is a descendant of.
 *  - `rootMargin` is the margin of the root element
 *  - a single `threshold` ranges from 0 to 1.0 (0 - 100%) as also can be an array [0, 0.5,...1.0]
 *  - The callback to the IntersectionObserver constructor is invoked, when the ref is x% of the parent element
 */</span>
<span class="hljs-keyword">import</span> { <span class="hljs-title">useEffect</span>, <span class="hljs-title">useMemo</span>, <span class="hljs-title">useState</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">"react"</span>;

export default <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">useOnScreen</span>(<span class="hljs-params">ref</span>) </span>{
  const [isIntersecting, setIntersecting] <span class="hljs-operator">=</span> useState(<span class="hljs-literal">false</span>);

  let options <span class="hljs-operator">=</span> {
    root: document.querySelector(<span class="hljs-string">"#root-el"</span>),
    rootMargin: <span class="hljs-string">"0px"</span>,
    threshold: <span class="hljs-number">0</span><span class="hljs-number">.5</span>
  };

    <span class="hljs-comment">// useMemo since the IntersectionObserver does consume more resources</span>
  const observer <span class="hljs-operator">=</span> useMemo( 
    () <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span>
      <span class="hljs-keyword">new</span> IntersectionObserver(
        ([entry]) <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> setIntersecting(entry.isIntersecting),
        options
      ),
    [ref]
  );

  useEffect(() <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> {
    observer.observe(ref.current);
    <span class="hljs-comment">// Removing the observer when the component is unmounted</span>
    <span class="hljs-keyword">return</span> () <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> {
      observer.disconnect();
    };
  }, []);

  <span class="hljs-keyword">return</span> isIntersecting;
}
</code></pre><p>Now, this hook will tell me whether an element (<code>ref</code>) is on my screen matching the threshold and lets me set the state.</p>
<p>So now I have a state variable, which contains the latest div which intersected the screen, so I’ll take that state variable and try to highlight the currently active element</p>
<pre><code>...
const [currentRefOnScreen, setCurrentRefOnScreen] <span class="hljs-operator">=</span> useState(<span class="hljs-operator">&lt;</span>id of the ref<span class="hljs-operator">&gt;</span>);
...
...
<span class="hljs-keyword">return</span>  (
    <span class="hljs-operator">&lt;</span>nav<span class="hljs-operator">&gt;</span>
            <span class="hljs-operator">&lt;</span>ul<span class="hljs-operator">&gt;</span>
                navList.map((navItem,index) <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> (
                        <span class="hljs-operator">&lt;</span>li className<span class="hljs-operator">=</span>{currentRefOnScreen <span class="hljs-operator">=</span><span class="hljs-operator">=</span><span class="hljs-operator">=</span> index ? <span class="hljs-string">'active'</span> : <span class="hljs-string">''</span>}<span class="hljs-operator">&gt;</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>li<span class="hljs-operator">&gt;</span>
                ))
            <span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>ul<span class="hljs-operator">&gt;</span>
    <span class="hljs-operator">&lt;</span>nav<span class="hljs-operator">&gt;</span>
...
)
</code></pre><p>The remaining part of the scroll spy left to implement was to scroll to the section when clicked on the nav list item.  Since I have access to the ref, I can easily scroll to the <code>ref</code> using <code>ref.scrollIntoView(..)</code></p>
<p>Here is the link to the final version on  <a target="_blank" href="https://vcke3.csb.app/">codesandbox.io</a>.</p>
<h4 id="heading-2-fancy-scroll-animation">2. Fancy Scroll Animation</h4>
<p>There is another example I have tried out to replicate the functionality which I’ve found on the Apple iPhone 13’s product display  <a target="_blank" href="https://www.apple.com/iphone-13/">page</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641125568106/czpvi3lVD.gif" alt="AmccSggRkM.gif" /></p>
<p>Here you can see how the battery level changes from 0 to 100 while scrolling. Our target is to replicate that.</p>
<p>Similar to the above scroll spy implementation example we need <em>to observe</em> something (target) within <em>the parent</em> (root)</p>
<p>So now we’ll have to observe the section of the page which contains the battery icon (and maybe the text describing it) and calculate the amount of the targeted element which is visible.</p>
<p>Let us start with the implementation - </p>
<ul>
<li>We’ll start by creating an observer and starting observing the target element</li>
</ul>
<pre><code>
const createObserver <span class="hljs-operator">=</span> () <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> {
  let observer;
  let options <span class="hljs-operator">=</span> {
    root: null,
    rootMargin: <span class="hljs-string">"0px"</span>,
    threshold: buildThresholdList()
  };

  observer <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> IntersectionObserver(handleIntersection, options);
  observer.observe(boxElementToBeObserved);
};

let boxElementToBeObserved;
boxElementToBeObserved <span class="hljs-operator">=</span> document.querySelector(<span class="hljs-string">"#app"</span>);

<span class="hljs-comment">//createObserver();</span>
</code></pre><p>We’ll also have a function that gives us the threshold values, here in this case I’m using a list of values because I want the battery percentage to increase from 0 to 1.0 in 10 (<code>numSteps</code>) intervals. Which turns out to be 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7,...1.0. One can increase or decrease the threshold based on the requirements.</p>
<p>Here is how it looks when the steps are reduced to 2 - </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641125988017/PojXWYI-O.gif" alt="0066t5y4uE.gif" /></p>
<p>and when the number of steps is 10 - </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1641126100270/KPPjes5ch.gif" alt="V1ttBefIvh.gif" /></p>
<ul>
<li>Next, we’ll jump into writing our intersection handler, which is called whenever the threshold values are met. calculating the width includes subtracting from 100 because initially 100% of the element will be visible and we need to start from 0 (100 - 100 = 0, Isn’t it?😂)</li>
</ul>
<pre><code>let prevRatio <span class="hljs-operator">=</span> <span class="hljs-number">0</span><span class="hljs-number">.0</span>;
const handleIntersection <span class="hljs-operator">=</span> (entries, observer) <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> {
  entries.forEach((entry, entryIndex) <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> {
    batteryLevelElement.style.width <span class="hljs-operator">=</span> `${<span class="hljs-number">100</span> <span class="hljs-operator">-</span> entry.intersectionRatio <span class="hljs-operator">*</span> <span class="hljs-number">100</span>}<span class="hljs-operator">%</span>`;
    prevRatio <span class="hljs-operator">=</span> entry.intersectionRatio; <span class="hljs-comment">// just preserving for reference incase we need it in future</span>
  });
};
</code></pre><p>Entries here are the list of Intersection objects for all the target elements we are observing, in our case, it’ll have only one element.</p>
<ul>
<li>Since we need to change the battery level, I have gotten access to the battery level element to which we have to change the width.</li>
</ul>
<pre><code><span class="hljs-keyword">const</span> batteryLevelElement = <span class="hljs-built_in">document</span>.<span class="hljs-built_in">querySelector</span>(<span class="hljs-string">".batteryLevel"</span>);
</code></pre><p>Here is the final working demo of the battery animation - https://codesandbox.io/s/apple-intersection-observer-example-final-5n6wx</p>
<p>I’m sure there might be better ways of doing without the extensive usage of refs in the implementation of scroll spy and If you have better solutions and any feedback, I’m glad to learn them from you😀. Make use of the comments section for constructive feedback.</p>
<p><strong>References -</strong></p>
<ol>
<li>IntersectionObserver documentation on MDN - https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API</li>
<li>StackOverflow thread - https://stackoverflow.com/questions/45514676/react-check-if-element-is-visible-in-dom</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Moving from Bootstrap to Tailwind.CSS]]></title><description><![CDATA[I know a lot more people getting started with web development learn bootstrap as the very initial step to master because it helps in prototyping more rapidly without having to write/focus a lot on media queries or writing custom CSS (removes all the ...]]></description><link>https://blog.saiyerniakhil.in/moving-from-bootstrap-to-tailwindcss</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/moving-from-bootstrap-to-tailwindcss</guid><category><![CDATA[CSS]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[Bootstrap]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Thu, 16 Sep 2021 07:06:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1631948764375/8ULLIVbzM.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I know a lot more people getting started with web development learn bootstrap as the very initial step to master because it helps in prototyping more rapidly without having to write/focus a lot on media queries or writing custom CSS (removes all the hassle) and concentrate on building applications. But now bootstrap has become common and people are moving towards other CSS frameworks like Tailwind.css, SemanticUI etc. </p>
<p>Tailwind.css likes to call itself a utility-first CSS framework. So what is a utility first CSS framework? Let us know that by an example, consider a social media application similar to Facebook, which contains something like a friends list, it might have a container (<code>div</code>) with a CSS class something like <code>.friends-list</code> we don't know what that class does unless we take a look at the CSS code, this is called semantic-first CSS. the <code>.friends-list</code> class might have the following CSS - </p>
<pre><code><span class="hljs-selector-class">.friends-list</span> {
    <span class="hljs-attribute">display</span>: flex; <span class="hljs-attribute">flex-direction</span>: column;
}
</code></pre><p>While talking about utility-first CSS, In tailwind we do something like this - </p>
<pre><code><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex flex-col"</span>&gt;</span>
        ...
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre><p>Bootstrap also implements such utility first classes, but that's very limited. For example, in bootstrap, we have <code>.card</code> we don't know what that does unless we inspect the HTML element.</p>
<blockquote>
<p>One thing note is that tailwind.css doesn't provide components like bootstrap's form, accordion, card etc.</p>
</blockquote>
<p>Now let's see how we can move from bootstrap to tailwind and going forward through this article we'll know about things starting from the setup to implement things in Tailwind that we can do in bootstrap.</p>
<h2 id="the-setup">The Setup</h2>
<p>We can set up tailwind using a CDN similar bootstrap also but there will not be any benefits like removal of unused CSS. You can refer to  <a target="_blank" href="https://tailwindcss.com/docs/installation#using-tailwind-via-cdn">this</a>. To reap the benefits of tailwind, we must use it with any build tools like PostCSS.</p>
<h3 id="initialize-an-npm-project-and-install-the-dependencies">initialize an npm project and install the dependencies -</h3>
<pre><code><span class="hljs-built_in">npm</span> init -y
<span class="hljs-built_in">npm</span> install tailwindcss@latest postcss@latest autoprefixer@latest vite
</code></pre><p><em>Note: <code>vite</code> is a build tool just like <code>webpack</code> which we see in the create-react-app</em></p>
<p>Setup tailwind.config.js and postcss.config.js</p>
<pre><code>npx tailwind <span class="hljs-keyword">init</span> -p
</code></pre><p>Now in the package.json, add a script to start the server - </p>
<pre><code><span class="hljs-keyword">...</span>
 <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"dev"</span>: <span class="hljs-string">"vite"</span>
  },
<span class="hljs-keyword">...</span>
</code></pre><p>Now in your base CSS file in the project, add these lines which import the base, component and utility layers from tailwind</p>
<pre><code><span class="hljs-variable">@tailwind</span> base;
<span class="hljs-variable">@tailwind</span> components;
<span class="hljs-variable">@tailwind</span> utilities;
</code></pre><p><em>Note: Do not forget to import this CSS file into your index.html file</em></p>
<p>You can get the boilerplate from  <a target="_blank" href="https://github.com/tailwindlabs/tailwindcss-from-zero-to-production/tree/main/01-setting-up-tailwindcss">here</a> (just download this, do npm install and it's done!) </p>
<p>Now that the setup is done, we'll move into things we had most implemented in bootstrap and try to replicate them using tailwind.</p>
<h4 id="grid">Grid</h4>
<p>The first of the things that have made bootstrap popular is it's easy to implement grid layout. Bootstrap divides the layout into 12 columns. If you look closely, bootstrap implements its grid using the flexbox but Tailwind uses the grid as it is.</p>
<pre><code><span class="hljs-comment">&lt;!-- using bootstrap --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-8"</span>&gt;</span>
         width of 8
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-4"</span>&gt;</span>
         width of 4 
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre><p>In tailwind, we can use up to 12 columns, but we can use even more than that by configuring the tailwind (more about <a target="_blank" href="https://tailwindcss.com/docs/theme#customizing-the-default-theme">customizing tailwind</a> )</p>
<pre><code><span class="hljs-comment">&lt;!-- using tailwind --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"grid grid-cols-12"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"grid-span-8"</span>&gt;</span>
         width of 8
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"grid-span-4"</span>&gt;</span>
         width of 4 
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre><p>For gutters/grid-gap, we can use <a target="_blank" href="https://tailwindcss.com/docs/gap"><code>gap-{n}</code></a> to the grid container.</p>
<h4 id="flexbox">Flexbox</h4>
<p>In bootstrap, we use <code>d-flex</code> and <code>flex</code> in tailwind.</p>
<pre><code><span class="hljs-comment">&lt;!-- using bootstrap--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"d-flex flex-row justify-content-start"</span>&gt;</span>
     text with flex-direction as row and its content justified start 
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre><pre><code><span class="hljs-comment">&lt;!-- using tailwind --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"flex flex-row justify-start"</span>&gt;</span>
     text with flex-direction as row and its content justified start 
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre><p>As we see, getting started with tailwind is not so hard 😀</p>
<h4 id="spacing">Spacing</h4>
<h5 id="margin-and-padding">Margin &amp; Padding</h5>
<p>Spacing is the most often thing we come across and have to deal with and similar to what we have seen with flexbox, spacing isn't different at all. </p>
<pre><code><span class="hljs-comment">&lt;!-- Tailwind --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m-4 mx-4 my-4 mt-4 mb-4 ml-4 mr-4"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre><blockquote>
<p>the m{direction}-{n} where direction is left (l), right (r), top (t), bottom (b), x-axis (x), y-axis (y) and n ranges from 0, 0.5 (0.125rem), 1, 1.5...4 (1rem)</p>
</blockquote>
<p>and we can replace <code>m</code> with <code>p</code> for padding.</p>
<h4 id="sizing">Sizing</h4>
<p>Sizing in tailwind is not limited to percentages of the parent container like we see in bootstrap, we can have a width in <code>rem</code> and also in percentage of the parent container and a lot more and here are some examples - </p>
<pre><code><span class="hljs-comment">&lt;!-- Tailwind --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w-1{-96}"</span>&gt;</span>
<span class="hljs-comment">&lt;!-- 1 - 0.5rem --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"w-5/12"</span>&gt;</span>
<span class="hljs-comment">&lt;!-- width = 41.666 --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre><h4 id="responsive-utility-based-css">Responsive utility based CSS</h4>
<p>When we use bootstrap, there is no way for us to avoid writing CSS at least for the responsive styles which we want to apply for a specific viewport. Personally, I think this is where tailwind.css excels.</p>
<p>In bootstrap, we can only control the responsiveness of grid layout for different viewports without any CSS. Let me show things we can do with tailwind -</p>
<pre><code>&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span>="<span class="hljs-title">sm</span>:<span class="hljs-type">text-blue-500 md:text-green-500 lg:text-red-500"&gt;</span></span>
&lt;/div&gt;
</code></pre><p>This applies different text colours for different viewports. We also have access to other viewports xs, xl, 2xl. </p>
<p>So, this will be our basic intro to get started with your journey from bootstrap to tailwind.css .</p>
<p>Thanks a lot for reading this article. Please comment you view and suggestions, it would help me a lot in improving.</p>
]]></content:encoded></item><item><title><![CDATA[A Short Review of "Dune", by Frank P Herbert]]></title><description><![CDATA["One Must Not Fear, Fear is the Mind Killer" - Dune

While reading the Dune, you'll not only read it but will live in it. I literally had dreams of me being on Arrakis and living in a cave, God! It made such an impact on me.
The philosophy of the Dun...]]></description><link>https://blog.saiyerniakhil.in/a-short-review-of-dune-by-frank-p-herbert</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/a-short-review-of-dune-by-frank-p-herbert</guid><category><![CDATA[books]]></category><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Thu, 06 May 2021 09:50:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1620294558400/XER0EEfpS.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>"One Must Not Fear, Fear is the Mind Killer" - Dune</p>
</blockquote>
<p>While reading the Dune, you'll not only read it but will live in it. I literally had dreams of me being on Arrakis and living in a cave, God! It made such an impact on me.</p>
<p>The philosophy of the Dune is so great, showing how tough people are made by living in a challenging environment be it Fremen (on Arrakis) or Sardaurkar (on Selusa Secundus).</p>
<p>Frank Herbert is an absolute genius. His imagination is top-class and so detailed, he even had an entire ecology of Dune created, starting from vegetation to terrain and the food chain. It also had royal houses Atreides, Harkonnens, Corrinos .The Dune also had its own religion formed over the basis of Islam, Christianity, Buddhislamic and Hinduism, There are also quite a few references to Arabic in the book. The terms like Bene Gesserit a religious school trying to achieve an apt bloodline for the "One"(Lisan-al-Gaib), Missionaria Protectiva has their own purpose to spread the Propaganda of Kwisatz Haderach to farther planets. The Galaxies and Planets (Selusa Secundus, Geidi Prime and Caladan) are also in place. The magical ingredient, Spice found on Arrakis, The Guild, The Sardaurkar. It was great how Sandworms have a place in the Dune ecosystem and how it's linked to the creation of Spice in the Arrakis.</p>
<p>The Dune #1 Dune has three books/parts: Dune, Muad'dib and The Prophet. The first book talks about how Paul comes to Arrakis, the desert planet, How the Harkonnens plan treachery to kill Duke Leto. The second book shows us, how Paul takes sanctuary at the Fremen's and comes to be known as Paul Muad'dib and how Paul teaches the Fremen the weirding ways of battle and gets taught, how to live like a Fremen, ride a Maker. The Final Part talks, about how the Arrakis revolt plays and how Paul wins over the Arrakeen and plans to turn Arrakis into an orchard.</p>
<p>I absolutely loved reading <em>The Dune</em> 😍.</p>
]]></content:encoded></item><item><title><![CDATA[Running an express web server on Raspberry Pi]]></title><description><![CDATA[#2Articles1Week
This will be the second post of the raspberry pi series. You can check out the first one from here -
https://blog.saiyerniakhil.in/setting-up-raspberry-pi-to-run-a-web-server
 
If you remember from the previous article, we set up our ...]]></description><link>https://blog.saiyerniakhil.in/running-an-express-web-server-on-raspberry-pi</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/running-an-express-web-server-on-raspberry-pi</guid><category><![CDATA[Express]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[Raspberry Pi]]></category><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Sat, 01 May 2021 16:24:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1619885958767/7E-aAorje.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>#2Articles1Week</p>
<p>This will be the second post of the raspberry pi series. You can check out the first one from here -</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://blog.saiyerniakhil.in/setting-up-raspberry-pi-to-run-a-web-server">https://blog.saiyerniakhil.in/setting-up-raspberry-pi-to-run-a-web-server</a></div>
<p> </p>
<p>If you remember from the previous article, we set up our web server so that it can be accessed without having to connect the Pi to a computer. Now is the time to get down to business, which is setting up and running a webserver. You should use whatever stack you're most comfortable with, but in this case, I'm using a Node/Express.js API.</p>
<p>The PuTTY utility can be used to ssh into the Pi, but I'm using the ssh utility from the Linux running on <a target="_blank" href="https://docs.microsoft.com/en-us/windows/wsl/install-win10">WSL</a>. Run the below command the proceed by entering the password as prompted.</p>
<pre><code class="lang-plaintext"> ssh pi@raspberrypi
</code></pre>
<p>Run the commands below to update the Linux packages and also get the things we need</p>
<pre><code class="lang-plaintext">sudo apt update
sudo apt-get install vim
sudo apt-get install node.js
sudo apt-get install npm
</code></pre>
<p>Once that's done, we're ready to go, and we'll need to create a npm project to enable us to run a webserver on the Pi.</p>
<h4 id="heading-setting-up-an-express-server">Setting up an express server.</h4>
<pre><code class="lang-plaintext">mkdir code-hello-world &amp;&amp; cd code-hello-world
npm init -y
</code></pre>
<p>After the project is set up, install the <code>express</code> package and create an index.js file.</p>
<pre><code class="lang-plaintext">vim index.js
</code></pre>
<p>In that index.js, put in the following code, which is the JavaScript code to serve hello-world from the Pi.</p>
<pre><code class="lang-plaintext">const express = require('express')
const app = express()
const PORT = 3000

app.get("/", (req, res) =&gt; {
        res.status(200).send("&lt;h1&gt; Hello, World! &lt;/h1&gt;")
 })

app.listen(PORT, (req, res) =&gt; {
        console.log(`R_PI listening from port ${PORT}`)
})
</code></pre>
<p>Now everything's set up, the only thing that's remaining is to run the express.js server -</p>
<pre><code class="lang-plaintext">node index.js
</code></pre>
<p>You'll now have the server running on the Pi.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1619885371386/wubtpIWFZ.png" alt="image.png" /></p>
<p>Please do let me know how you felt about this post.</p>
<p>Thumbnail/Cover Photo by <a target="_blank" href="https://unsplash.com/@snowjam?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">John McArthur</a> on <a target="_blank" href="https://unsplash.com/s/photos/express?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></p>
]]></content:encoded></item><item><title><![CDATA[Setting up Raspberry pi to run a web server]]></title><description><![CDATA[#2Articles1Week
I was bored this weekend, so I searched my shelves and discovered an old Raspberry Pi Zero W (which I never got to use). So I decided to use it as a web server and host some applications on it. I'll take you through the process of set...]]></description><link>https://blog.saiyerniakhil.in/setting-up-raspberry-pi-to-run-a-web-server</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/setting-up-raspberry-pi-to-run-a-web-server</guid><category><![CDATA[Raspberry Pi]]></category><category><![CDATA[web servers]]></category><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Sat, 24 Apr 2021 16:19:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1619280858039/2ONKA9ThJ.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>#2Articles1Week</p>
<p>I was bored this weekend, so I searched my shelves and discovered an old Raspberry Pi Zero W (which I never got to use). So I decided to use it as a web server and host some applications on it. I'll take you through the process of setting in this blog post. This is the first in a two-part series.</p>
<h3 id="pre-requisites">Pre-requisites</h3>
<ul>
<li>A Raspberry Pi with Wifi ( I have a Raspberry Zero W) </li>
<li>An SD Card minimum of 8 GB</li>
<li>A micro USB cable (to Power up the Pi)</li>
<li>A computer with an internet connection.</li>
</ul>
<h3 id="installing-os-into-the-raspberry-pi">Installing OS into the Raspberry Pi</h3>
<p>You need to download a tool called Raspberry Imager from  <a target="_blank" href="https://www.raspberrypi.org/software/">here</a>. There is also a <a target="_blank" href="https://www.youtube.com/watch?v=ntaXWS8Lk34&amp;feature=youtu.be">45-sec</a> video to guide you through the setup from the official Raspberry Pi.</p>
<blockquote>
<p>So, now that you know how to install an OS, how do you pick one for the Pi? I'm going to use it as a web server, so the GUI isn't important to me. Instead of the full desktop version of the Raspberry Pi OS, I've installed the Lite version of it, which is a headless version of the operating system.</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1619268145329/WBKvYfv7C.png" alt="image.png" /></p>
<h3 id="connecting-to-pi">Connecting to Pi</h3>
<p>After the OS has been mounted on the SD card. Now is the time to insert the SD card into the Pi and configure the OS to enable us to use the Pi without a monitor. Connect the Pi to the laptop using a USB cable and insert the USB pin into the USB port. Do not unplug the Pi from the laptop yet.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1619273328317/M6TGbG_QW.png" alt="image.png" /></p>
<h4 id="things-to-do">Things to do -</h4>
<p>Make these changes in <code>config.txt</code>, add the line <code>dtoverlay=dwc2</code> at the end of the file (<a target="_blank" href="https://www.balena.io/docs/reference/OS/advanced/#setting-device-tree-overlays-dtoverlay-and-parameters-dtparam:~:text=The%20Raspberry%20Pi%20allows%20loading%20custom,bootloader%20will%20use%20all%20of%20them.">ref</a>).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1619269899512/hJl7BaIQE.png" alt="image.png" /></p>
<p>Change the <code>cmdline.txt</code> file add this small text <code>modules-load=dwc2,g_ether</code> in between as shown below. <code>dwc2</code> is an upstream driver which turns the pi into gadget mode, which can provide us with the ethernet over the USB connection and <code>g_ether</code> is a gadget driver, which will behave as USB over ethernet.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1619268595591/35SeoJQX8.png" alt="image.png" /></p>
<blockquote>
<p><strong>Tip</strong>: take a backup of <code>cmdline</code> and <code>config</code>, if in the process you mess up, you have a way to start fresh</p>
</blockquote>
<h4 id="enabling-ssh-ing-into-the-pi">Enabling SSH-ing into the Pi</h4>
<p>To be able to ssh, we need to put an empty ssh file(<strong>no extensions required</strong>). Keep in mind that it should have <strong>UNIX file endings</strong> if you are creating the file on a Windows PC. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1619270482645/1Hr8lYdhU.png" alt="image.png" />
Here is the ssh file I have created using Notepad++.</p>
<h4 id="connecting-to-a-wifi-network">Connecting to a Wifi network</h4>
<p>There is a way to make our Pi automatically connect to the Wifi network we specify. To do so, create a file called <code>wpa_supplicant.conf</code> and paste the contents provided below into it using <strong>Unix File endings</strong>. These UNIX file endings are causing me a lot of anxiety because I had to spend a lot of time finding out what went wrong.</p>
<pre><code>country=GB
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
scan_ssid=1
ssid=<span class="hljs-string">"&lt;Your Wifi Name&gt;"</span>
psk=<span class="hljs-string">"&lt;Your Wifi Password&gt;"</span>
}
</code></pre><h3 id="ssh-ing-into-the-pi">SSH-ing into the Pi</h3>
<h4 id="dont-unplug-the-pi-from-the-pc-yet"><strong>⚠ Don't Unplug the Pi from the PC yet! ⚠</strong></h4>
<p>Until now, the most intriguing thing is the steps following. Proceed to the next step using PuTTY or any other ssh client with <code>raspberrypi</code> (If an error occurs, use <code>raspberrypi.local</code> as the hostname). A terminal window appears, prompting us to enter the username which will be <code>pi</code> and the password will be <code>raspberry</code> . If it prompts you with a warning, press 'Yes' and continues.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1619271760037/k4zp_a-6k.png" alt="image.png" /></p>
<p>Update the packages, using <code>sudo apt update</code>.</p>
<p>Run sudo <code>raspi-config</code>, which will bring you to the menu shown below. We make two improvements here that are important for a server -</p>
<ol>
<li>Make the Pi auto-login whenever it boots up.</li>
<li>Make the Pi be ssh-able over wifi.</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1619272776894/FLY4sSjFY.png" alt="image.png" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1619272898240/vJl2qz0ki.png" alt="image.png" /></p>
<p>Your portable server is now ready! and you can now unplug the Pi from your PC. In the next part, I'll guide you through how to run a hello world app using express.js on the Pi.</p>
<h3 id="tips">Tips -</h3>
<ol>
<li>You can check if your raspberry Pi is able to connect to the Wifi, with help of a tool called <strong>Angry IP Scanner</strong>. And you'll find the hostname <code>raspberrypi</code> in the list generated.</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1619273634767/Mo6m52Fuk.png" alt="image.png" /></p>
<p>Cover Image credits: Me 😀</p>
]]></content:encoded></item><item><title><![CDATA[Creating an app to help send your friends a self-destructing message - PART 2]]></title><description><![CDATA[This is part 2 of the article, if you haven't been through the first part yet, here is the link to it - 
https://saiyerniakhil.tech/creating-an-app-to-help-send-your-friends-a-self-destructing-message-1
In part 1, we have built our backend part of th...]]></description><link>https://blog.saiyerniakhil.in/creating-an-app-to-help-send-your-friends-a-self-destructing-message-2</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/creating-an-app-to-help-send-your-friends-a-self-destructing-message-2</guid><category><![CDATA[React]]></category><category><![CDATA[ReactHooks]]></category><category><![CDATA[react router]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Wed, 24 Mar 2021 10:24:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1616580577126/DMkzv_L2m.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is part 2 of the article, if you haven't been through the first part yet, here is the link to it - </p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://saiyerniakhil.tech/creating-an-app-to-help-send-your-friends-a-self-destructing-message-1">https://saiyerniakhil.tech/creating-an-app-to-help-send-your-friends-a-self-destructing-message-1</a></div>
<p>In part 1, we have built our backend part of the application, now here we are with building the frontend part and conclude the application development.</p>
<p>I am using ReactJS for the frontend and bootstrap as the CSS framework. I have used the codesandbox in the initial development of my application. </p>
<p>My Directory structure of the react application is as follows - </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1616577820560/ZaJ7nZaMb.png" alt="Code_Xls06zk4Kg.png" /></p>
<p>I have divided my react folders into components, pages, assets each component inside components and pages has <code>__tests__</code>  folder which contains the unit test and integration tests.</p>
<ol>
<li><code>components</code> contains the smallest possible react components which are re-used throughout the react application</li>
<li><code>pages</code> contains the combination of react components, which together form a single page. Since I'm using React Router in the application, it becomes more meaningful for the pages folder.</li>
<li><code>assets</code> folder contains the static files like images, SVGs etc.</li>
<li><code>App.js</code> is the root element of the component tree of the application.</li>
</ol>
<p>The current application, which is built using react-router, has two different routes in actual -</p>
<ul>
<li><code>/</code> - points to the HomePage</li>
<li><code>/result/:uuid</code> - points to the BufferPage</li>
</ul>
<p>While the homepage route is pretty straight forward but BufferPage isn't which I'll discuss in a moment.</p>
<p>The HomePage route renders the <code>HomePage</code> component in the pages directory. All the routes and pages contain the Header, Footer and conditionally rendered HeroImage component in general. the HomePage is where the user fills out the form to persist the message and set the expiry date into the database. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1616578872428/PN_GKKmlt.png" alt="Screenshot_2021-03-24 React App.png" />
<em>The homepage</em></p>
<p>When the user successfully submits a message to store it, he'll be provided with a message giving him the link to the message to access it. the user also can copy the link by clicking the copy button.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1616579200222/0A-mCwBu5.png" alt="chrome_XmZnUwwO9c.png" /></p>
<p>The form's submit button will remain disabled until a valid input is provided and also while the request payload is being sent to the server. The user has also been provided with instruction on how the application works.</p>
<p>The next route is <code>BufferPage</code>. This page's route accepts the UUID of the message, as we have seen earlier on the homepage the user is provided with a route <code>&lt;application-domain&gt;/result/&lt;uuid&gt;</code> so the BufferPage picks up that UUID from the params and does a fetch call to the server at <code>/retrieve/:uuid</code> endpoint. Based on the result, the user will then be redirected to either a success page, which contains the message, the expiry date and on failure, the page redirects to the error page, which then tells the user that the message has been expired or it is not present in the database and also has an option to reach the homepage.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1616579860569/k2IXeT4k5.png" alt="Screenshot_2021-03-24 React App(1).png" />
<em>The success page</em></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1616579941632/TotLILZz2.png" alt="Screenshot_2021-03-24 React App(2).png" />
<em>The error page</em></p>
<p>The entire application is also responsive for mobile devices.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1616580481158/v0SBFbr9k.png" alt="collage.png" /></p>
<p>The application is hosted at - <a target="_blank" href="https://short-url-gen.netlify.app/">short-url-gen.netlify.app</a></p>
<p>Illustration credits - <a target="_blank" href="https://undraw.co/">undraw.co</a></p>
]]></content:encoded></item><item><title><![CDATA[Creating an app to help send your friends a self-destructing message - PART 1]]></title><description><![CDATA[So looking at the problem, rather than diving straight into the "how" part, let's look at the problem with the 4 W thinking lenses ( Why, Where, What  and Who ) this helps us arrive at the optimum solution. In our case, the What part is - creating an...]]></description><link>https://blog.saiyerniakhil.in/creating-an-app-to-help-send-your-friends-a-self-destructing-message-1</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/creating-an-app-to-help-send-your-friends-a-self-destructing-message-1</guid><category><![CDATA[MERN Stack]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[Express]]></category><category><![CDATA[React]]></category><category><![CDATA[MongoDB]]></category><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Wed, 24 Mar 2021 06:58:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1616568660537/b_WvsMrJZ.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>So looking at the problem, rather than diving straight into the "how" part, let's look at the problem with the 4 W thinking lenses ( <em>Why, Where, What</em>  and <em>Who</em> ) this helps us arrive at the optimum solution. In our case, the <em>What</em> part is - creating an app that allows us to send our friends things like youtube links or some secret stuff, that expires after a certain time, the <em>Why</em> part - we usually share with our friends the usual memes, trending Youtube/Instagram videos and the messages we share don't need to be stored permanently and we won't be revisiting that anytime, so there needs to be a way to store them temporarily. Thus we arrived at this solution. The <em>Who</em> part will be our friends, colleagues, or anyone who has access to the internet. </p>
<p>Now diving into the <em>How</em> part, starting with the backend part of the application, we are gonna design it starting with the actions users might perform.</p>
<ol>
<li>The user enters a message he wishes to send, sets an expiry date/time.</li>
<li>The user then gets back his message, which the user can use to share.</li>
</ol>
<p>So to build the backend of the application, I'm gonna use node.js with Express.js, and MongoDB.</p>
<h4 id="setting-up-an-expressjs-app">Setting up an Express.js app</h4>
<pre><code>cd &lt;project-name&gt;
<span class="hljs-built_in">npm</span> init
<span class="hljs-built_in">npm</span> install express
</code></pre><p>Give the author's name and all the fields when prompted as you wish, during the setup.</p>
<p>The utilities are added to the Express app as middlewares. So have used quite a several middlewares while building the application.</p>
<h4 id="starting-the-server">Starting the server</h4>
<p>/index.js</p>
<pre><code><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>)

<span class="hljs-keyword">const</span> app = express()
app.use(express.json())
app.use(express.urlencoded({ <span class="hljs-attr">extended</span>: <span class="hljs-literal">false</span> }));

<span class="hljs-keyword">const</span> PORT = <span class="hljs-number">8082</span>

app.get(<span class="hljs-string">"/"</span>, <span class="hljs-function">(<span class="hljs-params">req,res</span>) =&gt;</span> {
    <span class="hljs-keyword">return</span> res.send(<span class="hljs-string">"Hello, World"</span>)
})

app.listen(process.env.PORT || PORT, <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Backend is running on port <span class="hljs-subst">${process.env.PORT || PORT}</span>`</span>)
})
</code></pre><p>The line <code>app.use(express.json())</code>, is a middleware used to tidy up the request payloads we get from the user to be able to use them with JavaScript. The line <code>app.use(express.urlencoded({}))</code> is an option to choose how to parse the incoming request object (<code>qs</code> or <code>querystring</code>). More details at <a target="_blank" href="https://github.com/expressjs/body-parser#extended">here</a>.</p>
<p>I'm now done with the initial setup, now going into the actual development based on the points we have listed above. The first task being, get the data from the user then store it inside our database. So, for that, we need a POST method, which takes the data from the user through a form. Since we haven't had our front-end form ready, I'm going to use a tool called <strong>Postman</strong> which is a tool used to interact and test APIs. The endpoints in the Express are termed as called routes.</p>
<h4 id="setting-up-the-mongodb-client">Setting up the MongoDB client</h4>
<p>There is good support for MongoDB in node.js and so there are several libraries available. So I have used the official native driver provided by MongoDB. </p>
<p>/index.js</p>
<pre><code>...
<span class="hljs-keyword">const</span> MongoClient = <span class="hljs-built_in">require</span>(<span class="hljs-string">'mongodb'</span>).MongoClient
<span class="hljs-keyword">const</span> DB_USERNAME = process.env.DB_USERNAME
<span class="hljs-keyword">const</span> DB_PASSWORD = process.env.DB_PASSWORD
<span class="hljs-keyword">const</span> DB_NAME = process.env.DB_NAME
<span class="hljs-keyword">const</span> DATABASE_URL = <span class="hljs-string">`mongodb+srv://<span class="hljs-subst">${DB_USERNAME}</span>:<span class="hljs-subst">${DB_PASSWORD}</span>@cluster0.yqxu2.mongodb.net/<span class="hljs-subst">${DB_NAME}</span>?retryWrites=true&amp;w=majority`</span>
MongoClient.connect(DATABASE_URL,{useUnifiedTopology: <span class="hljs-literal">true</span>})
.then(<span class="hljs-function">(<span class="hljs-params">client</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> db = client.db(DB_NAME)
    <span class="hljs-keyword">const</span> messagesCollection = db.collection(<span class="hljs-string">'newCollection'</span>)
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Connected to the Database - SUCCESS!'</span>)
    ...
}).catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> {
    ...
)}

...
</code></pre><p>The client object we got in the then(...) part of the promise is what is needed for us to interact with the Mongo server. Hence all the logic and routes involving the database comes in it.</p>
<p>I have hosted my database on MongoDB atlas. To store all the database credentials, I have used a utility called <code>dotenv</code>, I have created a <code>.env</code> to store all my credentials as key-value pairs separated with an <code>=</code>. Storing credentials as a const in the js files is a bad practice, as others viewing your files will get to know your credentials.</p>
<h4 id="the-post-method">The POST method</h4>
<p>route - /add</p>
<p>/index.js</p>
<pre><code>...
app.post(<span class="hljs-string">"/add"</span>,<span class="hljs-function">(<span class="hljs-params">req,res</span>) =&gt;</span> {
        <span class="hljs-keyword">const</span> uuid = nanoid(<span class="hljs-number">7</span>)
        <span class="hljs-keyword">const</span> insertDate = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>() 
        <span class="hljs-keyword">const</span> millisSecondsFromNow = req.body.time * <span class="hljs-number">1000</span>
        <span class="hljs-keyword">const</span> expireAt = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(insertDate.getTime() + millisSecondsFromNow)
        <span class="hljs-keyword">const</span> newMessageDocument = {...req.body, expireAt, insertDate, <span class="hljs-attr">_id</span>: uuid}
        messagesCollection.insertOne(newMessageDocument)
        .then(<span class="hljs-function"><span class="hljs-params">result</span> =&gt;</span> {
            <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">201</span>).send({ <span class="hljs-attr">uniqueUrl</span> : uuid, expireAt})
        }).catch(<span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> {
            <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">503</span>).send(error)
        })
    })
...
</code></pre><p>The task associated with this endpoint is to store this in the database, which is creating a resource, hence the use of the POST method. To create a unique field, to access the document, I have here used a library called nanoid which gives the UUID of a specified length (here 7). I am getting the time after which the message should be expired in seconds from the time of creation and then I increment the current time with the seconds from the user to arrive at the expiry date. Thereafter I insert them into my collection in the database and respond to the user with apt response codes. You can know more about HTTP response codes - <a target="_blank" href="https://www.restapitutorial.com/httpstatuscodes.html">here</a>.</p>
<p>While we move into the next part of the application. I will quickly dive into the database design of our database and how we achieved the timely deletion of the records after a specified time?</p>
<p>The only data we need to store is the message, the insert date, the expiry date and the time active (in seconds). hence a sample document of the data would be like - </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1616565161369/3ZaHXxXXY.png" alt="chrome_QMmPV2wUag.png" /></p>
<p>The time given is 10000 seconds which is equal to around 2.77 hours. hence, the field <code>expireAt</code> is 2.77 hours from the <code>insertDate</code>. </p>
<p>How do we test if that's working fine? Using postman!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1616565991403/DJmDh3XS6.jpeg" alt="Postman_uFbO79XIub_LI.jpg" /></p>
<p>We can select the type of request from the dropdown on the left of the address bar. Now its POST and the endpoint <code>/add</code> in the address bar. We can now see the request body with two fields from the user, message and time. And down below we get to see the response from the server, which has <code>uniqueURL</code> which I'll discuss going forward and the time at which the message expires.</p>
<h4 id="how-did-we-achieve-timely-self-destruction">How did we achieve, timely self-destruction?</h4>
<p>Coming to the MongoDB server, it has a background thread <code>mongod</code> (mongo daemon) which always runs in the server. There's a feature in MongoDB called, Time-to-Live (TTL), the <code>mongod</code> thread always runs and checks to delete the documents at a trigger time. It can be the same time for all the records or the column specifying the delete time. How to add this check to our database collection?</p>
<p><code>db.&lt;collection_name&gt;.createIndex({expireAfterSeconds: 3200})</code> - adding this makes the records to auto-delete after 3200 seconds
but we need different units of time (minutes, seconds, hours or even days) hence I create an index <code>expireAt</code> the time after which I intend to delete the document after. Using this - <code>db.&lt;collection_name&gt;.createIndex( {"expireAt": 1}, {expireAfterSeconds: 0} )</code>. You can know more about the feature at <a target="_blank" href="https://docs.mongodb.com/manual/tutorial/expire-data/">here</a>.</p>
<p>Going to the next part of our solution, which is the user getting back his message from the database.</p>
<h4 id="the-get-method">The GET method</h4>
<p>route - <code>/retrieve/:uuid</code></p>
<p>/index.js</p>
<pre><code>...
MongoClient.connect(DATABASE_URL,{<span class="hljs-attr">useUnifiedTopology</span>: <span class="hljs-literal">true</span>})
.then(<span class="hljs-function">(<span class="hljs-params">client</span>) =&gt;</span> {
...
app.post(<span class="hljs-string">"/add"</span>,<span class="hljs-function">(<span class="hljs-params">req,res</span>) =&gt;</span> {
...
})

app.get(<span class="hljs-string">"/retrieve/:uuid"</span>,<span class="hljs-function">(<span class="hljs-params">req,res</span>) =&gt;</span> {
        <span class="hljs-keyword">const</span> uuid = req.params.uuid
        messagesCollection.findOne({<span class="hljs-attr">_id</span>: uuid})
        .then(<span class="hljs-function"><span class="hljs-params">result</span> =&gt;</span> {
            <span class="hljs-keyword">if</span> (result === <span class="hljs-literal">null</span>) {
                <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">404</span>).end()
            }
            <span class="hljs-keyword">else</span>
                <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">302</span>).send(result)
        }).catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> {
            <span class="hljs-built_in">console</span>.log(err)
            <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">503</span>).send(error)
        })
    })

...
</code></pre><p>In this part we are accessing a record from the database neither creating nor updating, hence we have used the GET method. How do we access the particular record? If we are in a Relational Database, we use a primary key, At present, we have a similar index in our collection called the <code>_id</code>, which is the UUID generated by <code>nanoid</code>. We get this UUID from the user and our server responds accordingly if its found then return the document else return null with apt response codes. </p>
<h5 id="testing-the-endpoint-in-postman">Testing the endpoint in postman</h5>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1616567817153/OSRhXRnR0.png" alt="Postman_ULh0Vm5DIJ.png" /></p>
<p>In the address bar, we see the <code>retrieve/</code> suffixed by the UUID we got previously. And we got the response from the server, all the details of the message like (<em>_id, expireAt, insertDate, message and time</em>) </p>
<p>Now all the tasks we intended after the analysis are done and we now got the working version of the backend with us.</p>
<p>You can find the source code at -  <a target="_blank" href="https://github.com/saiyerniakhil/url-generator-backend">github.com/saiyerniakhil</a>.
The final application is hosted at - <a target="_blank" href="https://short-url-gen.netlify.app/">https://short-url-gen.netlify.app/</a></p>
<p>The link to the second part of the article - </p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://saiyerniakhil.tech/creating-an-app-to-help-send-your-friends-a-self-destructing-message-2">https://saiyerniakhil.tech/creating-an-app-to-help-send-your-friends-a-self-destructing-message-2</a></div>
]]></content:encoded></item><item><title><![CDATA[Go, Git it! — Beginner’s guide to making your first commit.]]></title><description><![CDATA[Before getting to know what is Git, we need to know what are version control systems. They are the code management tools which allow us to maintain different versions of the code in a non-clumsy way. When I was starting to code and create websites I ...]]></description><link>https://blog.saiyerniakhil.in/go-git-it-beginners-guide-to-making-your-first-commit-6c9eb9014064</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/go-git-it-beginners-guide-to-making-your-first-commit-6c9eb9014064</guid><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Fri, 04 Oct 2019 08:02:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567985808/78o3jdXE6.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Before getting to know what is Git, we need to know what are version control systems. They are the code management tools which allow us to maintain different versions of the code in a non-clumsy way. When I was starting to code and create websites I used to make copies of the folders like this —</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567968350/sNo197Opl.png" alt="Haha! it’s funny" /><em>Haha! it’s funny</em></p>
<p>It seemed okay then. But, When I have to deal with more and more complex projects I felt difficult to move on and often confused. But its when version control tools like Git looked like a saviour to me. Why? let’s check it out.</p>
<ul>
<li><p>Cleaner project directories.</p>
</li>
<li><p>Ability to rollback.</p>
</li>
<li><p>Maintain different versions of the code (branches)</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567970545/GkiTCkWxY.png" alt="Git logo" /><em>Git logo</em></p>
<p>Installing git isn’t a tedious task and you can find the detailed guide <a target="_blank" href="https://git-scm.com/book/en/v2/Getting-Started-Installing-Git">here</a>.</p>
<p>So, while we are learning about git there are certain terms which are important that we understand and we come across them every time — </p>
<ul>
<li>Repository</li>
<li>Commit</li>
<li>Branch</li>
</ul>
<h2 id="what-is-a-repository">What is a repository?</h2>
<p>A repository (or a repo) is a parent folder which the git tracks, which may be the directory which contains the project files. In case of a web app, the repository contains all the Html files documents, stylesheets and images which are used in the web app.</p>
<blockquote>
<p><strong>How to create a repository?
</strong>Creating a repository is very easy, you can intialize an empty repository or turn an existing project into git repository or else move to the existing project repo and use the command <strong>*git init </strong>using<strong> </strong>git<strong> </strong>command line tool.*</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567972760/Tuf0do37K.png" alt="initializing a repository" /><em>initializing a repository</em></p>
<h2 id="now-what-is-a-commit">Now, What is a commit?</h2>
<p>A commit is a checkpoint. Let us say you have initially created a web app and then made changes to the initial version. Now you’ve made a blunder and messed with the project and wanted to revert to the initial version, with the help of a commit. Commits are checkpoints, as mentioned before and we can come back to it.</p>
<blockquote>
<p><strong>How to make commits? 
</strong>Here it is, this is how we make a commit — 
<strong>git commit</strong>
Before we make a commit we need to stage the changes. Staging changes helps us to commit all the files at once without fail. We can stage all the files at once or we can a single file using — 
<strong>git add .</strong> or <strong>git add &lt;filename&gt;</strong>
while comitting we need to specify a commit which briefly describes the changes. So we generally use a message flag <strong>-m </strong>directly in the command-
<strong><em>git commit -m “&lt;commit message&gt;”</em></strong>
<em>each commit i.e., each checkpoints has it own id.</em></p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567974401/Vym_PzqvS.png" alt="The initial version of file random.txt" /><em>The initial version of file random.txt</em></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567975865/1Hueel4eE.png" alt="Staging and committing the files in the repository" /><em>Staging and committing the files in the repository</em></p>
<blockquote>
<p>Now making a second commit</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567977471/nfWwX28hs.png" alt="Staging and making a second commit" /><em>Staging and making a second commit</em></p>
<blockquote>
<p><strong>How do we revert?
</strong>We can revert using the commit specifying the commit ID
<strong><em>git checkout &lt;commit-id&gt;</em></strong></p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567979065/R6rSckkux.png" alt /></p>
<blockquote>
<p>When we go on with the software development we need have a look at the commits. For that we’ll be using the command — 
<strong>*git log
</strong>which is a pretty useful command.*</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567980731/3Q5xOzIEf.png" alt /></p>
<h2 id="what-are-the-branches">What are the branches?</h2>
<p>When we want to test new features in our software without actually disturbing the original version. We use branches for that very reason.</p>
<blockquote>
<p><strong>How do we create branches?
</strong>Branches are creating by using same command we used in earlier by using a<strong> -b </strong>flag.
<strong><em>git checkout -b &lt;new-branch-name&gt;</em></strong></p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567982410/ao3BAXFog.png" alt /></p>
<blockquote>
<p>Now have a look at the same file in two distinct branches and you’ll clearly know why we use branches —</p>
</blockquote>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567984086/wXGKQTc6d.png" alt /></p>
<blockquote>
<p><strong>How to delete a branch?
</strong>A branch can be deleted by specifying a<strong> -d </strong>flag
<strong><em>git checkout -d &lt;branch-name&gt;</em></strong></p>
</blockquote>
<p>Now that we are clear with the terms used in Git. In the next post, we’ll learn how to host it on the internet.</p>
<p>Do share and suggest some improvements.</p>
]]></content:encoded></item><item><title><![CDATA[Flask — from development to deployment in 15 minutes]]></title><description><![CDATA[A brief guide to develop a basic flask app and deploying it into Heroku cloud.
Flask is a micro framework written in Python…blah…blah..blah! I’m not gonna waste you time so, more info at flask.pocoo.org!
Developing a Flask app

Install flask through ...]]></description><link>https://blog.saiyerniakhil.in/flask-from-development-to-deployment-in-15-minutes-85010a0765ce</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/flask-from-development-to-deployment-in-15-minutes-85010a0765ce</guid><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Mon, 04 Mar 2019 04:51:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1615568001094/xssTwWEgf.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A brief guide to develop a basic flask app and deploying it into Heroku cloud.</p>
<p>Flask is a micro framework written in Python…blah…blah..blah! I’m not gonna waste you time so, more info at <a target="_blank" href="http://flask.pocoo.org/">flask.pocoo.org!</a></p>
<h2 id="developing-a-flask-app">Developing a Flask app</h2>
<ul>
<li>Install flask through <strong>pip </strong>using —</li>
</ul>
<pre><code><span class="hljs-attribute">pip</span> install flask
</code></pre><ul>
<li>Running a sample “Hello World!” flask web app</li>
</ul>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask

app = Flask(__name__)

<span class="hljs-meta">@app.route("/")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">hello</span>():</span>
  <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello, World!"</span>
</code></pre>
<p>Running a flask app is just <code>flask run</code>away, just head over to your app location in your command prompt/bash/terminal.</p>
<pre><code>C:/[<span class="hljs-type">Path</span> /<span class="hljs-keyword">to</span> your/ app/]&gt;flask run
</code></pre><p>When you make some changes to your app, you should run flask run again by quitting.</p>
<blockquote>
<p>Debug mode is a very useful tool while you’re developing an app and you are in need of frequent reloads. 
Here’s what you can do in your cmd to activate debug mode in Windows 
<strong>set FLASK_ENV=development</strong></p>
</blockquote>
<p>Now you can see the following on your cmd —</p>
<pre><code><span class="hljs-bullet">*</span> Environment: production
 WARNING: Do not use the development server in a production environment.
 Use a production WSGI server instead.
<span class="hljs-bullet"> *</span> Debug mode: off
<span class="hljs-bullet"> *</span> Running on [<span class="hljs-string">http://127.0.0.1:5000/</span>](<span class="hljs-link">http://127.0.0.1:5000/</span>) (Press CTRL+C to quit)
</code></pre><p>The above app generates some content in the browser which looks like this —</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567991465/2UFydFH7C.png" alt="A Hello World" /><em>A Hello World</em></p>
<p>Now, Let us know what each line in the above code works or does the things</p>
<pre><code><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask
</code></pre><p>More about “Flask” at <a target="_blank" href="http://flask.pocoo.org/docs/1.0/api/#flask.Flask">here</a>.</p>
<p>The 3rd line in the code creates an instance of our <a target="_blank" href="https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface">WSGI</a> Application.</p>
<p>If you have ever noticed your address bar while visiting websites like Wikipedia, Instagram, Reddit etc., you should have noticed this</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567993125/qGIEGNcWF.png" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567994835/6i4q-4nyc.png" alt /></p>
<p>In the first image there’s Instagram’s default route. It is always showed up when you navigate to <a target="_blank" href="http://instagram.com">instagram.com</a>. The default route is a “/” (forward slash)</p>
<p>In the second image, when you want to navigate to specific Instagram profile then you need to give the specify like “&lt;username&gt;” after the default route like “/sachintendulkar” for viewing <a target="_blank" href="http://instagram.com/sachintendulkar">Sachin Tendulkar</a>’s Instagram profile.</p>
<p>The function below the route serves the content to be displayed or served for that route.So that we’re clear how routes work. We can now start adding routes for our web app.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask

app = Flask(__name__)

<span class="hljs-meta">@app.route("/")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">hello</span>():</span>
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Hello World!"</span>

<span class="hljs-meta">@app.route("/first")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">first</span>():</span>
    <span class="hljs-keyword">return</span> <span class="hljs-string">"The First Route"</span>
</code></pre>
<p>Which results in this —</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567996506/_jUL8YsgE.png" alt="The First Route" /><em>The First Route</em></p>
<p>Its achieves our purpose of adding routes but, is that what an actual web app look like? No! There a no HTML pages and no anchor tags and nothing in there. But do not panic we’ll now be dealing with rendering HTML pages rather than generating a simple plain text. For that we need to import a function <code>render_template</code> from flask.</p>
<blockquote>
<p>All the HTML files to be served via <code>render_template</code>should be placed in a folder named <strong>templates</strong> inside your working directory</p>
</blockquote>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask,render_template

app = Flask(__name__)

<span class="hljs-meta">@app.route("/")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">hello</span>():</span>
    <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"index.html"</span>)

<span class="hljs-meta">@app.route("/first")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">first</span>():</span>
    <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"first.html"</span>)
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>My Web App<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>This is the first route<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span>&gt;</span>back<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>My Web App<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello, World!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/first"</span>&gt;</span>first<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The navigation functions as —</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567997984/JQMXouwuc.png" alt /></p>
<h2 id="deploying-the-flask-app-to-heroku-cloud">Deploying the Flask app to Heroku Cloud</h2>
<p>Now that the basic app is ready and now its time for deployment. We are now going to deploy it to Heroku Cloud. Why Heroku? It offers a command line interface for configuring and deploying python or any web app with version controlling, which makes it easier to track your files and versions of your web app.</p>
<p>For starting with Heroku you need to create a Heroku account and install Heroku CLI in your local computer. You can download it <a target="_blank" href="https://devcenter.heroku.com/articles/heroku-cli">here</a></p>
<blockquote>
<p>For you to use Heroku, you need to install and configure git. Steps to install git can be found here — <a target="_blank" href="https://git-scm.com/book/en/v2/Getting-Started-Installing-Git">https://git-scm.com/book/en/v2/Getting-Started-Installing-Git</a></p>
</blockquote>
<ul>
<li><p>After installing Heroku CLI, now use the <code>heroku login</code>command to connect your Heroku account to the CLI in your local computer.</p>
</li>
<li><p>Install a python package <code>gunicorn</code> by <code>pip install gunicorn</code> . (<a target="_blank" href="https://en.wikipedia.org/wiki/Gunicorn">Wikipedia</a>)</p>
</li>
<li><p>Its time to create a <strong>Procfile, </strong>which tells the Heroku cloud which server our web app runs on. The Procfile contents for our web app looks like —</p>
</li>
</ul>
<pre><code><span class="hljs-attribute">web</span>: gunicorn <span class="hljs-attribute">app</span>:app
</code></pre><ul>
<li><p>Now move over to the working directory in the command prompt and generate a <code>requirements.txt</code> file which tells about the package dependencies for our web app by running <code>pip freeze requirements.txt</code></p>
</li>
<li><p>Now initialize a git repository in the current working directory <code>git init</code> .</p>
<blockquote>
<p>adding a .gitignore file is an optional</p>
</blockquote>
</li>
<li><p>Next, stage and commit all changes <code>git add .</code> and <code>git commit -m 'first commit'</code> .</p>
</li>
<li><p>Create a Heroku app <code>heroku create</code></p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567999531/IfGzE1esX.png" alt="The result of **heroku create** command" /><em>The result of <strong>heroku create</strong> command</em></p>
<ul>
<li><p>Let us push all the contents of our repository into the Heroku cloud by <code>git push heroku master</code> .Its takes some time for the cloud to be configured for our app to be run.</p>
</li>
<li><p><code>heroku open</code> to open your web app in your browser.</p>
</li>
</ul>
<p>Its done! you’ve now created a basic flask app and deployed it to Heroku cloud.</p>
<p>The app I’ve created is now live at <a target="_blank" href="https://safe-waters-62537.herokuapp.com/">https://safe-waters-62537.herokuapp.com/</a></p>
<p>Now that you’ve got an idea about developing and deploying basic flask application. You can continue to build some advanced flask applications by learning at <a target="_blank" href="https://www.edx.org/course/cs50s-web-programming-with-python-and-javascript">Edx</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Setting up Anaconda Environment with Visual Studio Code in Windows 10]]></title><description><![CDATA[As a part of TalentAccurate’s python-75-challenge remote hackathon Anaconda Environment setup is very much needed. So, to get started with setting up Anaconda environment and complementing it with Visual Studio Code, follow the below steps -

Install...]]></description><link>https://blog.saiyerniakhil.in/setting-up-anaconda-environment-with-visual-studio-code-in-windows-10-ac3f9afd80e0</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/setting-up-anaconda-environment-with-visual-studio-code-in-windows-10-ac3f9afd80e0</guid><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Fri, 14 Dec 2018 06:03:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1615568022949/HAS5Om9lA.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As a part of TalentAccurate’s python-75-challenge remote hackathon Anaconda Environment setup is very much needed. So, to get started with setting up Anaconda environment and complementing it with Visual Studio Code, follow the below steps -</p>
<ul>
<li><p>Install Anaconda from <a target="_blank" href="https://www.anaconda.com/download/">Here</a> .</p>
</li>
<li><p>After you complete installing Anaconda, Open Anaconda Navigator (In windows, you can simply do that by searching for it in the start menu).</p>
</li>
<li><p>In the Anaconda Navigator, you could easily find an <strong>Environment </strong>tab in the side navigation bar, open it and you can find a create option to the bottom left click on it and head over to next step.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615568011519/O0e5XGi0j.png" alt /></p>
<ul>
<li>When you click on create a small alert pops up, enter a environment name of your choice (for <strong>example</strong>, py36 ). Please do make note of the location of your environment which is just below the text box.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615568013253/xh-XWROhP.png" alt="create new environment pop-up" /><em>create new environment pop-up</em></p>
<ul>
<li><p>Head over to the location of your environment which you have noted down. (which is of the form C:/Users/…. in windows)</p>
</li>
<li><p>Open <strong>edit system environment variables </strong>from start menu and and a new window appears then click on <strong>Environment variables &gt; System Variables </strong>then you could find a variable named <strong>path </strong>. Click on edit and add new path to it and paste the location of your Anaconda Environment.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615568014762/AK_4bLH2Z.png" alt="searching edit system system environment variables" /><em>searching edit system system environment variables</em></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615568016334/ktAn8K1CN.png" alt="clicking on edit will lead you to the below window" /><em>clicking on edit will lead you to the below window</em></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615568017907/UfjT8K9C7.png" alt="click on new and paste your anaconda environment location" /><em>click on new and paste your anaconda environment location</em></p>
<ul>
<li>Now open your Python project folder in Visual Studio Code, and to the bottom left corner you can find something like this</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615568019338/-oAI1Pj77.png" alt="click on the highlighted one and it’ll lead you to the below one" /><em>click on the highlighted one and it’ll lead you to the below one</em></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615568020814/utpQpTk-z.png" alt="you can now see your python interpreters (in my case it’s the **second one **~\Anaconda3\envs\py36\python.exe) where py36 is my environment name." /><em>you can now see your python interpreters (in my case it’s the <strong>second one </strong>~\Anaconda3\envs\py36\python.exe) where py36 is my environment name.</em></p>
]]></content:encoded></item><item><title><![CDATA[Mozilla Firefox for geeks :V]]></title><description><![CDATA[Long ago I’ve been a Google fan boy (even now)and an avid user of Google Chrome. But then came the new Mozilla Firefox Quantum. I have a habit of trying every piece of software alternatives and check which ones better and tried out Opera, Avant, Rock...]]></description><link>https://blog.saiyerniakhil.in/mozilla-firefox-for-geeks-v-aec7a218ea12</link><guid isPermaLink="true">https://blog.saiyerniakhil.in/mozilla-firefox-for-geeks-v-aec7a218ea12</guid><dc:creator><![CDATA[Sai Yerni Akhil Madabattula]]></dc:creator><pubDate>Sat, 01 Sep 2018 18:49:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567962891/n9FYOcy3A.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Long ago I’ve been a Google fan boy (even now)and an avid user of Google Chrome. But then came the new Mozilla Firefox Quantum. I have a habit of trying every piece of software alternatives and check which ones better and tried out Opera, Avant, Rockmelt (which is pretty old I guess) and even Microsoft’s Edge too. At the beginning there’s a problem moving from a complete Google’s environment to another environment which is completely different. Moving on has been much easy compared to others. There are some reasons why I really loved Firefox -</p>
<p>The new Firefox Quantum is built on Rust programming language, sponsored by Mozilla which means more power to Mozilla in making Firefox more powerful.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567949630/RYTuXo9R6.png" alt /></p>
<p>I’m into web development for some time and I’ve loved using Firefox’s DevTools which is lightweight when compared to Chrome’s.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567951700/veKAfPZcV.png" alt="A look at Firefox’s DevTools" /><em>A look at Firefox’s DevTools</em></p>
<p>It also had an interesting feature called Firefox Test Pilot which is a beta program for trying out cool new features (I have an unconditional love towards beta testing new products). The test pilot program really awes me.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567953744/BO5au3rYP.png" alt="A look at Firefox Test Pilot" /><em>A look at Firefox Test Pilot</em></p>
<p>A universal address bar — Yes you’ve heard it right. The address bar is not only limited to your default search engine but also several and you can add your custom search engine</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567956119/Bzc5w9YHH.png" alt="To search using duckduckgo just @duckduckgo and add your search query beside it" /><em>To search using duckduckgo just @duckduckgo and add your search query beside it</em></p>
<p>Built in tracking protection, yeah and its true.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567957667/IfGCl_5tM.png" alt="tracking protection is built into the browser" /><em>tracking protection is built into the browser</em></p>
<p>Coming to add-ons, I know that, by redesigning Firefox, Mozilla had to dump many add-ons, but believe me — more add-ons are being added.</p>
<p>Built in screenshot tool — for a power user like me taking screenshots has been made easier by tools like ShareX but the Firefox’s screenshot tool is built for webpages.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1615567960169/_Pa071ZpE.png" alt="Take a screenshot of a selective region without having it to be cropped." /><em>Take a screenshot of a selective region without having it to be cropped.</em></p>
<p>There are many other features besides them but I felt these were the cool ones.</p>
<p>This is my first post and I’m getting started. Hope you liked it ❤️</p>
]]></content:encoded></item></channel></rss>