<?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[Siddhesh's Tech Bytes]]></title><description><![CDATA[I am a Computer Science and Math enthusiast. I am interested in Backend Development, Machine Learning, Natural Language Processing, Generative AI and Cybersecurity. I like building tools.]]></description><link>https://blog.siddhesh.cc</link><generator>RSS for Node</generator><lastBuildDate>Sun, 10 May 2026 01:06:25 GMT</lastBuildDate><atom:link href="https://blog.siddhesh.cc/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Learning CSS with games]]></title><description><![CDATA[Some topics in CSS are more easier to understand by experience then they are by reading docs/blogs. Here are some games that helped me understand these topics better:
CSS

CSS Challenges - https://css-challenges.com/

CSS Speedrun - https://css-speed...]]></description><link>https://blog.siddhesh.cc/learning-css-with-games</link><guid isPermaLink="true">https://blog.siddhesh.cc/learning-css-with-games</guid><category><![CDATA[CSS]]></category><category><![CDATA[CSS3]]></category><category><![CDATA[Games]]></category><dc:creator><![CDATA[Siddhesh Agarwal]]></dc:creator><pubDate>Sat, 24 Jan 2026 12:54:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1769259214391/9792127f-d133-45ef-9f91-8289f1b32d05.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Some topics in CSS are more easier to understand by experience then they are by reading docs/blogs. Here are some games that helped me understand these topics better:</p>
<h2 id="heading-css">CSS</h2>
<ul>
<li><p>CSS Challenges - <a target="_blank" href="https://css-challenges.com/">https://css-challenges.com/</a></p>
</li>
<li><p>CSS Speedrun - <a target="_blank" href="https://css-speedrun.netlify.app/">https://css-speedrun.netlify.app/</a></p>
</li>
</ul>
<h2 id="heading-selectors"><strong>Selectors</strong></h2>
<ul>
<li>CSS Diner - <a target="_blank" href="https://flukeout.github.io/">https://flukeout.github.io/</a></li>
</ul>
<h2 id="heading-flexbox"><strong>Flexbox</strong></h2>
<ul>
<li><p>Flexbox Froggy - <a target="_blank" href="https://flexboxfroggy.com/">https://flexboxfroggy.com/</a></p>
</li>
<li><p>Flexbox Defense - <a target="_blank" href="http://www.flexboxdefense.com/">http://www.flexboxdefense.com/</a></p>
</li>
<li><p>Flexbox Zombies - <a target="_blank" href="https://mastery.games/flexboxzombies/">https://mastery.games/flexboxzombies/</a></p>
</li>
<li><p>Flexbox Adventure - <a target="_blank" href="https://codingfantasy.com/games/flexboxadventure">https://codingfantasy.com/games/flexboxadventure</a></p>
</li>
</ul>
<h2 id="heading-grid"><strong>Grid</strong></h2>
<ul>
<li><p>Grid Garden - <a target="_blank" href="https://cssgridgarden.com/">https://cssgridgarden.com/</a></p>
</li>
<li><p>Grid Critters - <a target="_blank" href="https://mastery.games/gridcritters/">https://mastery.games/gridcritters/</a></p>
</li>
<li><p>Grid Attack - <a target="_blank" href="https://codingfantasy.com/games/css-grid-attack">https://codingfantasy.com/games/css-grid-attack</a></p>
</li>
</ul>
<h2 id="heading-anchor">Anchor</h2>
<ul>
<li>Anchoreum - <a target="_blank" href="https://anchoreum.com/">https://anchoreum.com/</a></li>
</ul>
<hr />
<h1 id="heading-testing-yourself">Testing yourself</h1>
<p>Here are some websites where you can test your skills against other people around the world or your friends:</p>
<ul>
<li><p>CSS Battle - <a target="_blank" href="https://cssbattle.dev/">https://cssbattle.dev/</a></p>
</li>
<li><p>Coding Game - <a target="_blank" href="https://www.codingame.com/start/">https://www.codingame.com/start/</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Copyrights and LLMs]]></title><description><![CDATA[Large Language Models (LLMs) like OpenAI’s GPT, Google’s Gemini, Meta’s LLaMA, and Deepseek’s R1 have transformed AI by creating human-like text, code, and creative content. However, their quick progress has raised serious concerns about copyright in...]]></description><link>https://blog.siddhesh.cc/copyrights-and-llms</link><guid isPermaLink="true">https://blog.siddhesh.cc/copyrights-and-llms</guid><category><![CDATA[AIethics]]></category><category><![CDATA[large language models]]></category><dc:creator><![CDATA[Siddhesh Agarwal]]></dc:creator><pubDate>Sun, 30 Mar 2025 14:47:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1743346129918/ff6f2027-ae62-4d70-a133-cfb91257c8f8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Large Language Models (LLMs) like OpenAI’s GPT, Google’s Gemini, Meta’s LLaMA, and Deepseek’s R1 have transformed AI by creating human-like text, code, and creative content. However, their quick progress has raised serious concerns about <strong>copyright infringement</strong>. Many of these models are trained on large amounts of copyrighted material—such as books, articles, research papers, and even proprietary media—without explicit permission from authors or publishers.</p>
<p>This ethical and legal dilemma forces us to ask: <strong>Should AI companies be allowed to use copyrighted data without compensation?</strong> And if they do, shouldn’t they be required to either:</p>
<ol>
<li><p><strong>Open-source their models</strong> (to ensure transparency and public benefit), or</p>
</li>
<li><p><strong>Pay for the rights</strong> to the copyrighted material they use?</p>
</li>
</ol>
<h2 id="heading-the-problem-llms-are-built-on-copyrighted-works"><strong>The Problem: LLMs Are Built on Copyrighted Works</strong></h2>
<p>Most leading LLMs are trained on datasets scraped from the internet, including:</p>
<ul>
<li><p>Books (fiction, non-fiction, academic)</p>
</li>
<li><p>News articles and journalistic content</p>
</li>
<li><p>Research papers and technical documentation</p>
</li>
<li><p>Proprietary code from platforms like GitHub</p>
</li>
</ul>
<p>Many of these sources are <strong>protected under copyright law</strong>. However, AI companies claim their use qualifies as <strong>"fair use"</strong>—a legal rule that permits limited use of copyrighted material for things like research, education, or commentary. This argument becomes less convincing when AI-generated content competes with the original works it was trained on, such as AI-written books replacing those by human authors.</p>
<h2 id="heading-why-should-ai-companies-open-source-their-models"><strong>Why Should AI Companies Open-Source Their Models?</strong></h2>
<p>If AI firms refuse to pay for copyrighted training data, they should at least <strong>open-source their models</strong> to:</p>
<ul>
<li><p><strong>Ensure Transparency:</strong> Users and regulators can audit the training data and model behavior.</p>
</li>
<li><p><strong>Prevent Monopolization:</strong> Closed-source LLMs give tech giants an unfair advantage, stifling competition.</p>
</li>
<li><p><strong>Enable Public Benefit:</strong> Open models allow researchers, startups, and nonprofits to innovate without corporate restrictions.</p>
</li>
</ul>
<p><strong>Meta’s LLaMA and DeepSeek’s models</strong> are steps in this direction, but many leading AI systems remain proprietary.</p>
<h2 id="heading-if-not-open-source-ai-firms-must-pay-for-rights"><strong>If Not Open-Source, AI Firms Must Pay for Rights</strong></h2>
<p>If companies insist on keeping their models closed, they should <strong>negotiate licenses</strong> with copyright holders. Some possible approaches:</p>
<ul>
<li><p><strong>Direct Licensing Deals</strong> (e.g., OpenAI partnering with publishers like Axel Springer)</p>
</li>
<li><p><strong>Royalty Systems</strong> (compensating authors per AI-generated output)</p>
</li>
<li><p><strong>Opt-out mechanisms</strong> (letting creators exclude their work from training datasets)</p>
</li>
</ul>
<p>The <a target="_blank" href="https://www.nytimes.com/2023/12/27/business/media/new-york-times-open-ai-microsoft-lawsuit.html"><strong>New York Times lawsuit against OpenAI</strong></a> and the <a target="_blank" href="https://www.reuters.com/technology/openai-face-indian-digital-news-firms-ambani-adani-copyright-battle-2025-01-27/">Indian Media v/s OpenAI Case</a> raises a question:</p>
<blockquote>
<p>if AI models reproduce paywalled content verbatim, should they be liable for copyright violations?</p>
</blockquote>
<h2 id="heading-conclusion-a-fair-approach-to-ai-and-copyright"><strong>Conclusion: A Fair Approach to AI and Copyright</strong></h2>
<p>The current practice of <strong>scraping copyrighted works without permission</strong> is unsustainable. AI companies must choose:</p>
<ol>
<li><p><strong>Open-source their models</strong> to democratize AI and avoid legal risks, <strong>or</strong></p>
</li>
<li><p><strong>Pay for licensed data</strong>, ensuring creators are fairly compensated.</p>
</li>
</ol>
<p>Without reform, the AI industry risks legal battles, public backlash, and an erosion of trust. The future of AI should be built on <strong>ethical data use</strong>, not the unchecked exploitation of copyrighted material.</p>
]]></content:encoded></item><item><title><![CDATA[The Pointlessness of FP vs OOP Discussions]]></title><description><![CDATA[In the world of software engineering, discussions about different programming styles are pretty common. The clash between Object-Oriented Programming (OOP) and Functional Programming (FP) often takes centre stage. Each camp claims its approach is the...]]></description><link>https://blog.siddhesh.cc/the-pointlessness-of-fp-vs-oop-discussions</link><guid isPermaLink="true">https://blog.siddhesh.cc/the-pointlessness-of-fp-vs-oop-discussions</guid><category><![CDATA[Object Oriented Programming]]></category><category><![CDATA[Functional Programming]]></category><category><![CDATA[programming]]></category><dc:creator><![CDATA[Siddhesh Agarwal]]></dc:creator><pubDate>Sun, 05 Jan 2025 07:24:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1743387328268/e17fd1ab-8b07-4e5e-a689-44ae1e74172c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the world of software engineering, discussions about different programming styles are pretty common. The clash between <strong>Object-Oriented Programming (OOP)</strong> and <strong>Functional Programming (FP)</strong> often takes centre stage. Each camp claims its approach is the best, pointing to scalability, maintainability, and user-friendliness as key factors. But honestly, this debate tends to be more distracting than anything productive.</p>
<p>The real issue in programming isn’t about sticking to a specific style; it’s about understanding code as <strong>Data Flow</strong>. Grasping how data moves and gets processed in your system is way more valuable than arguing over whether a <code>class</code> or a <code>reduce</code> function is the way to go.</p>
<hr />
<h2 id="heading-average-fp-vs-oop-debate">Average FP vs OOP Debate</h2>
<p>This video perfectly sums up the average Functional Programming or object-oriented programming Debate</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/lRX5b6SiR3o">https://youtu.be/lRX5b6SiR3o</a></div>
<p> </p>
<hr />
<h2 id="heading-paradigms-tools-not-identities">Paradigms: Tools, Not Identities</h2>
<p>Before we get into data flow, let’s take a moment to clarify our frameworks. Both Object-Oriented Programming (OOP) and Functional Programming (FP) are mental models that help us make sense of code. Think of them as tools rather than strict rules to follow.</p>
<ul>
<li><p>OOP focuses on encapsulation and represents the world as a bunch of interacting entities (or objects). This approach works well in areas like UI design or game development.</p>
</li>
<li><p>FP, on the other hand, highlights immutability and composition, which often leads to clean and predictable transformations. This method is particularly useful in data-heavy fields like data pipelines or distributed systems.</p>
</li>
</ul>
<p>The key takeaway is that these paradigms excel in certain situations but can fall short if applied too rigidly. Sticking to just one paradigm can distract us from the more important question: How does data flow through our system?</p>
<hr />
<h2 id="heading-the-essence-of-programming-data-flow">The Essence of Programming: Data Flow</h2>
<p>Programming fundamentally involves three components: inputs, processes, and outputs. For instance, processing user data from a database to display on a webpage illustrates this concept. Regardless of whether you utilize Object-Oriented Programming (OOP) or Functional Programming (FP), the essential steps remain the same:</p>
<ol>
<li><p><strong>Input</strong>: Fetch data from the database.</p>
</li>
<li><p><strong>Processes</strong>: Filter, sort, or format the data.</p>
</li>
<li><p><strong>Output</strong>: Render the processed data through HTML.</p>
</li>
</ol>
<p>Concentrating on how data moves and evolves within the system encourages you to think beyond mere syntax and boilerplate.</p>
<ul>
<li><p>Understand dependencies.</p>
</li>
<li><p>Minimize unnecessary transformations.</p>
</li>
<li><p>Optimize for performance and clarity.</p>
</li>
</ul>
<p>This perspective naturally integrates the strengths of both OOP and FP while avoiding their pitfalls.</p>
<hr />
<h2 id="heading-data-flow-in-practice">Data Flow in Practice</h2>
<p>Let’s consider a practical scenario involving the development of a <strong>recommendation system</strong>.</p>
<h3 id="heading-oop-approach">OOP Approach</h3>
<p>You might create classes like <code>User</code>, <code>Product</code>, and <code>RecommendationEngine</code>. Each class has methods encapsulating behaviour, such as <code>getRecommendations()</code>. While this can work, it often leads to tight coupling and hard-to-follow chains of method calls, especially in systems with complex logic.</p>
<h3 id="heading-fp-approach">FP Approach</h3>
<p>Alternatively, you can view the data as unchangeable structures and use functions to manage it. This approach can create clean and efficient pipelines. However, if you rely too heavily on functional programming, it may become confusing and require significant mental effort to keep track of what's happening in between.</p>
<h3 id="heading-data-flow-approach">Data Flow Approach</h3>
<p>Instead of starting with paradigm constraints, begin by modelling the flow of data:</p>
<ol>
<li><p><strong>Data Collection</strong>: Aggregate user interactions and product metadata.</p>
</li>
<li><p><strong>Processing</strong>: Utilize algorithms such as collaborative filtering or content-based filtering.</p>
</li>
<li><p><strong>Delivery</strong>: Serialize the results and send them to the client.</p>
</li>
</ol>
<p>Tools and abstractions, including classes, functions, and other types, should primarily facilitate this flow. By concentrating on the sequence of transformations, you can:</p>
<ul>
<li><p>Simplify complex systems by dividing them into distinct, testable components.</p>
</li>
<li><p>Select the appropriate paradigm or library for each step.</p>
</li>
<li><p>Steer clear of early optimization and avoid making things more complicated than necessary.</p>
</li>
</ul>
<hr />
<h2 id="heading-moving-beyond-paradigm-wars">Moving Beyond Paradigm Wars</h2>
<p>The main point is simple: paradigms are not solutions; they are ways to understand problems. Sticking to one paradigm as the "right" way limits creativity and hides the real goal of programming, which is to solve problems effectively. By shifting focus to data flow:</p>
<ol>
<li><p><strong>Clarity Improves</strong>: Your understanding of the problem should align with its true nature rather than being influenced by the peculiarities of established paradigms.</p>
</li>
<li><p><strong>Flexibility Increases</strong>: You can take a hybrid approach by incorporating the best ideas from various paradigms.</p>
</li>
<li><p><strong>Efficiency Gains</strong>: Enhancing data movement and transformation usually results in improved performance over sticking to arbitrary design principles.</p>
</li>
</ol>
<hr />
<h2 id="heading-conclusion">Conclusion</h2>
<p>The debate between Object-Oriented Programming (OOP) and Functional Programming (FP) highlights a basic problem: we often confuse tools with solutions. By seeing code as the flow of data, we can look past this simple argument and concentrate on what matters. Instead of getting stuck in debates about paradigms, think about how data moves and how we can make that movement simpler and clearer. That's where real progress happens.</p>
<hr />
<h2 id="heading-tldr"><strong>TL;DR</strong></h2>
<p>The ongoing debate between Object-Oriented Programming (OOP) and Functional Programming (FP) is pointless. It doesn't matter if you use FP or OOP as long as you solve the problem. Developers should focus on the main idea of data flow, which is how data moves, changes, and adds value to a system. By focusing on good data movement and transformation, we can make our projects clearer, more adaptable, and more efficient. Thinking about data flow helps programmers handle challenges more effectively.</p>
<p><img src="https://i.imgflip.com/9foylc.jpg" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[RAG Model using Langchain.py and ChromaDB]]></title><description><![CDATA[Today, I will discuss creating a Retrieval Augmented Generation (RAG) Model on your custom data using Python, LangChain, and ChromaDB (or any VectorStore you choose).

You can find the source code here: Siddhesh-Agarwal/django-rag (github.com)

What ...]]></description><link>https://blog.siddhesh.cc/rag-model-using-langchainpy-and-chromadb</link><guid isPermaLink="true">https://blog.siddhesh.cc/rag-model-using-langchainpy-and-chromadb</guid><category><![CDATA[Python]]></category><category><![CDATA[langchain]]></category><category><![CDATA[RAG ]]></category><category><![CDATA[chromadb]]></category><dc:creator><![CDATA[Siddhesh Agarwal]]></dc:creator><pubDate>Sun, 28 Apr 2024 03:09:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1714199115386/5716207c-c837-47de-b7ea-999c09926695.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Today, I will discuss creating a Retrieval Augmented Generation (RAG) Model on your custom data using Python, LangChain, and ChromaDB (or any VectorStore you choose).</p>
<blockquote>
<p>You can find the source code here: <a target="_blank" href="https://github.com/Siddhesh-Agarwal/django-rag">Siddhesh-Agarwal/django-rag (</a><a target="_blank" href="http://github.com">github.com</a><a target="_blank" href="https://github.com/Siddhesh-Agarwal/django-rag">)</a></p>
</blockquote>
<h2 id="heading-what-is-a-rag-modelhttpsgithubcomsiddhesh-agarwaldjango-rag"><a target="_blank" href="https://github.com/Siddhesh-Agarwal/django-rag">What is a RAG Model?</a></h2>
<p><a target="_blank" href="https://github.com/Siddhesh-Agarwal/django-rag">To put it in sim</a>ple words, a RAG Model is a Large Language Model that is connected to a "Retrieval Agent". A retrieval agent is an agent that fetches documents from a "VectorStore" using the <a target="_blank" href="https://en.wikipedia.org/wiki/Nearest_neighbor_search#Approximation_methods">Approximate Nearest Neighbor</a> (ANN) algorithm. A VectorStore can be thought to be similar to a <a target="_blank" href="https://en.wikipedia.org/wiki/Knowledge_base">Knowledge Base</a>. VectorStore or Vector Database is a special type of Database that stores information as high-order vectors. These vectors are based on the "text embeddings" of the information. Since LLMs do not understand "Language", sentences are tokenized (essentially, tokenization is the process of breaking down sentences into smaller units called "tokens". A token may or may not be equivalent to a word) and converted to their vector equivalent. Each LLM has a unique text embedding.</p>
<h2 id="heading-what-is-the-use-of-it">What is the use of it?</h2>
<p>There are 2 major problems while using Large Language Models:</p>
<ol>
<li><p><strong>Training Date Cutoff</strong>: LLMs do not have information after their training cutoff date, so they cannot answer questions about the latest events.</p>
</li>
<li><p><strong>Hallucinations</strong>: LLMs tend to "imagine" certain information to answer questions. This may be because the relevant information is missing or is getting lost due to the context size of the model. This results in the model spitting out factually Inconsistent information.</p>
</li>
</ol>
<p>We can solve both of these problems using RAG Models.</p>
<blockquote>
<p><strong>READ MORE</strong>: <a target="_blank" href="https://arxiv.org/abs/2311.13878">[2311.13878] Minimizing Factual Inconsistency and Hallucination in Large Language Models (</a><a target="_blank" href="http://arxiv.org">arxiv.org</a><a target="_blank" href="https://arxiv.org/abs/2311.13878">)</a></p>
</blockquote>
<p>We can create custom Chatbots that answer questions based on our custom data. For example, a car manufacturer could make a chatbot for its website that answers basic questions!</p>
<hr />
<h1 id="heading-building-a-rag-model">Building a RAG Model</h1>
<p>We can build our RAG Model in 4 simple steps.</p>
<h2 id="heading-step-1-selecting-llm-and-vectorstore">Step 1: Selecting LLM and VectorStore</h2>
<p>While this step is the simplest, it is also the most crucial in the process. You can select <a target="_blank" href="https://python.langchain.com/docs/integrations/vectorstores/">any VectorStore</a> and <a target="_blank" href="https://python.langchain.com/docs/integrations/llms/">any LLMs</a>. For simplicity, let's choose ChromaDB and the GPT 3.5-Turbo Model (requires an OpenAI API key).</p>
<h2 id="heading-step-2-data-extraction-and-document-loading"><strong>Step 2: Data Extraction and Document Loading</strong></h2>
<p>First, we need to extract our data. It could be in the form of a text file, a PDF, or even a webpage. To extract the data, we should use <a target="_blank" href="https://python.langchain.com/docs/integrations/document_loaders/">Langchain's document loaders</a>. For instance, if we are developing a Chatbot trained on the <a target="_blank" href="https://django.readthedocs.io/en/stable/">Django documentation</a>, we should start by using a document loader to fetch the documents from the website:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> langchain_community.document_loaders.recursive_url_loader <span class="hljs-keyword">import</span> RecursiveUrlLoader
<span class="hljs-keyword">from</span> bs4 <span class="hljs-keyword">import</span> BeautifulSoup

loader = RecursiveUrlLoader(
    url=<span class="hljs-string">"https://django.readthedocs.io/en/stable/"</span>,
    max_depth=<span class="hljs-number">3</span>,
    extractor=<span class="hljs-keyword">lambda</span> x: BeautifulSoup(x).text,
)
</code></pre>
<p>Now that we have created a loader, we load the documents:</p>
<pre><code class="lang-python">docs = loader.load()
</code></pre>
<p>While this gets the job done, there is an issue with <code>loader.load()</code>. The problem is that it produces documents with inconsistent sizes (one page might be too large while another might be too small, causing variations in document size) and there is no set maximum size for a document (this could lead to the LLM missing context even if the right document is recognized due to large context size). This problem can be resolved by utilizing the <code>load_and_split()</code> method of the <code>loader</code>:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> langchain.text_splitter <span class="hljs-keyword">import</span> RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter()
docs = loader.load_and_split(text_splitter=text_splitter)
</code></pre>
<p>The idea behind a "text splitter" is to split the documents into small uniformly sized documents.</p>
<h2 id="heading-step-3-creating-embeddings-and-storage">Step 3: Creating Embeddings and Storage</h2>
<p>Now we have to add the documents to a Vector Store. But first, we need to initialize the VectorStore:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> langchain.vectorstores.chroma <span class="hljs-keyword">import</span> Chroma
<span class="hljs-keyword">from</span> langchain_openai.embeddings <span class="hljs-keyword">import</span> OpenAIEmbeddings
<span class="hljs-keyword">import</span> chromadb

client = chromadb.PersistentClient()
embeddings = OpenAIEmbeddings(model=<span class="hljs-string">"text-embedding-3-large"</span>)
db = Chroma(
    client=client,
    collection_name=<span class="hljs-string">"django"</span>,
    embedding_function=embeddings,
)
</code></pre>
<p>Now, we add the documents to the store:</p>
<pre><code class="lang-python">db.add_documents(docs)
</code></pre>
<p>You will face the <code>RateLimitError</code> if you have enough data and are working on the free tier/tier-1. To prevent the rate limiting, we can add a small amount of documents after small intervals:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> time

<span class="hljs-comment"># change these variables to experiment</span>
batch_size = <span class="hljs-number">10</span>
sleep_time = <span class="hljs-number">1</span>
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">0</span>, len(docs), batch_size):
    db.add_documents(docs[i : i + batch_size])
    time.sleep(sleep_time)
</code></pre>
<p>After this step is done, you have successfully embedded all the data in a VectorStore</p>
<h2 id="heading-step-4-connecting-retriever-to-llm">Step 4: Connecting Retriever to LLM</h2>
<p>Now comes the nice part, we create a retriever instance, an LLM instance and a Prompt template and join all 3 to form an LLM chain:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> langchain.prompts.chat <span class="hljs-keyword">import</span> ChatPromptTemplate
<span class="hljs-keyword">from</span> langchain_core.output_parsers.string <span class="hljs-keyword">import</span> StrOutputParser
<span class="hljs-keyword">from</span> langchain_core.runnables.passthrough <span class="hljs-keyword">import</span> RunnablePassthrough
<span class="hljs-keyword">from</span> langchain_openai.llms <span class="hljs-keyword">import</span> OpenAI

retriever = db.as_retriever()
model = OpenAI(temperature=<span class="hljs-number">0</span>)
template = <span class="hljs-string">"""Answer the question based only on the following context:
{context}

Question: {question}
"""</span>
prompt = ChatPromptTemplate.from_template(template)

chain = (
    {<span class="hljs-string">"context"</span>: retriever, <span class="hljs-string">"question"</span>: RunnablePassthrough()}
    | prompt
    | model
    | StrOutputParser()
)

query = <span class="hljs-string">"What are the features of Django?"</span>
chain.stream(query)
</code></pre>
<p>Congrats, you have made your very own RAG Model that answers questions from the Django documentation!!!</p>
<hr />
<h1 id="heading-deployment">Deployment</h1>
<p>The RAG Model can be deployed using Streamlit.</p>
<blockquote>
<p>To learn more about streamlit, check out my previous article on <a target="_blank" href="https://blog.siddhesh.tech/deploy-ml-models-with-streamlit">Streamlit for ML deployment</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Deploy ML Models with Streamlit]]></title><description><![CDATA[Streamlit is an open-source Python library that can make and deploy beautiful-looking web apps in a few minutes. It has been quite a handy tool for deploying ML models without creating API endpoints in Flask or FastAPI.
Today, I will talk about some ...]]></description><link>https://blog.siddhesh.cc/deploy-ml-models-with-streamlit</link><guid isPermaLink="true">https://blog.siddhesh.cc/deploy-ml-models-with-streamlit</guid><category><![CDATA[Python]]></category><category><![CDATA[streamlit]]></category><category><![CDATA[machine learning models]]></category><dc:creator><![CDATA[Siddhesh Agarwal]]></dc:creator><pubDate>Wed, 24 Apr 2024 03:53:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1714038253413/2207a289-4372-4af1-94f4-621171a8beea.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a target="_blank" href="http://github.com/streamlit/streamlit">Streamlit</a> is an open-source Python library that can make and deploy beautiful-looking web apps in a few minutes. It has been quite a handy tool for deploying ML models without creating API endpoints in Flask or FastAPI.</p>
<p>Today, I will talk about some streamlit functions I have used that could help you too! For Demo, this is what a streamlit app looks like:</p>
<p><a target="_blank" href="https://skin-cancer-check.streamlit.app/"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1713929603148/6636ecdf-057e-4072-984c-026f85b8ccbc.png" alt class="image--center mx-auto" /></a></p>
<blockquote>
<p><strong><em>Source</em></strong>: <a target="_blank" href="https://github.com/Siddhesh-Agarwal/Skin-Cancer-Detection">Siddhesh-Agarwal/Skin-Cancer-Detection: A web app to detect Skin cancer using pictures of moles and other marks on skin (</a><a target="_blank" href="http://github.com">github.com</a><a target="_blank" href="https://github.com/Siddhesh-Agarwal/Skin-Cancer-Detection">)</a></p>
</blockquote>
<h1 id="heading-creatinghttpsgithubcomsiddhesh-agarwalskin-cancer-detection"><a target="_blank" href="https://github.com/Siddhesh-Agarwal/Skin-Cancer-Detection">Creating</a></h1>
<p><a target="_blank" href="https://github.com/Siddhesh-Agarwal/Skin-Cancer-Detection">To begin, create a <code>app.py</code> file or use a template. In your <code>app.py</code> file simply type:</a></p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> streamlit <span class="hljs-keyword">as</span> st

st.title(<span class="hljs-string">"Test"</span>)
</code></pre>
<h2 id="heading-magic">Magic</h2>
<p>Anything written in the Python script between triple quotes (<code>"""</code>)will be rendered as markdown text!</p>
<pre><code class="lang-python"><span class="hljs-string">"""
# Heading 1
## Heading 2
### Heading 3

1. Ordered list 1
2. Ordered list 2
3. Ordered list 3
"""</span>
</code></pre>
<h2 id="heading-components">Components</h2>
<h3 id="heading-write">Write</h3>
<p>Described as the "Swiss Army knife of Streamlit commands", `st.write()` is one of the most versatile functions to display any data type.</p>
<pre><code class="lang-python">st.write(<span class="hljs-string">"_Hello_ *World*"</span>)
st.write(df)
</code></pre>
<h3 id="heading-data-elements">Data Elements</h3>
<ol>
<li><p>JSON</p>
<pre><code class="lang-python"> st.json(dict_or_json_obj)
</code></pre>
</li>
<li><p>DataFrame</p>
<pre><code class="lang-python"> st.dataframe(df)
</code></pre>
</li>
<li><p>Table</p>
<pre><code class="lang-python"> st.table(df)
</code></pre>
</li>
<li><p>Metrics</p>
<pre><code class="lang-python"> st.metric(<span class="hljs-string">"Temperature"</span>, <span class="hljs-string">"39°C"</span>, <span class="hljs-string">"1°C"</span>)
 st.metric(<span class="hljs-string">"Wind"</span>, <span class="hljs-string">"12 kmph"</span>, <span class="hljs-string">"-8%"</span>)
</code></pre>
</li>
</ol>
<h3 id="heading-input-widgets">Input Widgets</h3>
<ol>
<li><p>Text Input</p>
<pre><code class="lang-python"> name = st.text_input(<span class="hljs-string">"Enter you name"</span>)
 password = st.text_input(<span class="hljs-string">"Enter the password"</span>, type=<span class="hljs-string">"password"</span>)
 st.write(<span class="hljs-string">f"Your name is <span class="hljs-subst">{name}</span> and your password is <span class="hljs-subst">{password}</span>"</span>)
</code></pre>
</li>
<li><p>Number Input</p>
<pre><code class="lang-python"> age = st.number_input(<span class="hljs-string">"Enter your age"</span>, min_value=<span class="hljs-number">18</span>, max_value=<span class="hljs-number">120</span>)
 st.write(<span class="hljs-string">"Your Age is:"</span>, age)
</code></pre>
</li>
<li><p>Slider</p>
<pre><code class="lang-python"> age = st.slider(<span class="hljs-string">"Enter your age"</span>, min_value=<span class="hljs-number">18</span>, max_value=<span class="hljs-number">120</span>)
 st.write(<span class="hljs-string">"Your Age is:"</span>, age)
</code></pre>
</li>
<li><p>Date Input</p>
<pre><code class="lang-python"> <span class="hljs-keyword">from</span> datetime <span class="hljs-keyword">import</span> date

 bday = st.date_input(<span class="hljs-string">"When's your birthday"</span>, date(<span class="hljs-number">2019</span>, <span class="hljs-number">7</span>, <span class="hljs-number">6</span>))
 st.write(<span class="hljs-string">'Your birthday is:'</span>, bday)
</code></pre>
</li>
<li><p>Button</p>
<pre><code class="lang-python"> <span class="hljs-keyword">if</span> st.button(<span class="hljs-string">"Click me"</span>):
     st.write(<span class="hljs-string">"Well Done"</span>)
</code></pre>
</li>
<li><p>Radio</p>
<pre><code class="lang-python"> food_items = [<span class="hljs-string">"Pizza 🍕"</span>, <span class="hljs-string">"Burger 🍔"</span>, <span class="hljs-string">"Spaghetti 🍝"</span>]
 food = st.radio(<span class="hljs-string">"What do you want to eat?"</span>, food_items)
 <span class="hljs-keyword">if</span> food:
     st.write(<span class="hljs-string">f"You are eating <span class="hljs-subst">{food}</span>!"</span>)
</code></pre>
</li>
<li><p>Select Box</p>
<pre><code class="lang-python"> food_items = [<span class="hljs-string">"Pizza 🍕"</span>, <span class="hljs-string">"Burger 🍔"</span>, <span class="hljs-string">"Spaghetti 🍝"</span>]
 food = st.selectbox(<span class="hljs-string">"What do you want to eat?"</span>, food_items)
 <span class="hljs-keyword">if</span> food:
     st.write(<span class="hljs-string">f"You are eating <span class="hljs-subst">{food}</span>!"</span>)
</code></pre>
</li>
<li><p>Multiselect</p>
<pre><code class="lang-python"> food_items = [<span class="hljs-string">"Pizza 🍕"</span>, <span class="hljs-string">"Burger 🍔"</span>, <span class="hljs-string">"Spaghetti 🍝"</span>]
 food = st.multiselect(<span class="hljs-string">"What do you want to eat?"</span>, food_items)
 <span class="hljs-keyword">if</span> food:
     st.markdown(<span class="hljs-string">f"You are eating <span class="hljs-subst">{<span class="hljs-string">', '</span>.join(food)}</span>!"</span>)
</code></pre>
</li>
<li><p>Toggle</p>
<pre><code class="lang-python"> toggle = st.toggle(<span class="hljs-string">"Display Dataframe"</span>)
 <span class="hljs-keyword">if</span> toggle:
     st.write(df)
</code></pre>
</li>
<li><p>File Uploader</p>
<pre><code class="lang-python">file = st.file_uploader(<span class="hljs-string">"Upload a file"</span>)
</code></pre>
</li>
</ol>
<h3 id="heading-layouts">Layouts</h3>
<ol>
<li><p>Columns</p>
<pre><code class="lang-python"> cols = st.columns(<span class="hljs-number">2</span>)
 <span class="hljs-keyword">with</span> cols[<span class="hljs-number">0</span>]:
     st.write(<span class="hljs-string">"This is Column 1"</span>)
 <span class="hljs-keyword">with</span> cols[<span class="hljs-number">1</span>]:
     st.write(<span class="hljs-string">"This is Column 2"</span>)
</code></pre>
</li>
<li><p>Container</p>
<pre><code class="lang-python"> c = st.container()
 st.write(<span class="hljs-string">"Line 3"</span>)
 c.write(<span class="hljs-string">"Line 1"</span>)
 c.write(<span class="hljs-string">"Line 2"</span>)
</code></pre>
</li>
<li><p>Expander</p>
<pre><code class="lang-python"> <span class="hljs-keyword">with</span> st.expander(<span class="hljs-string">"Click to Open"</span>):
     st.write(<span class="hljs-string">"Here is some more content"</span>)
</code></pre>
</li>
<li><p>Sidebar</p>
<pre><code class="lang-python"> <span class="hljs-keyword">with</span> st.sidebar:
     st.write(<span class="hljs-string">"This will be displayed in the sidebar"</span>)
</code></pre>
</li>
<li><p>Tabs</p>
<pre><code class="lang-python"> tabs = st.tabs([<span class="hljs-string">"Milk"</span>, <span class="hljs-string">"Cookies"</span>])
 <span class="hljs-keyword">with</span> tabs[<span class="hljs-number">0</span>]:
     st.write(<span class="hljs-string">"You chose Milk 🥛"</span>)
 <span class="hljs-keyword">with</span> tabs[<span class="hljs-number">1</span>]:
     st.write(<span class="hljs-string">"You chose Cookies 🍪"</span>)
</code></pre>
</li>
</ol>
<h3 id="heading-status-elements">Status Elements</h3>
<ol>
<li><p>Spinner</p>
<pre><code class="lang-python"> <span class="hljs-keyword">with</span> st.spinner(<span class="hljs-string">"Loading..."</span>):
     perform_task()
</code></pre>
</li>
<li><p>Toast</p>
<pre><code class="lang-python"> st.toast(<span class="hljs-string">"Process completed successfully!"</span>)
</code></pre>
</li>
<li><p>Balloons / Snow</p>
<pre><code class="lang-python"> st.balloons()
 st.snow()
</code></pre>
</li>
<li><p>status boxes</p>
<pre><code class="lang-python"> st.success(<span class="hljs-string">"Success"</span>)
 st.info(<span class="hljs-string">"Information"</span>)
 st.warning(<span class="hljs-string">"Warning"</span>)
 st.error(<span class="hljs-string">"Error"</span>)
</code></pre>
</li>
</ol>
<h3 id="heading-control-flow">Control Flow</h3>
<ol>
<li><p>Forms</p>
<pre><code class="lang-python"> <span class="hljs-keyword">with</span> st.form(key=<span class="hljs-string">'some_form'</span>):
     name = st.text_input(<span class="hljs-string">"Name"</span>)
     age = st.number_input(<span class="hljs-string">"Age"</span>)
     <span class="hljs-keyword">if</span> st.form_submit_button(<span class="hljs-string">"Submit"</span>):
         st.balloons()
</code></pre>
</li>
<li><p>Rerun</p>
<pre><code class="lang-python"> st.rerun()
</code></pre>
</li>
<li><p>Stop Execution</p>
<pre><code class="lang-python"> st.stop()
</code></pre>
</li>
</ol>
<h2 id="heading-configuration">Configuration</h2>
<p>Streamlit allows the configuration of colour along with some other things. To customize, create a <code>.streamlit/config.toml</code> file. You can do something like this to change the classic black-and-white style to something more colourful:</p>
<pre><code class="lang-ini"><span class="hljs-section">[theme]</span>
<span class="hljs-attr">primaryColor</span>=<span class="hljs-string">"#F63366"</span>
<span class="hljs-attr">backgroundColor</span>=<span class="hljs-string">"#FCF2E5"</span>
<span class="hljs-attr">secondaryBackgroundColor</span>=<span class="hljs-string">"#F8E4C7"</span>
<span class="hljs-attr">textColor</span>=<span class="hljs-string">"#302730"</span>
</code></pre>
<blockquote>
<p>Learn More: <a target="_blank" href="https://docs.streamlit.io/develop/api-reference/configuration/config.toml">config.toml - Streamlit Docs</a></p>
</blockquote>
<h2 id="heading-secretshttpsdocsstreamlitiodevelopapi-referenceconfigurationconfigtoml"><a target="_blank" href="https://docs.streamlit.io/develop/api-reference/configuration/config.toml">Secrets</a></h2>
<p>To manage secrets (like environment variables and API Keys), Streamlit has a custom solution. A special file (<code>./.streamlit/secrets.toml</code>) keeps all the secrets.</p>
<pre><code class="lang-ini"><span class="hljs-attr">OPENAI_API_KEY</span>=<span class="hljs-string">"&lt;OPENAI_API_KEY_HERE&gt;"</span>
</code></pre>
<hr />
<h1 id="heading-deployment">Deployment</h1>
<ol>
<li><p>The first step is to identify the input taken by the model and input those details.</p>
<pre><code class="lang-python"> pic = st.file_uploader(
     label=<span class="hljs-string">"Upload a picture"</span>,
     type=[<span class="hljs-string">"png"</span>, <span class="hljs-string">"jpg"</span>, <span class="hljs-string">"jpeg"</span>],
     accept_multiple_files=<span class="hljs-literal">False</span>,
     help=<span class="hljs-string">"Upload a picture of a cat or dog"</span>,
 )
</code></pre>
</li>
<li><p>The second step is to preprocess the image to fit the model (this preprocessing depends on your model.</p>
</li>
<li><p>The next step is to load your model (TIP: cache the model to prevent loading time for subsequent runs)</p>
<pre><code class="lang-python"><span class="hljs-meta"> @st.cache_resource</span>
 <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">load_model</span>():</span>
     model = tf.keras.models.load_model(<span class="hljs-string">"./model/model.h5"</span>)
     <span class="hljs-keyword">return</span> model
</code></pre>
</li>
<li><p>Pass the processed image to the model and display the output.</p>
<pre><code class="lang-python"> model = load_model()
 st.write(model.predict(img))
</code></pre>
</li>
</ol>
<hr />
<h1 id="heading-execution">Execution</h1>
<p>To run the file, run:</p>
<pre><code class="lang-sh">$ streamlit run app.py
</code></pre>
<blockquote>
<p><strong>NOTE</strong>: You can learn about the different components in streamlit through their <a target="_blank" href="https://docs.streamlit.io/">official docs</a>.</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Publishing Packages using Poetry]]></title><description><![CDATA[Poetry is rapidly gaining recognition as an excellent dependency manager in the Python community. It has risen rapidly to become the dependency manager for various projects across the Python community. But did you know that not only can poetry be use...]]></description><link>https://blog.siddhesh.cc/publishing-packages-using-poetry</link><guid isPermaLink="true">https://blog.siddhesh.cc/publishing-packages-using-poetry</guid><category><![CDATA[Python]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[Poetry]]></category><category><![CDATA[pypi]]></category><dc:creator><![CDATA[Siddhesh Agarwal]]></dc:creator><pubDate>Sat, 03 Feb 2024 08:40:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1706949488188/bd900968-06b4-4a2d-900a-6cb8baafbb1e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Poetry is rapidly gaining recognition as an excellent dependency manager in the Python community. It has risen rapidly to become the dependency manager for various projects across the Python community. But did you know that not only can <a target="_blank" href="https://python-poetry.org/">poetry</a> be used as a dependency manager but it can also be used for publishing Python packages to <a target="_blank" href="https://pypi.org">PyPI</a>? I have previously written about publishing to PyPI using the tedious setup.py-bdist-twine method</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.siddhesh.tech/packaging-and-publishing-on-pypi">https://blog.siddhesh.tech/packaging-and-publishing-on-pypi</a></div>
<p> </p>
<h2 id="heading-initiating-a-project">Initiating a project</h2>
<p>To start a new project, run the following command:</p>
<pre><code class="lang-bash">poetry new poetry-demo
</code></pre>
<p>This will create a file <code>poetry-demo</code> with the following file structure:</p>
<pre><code class="lang-plaintext">poetry-demo
├── pyproject.toml
├── README.md
├── poetry_demo
│   └── __init__.py
└── tests
    └── __init__.py
</code></pre>
<blockquote>
<p><strong>NOTE</strong>: Check the availability of the name on <a target="_blank" href="https://pypi.org/">PyPI</a></p>
</blockquote>
<h2 id="heading-adding-dependencies">Adding Dependencies</h2>
<p>To add dependencies to the project, we run the command:</p>
<pre><code class="lang-bash">poetry add &lt;dependency&gt;
</code></pre>
<p>For example, to add pandas as our dependency, we run the command:</p>
<pre><code class="lang-bash">poetry add pandas
</code></pre>
<p>If you are adding a dependency for the first time in a project, you will notice a new <code>poetry.lock</code> file being generated. It contains dependencies along with their corresponding versions and checksums/hashes. This helps users to always be on the same depency versions. It also results in faster dependency conflict resolution.</p>
<blockquote>
<p>Read more about <a target="_blank" href="https://python-poetry.org/docs/">poetry</a></p>
</blockquote>
<p>Poetry also allows us to create groups. We can do them something like this:</p>
<pre><code class="lang-bash">poetry add black isort --group dev
</code></pre>
<p>The installation command will now be:</p>
<pre><code class="lang-bash">pip install <span class="hljs-string">"poetry-demo[dev]"</span>
</code></pre>
<h2 id="heading-tweaking-poetrytoml">Tweaking <code>poetry.toml</code></h2>
<p>The <code>poetry.toml</code> file contains metadata similar to the <code>setup.py</code> file. We can enter various things like name, version, description, license, authors, readme, repository, keywords and classifiers among other things.</p>
<blockquote>
<p>Read more about the <a target="_blank" href="https://python-poetry.org/docs/pyproject/"><code>poetry.toml</code> file</a></p>
</blockquote>
<h2 id="heading-publishing-on-pypi">Publishing on PyPI</h2>
<p>Before publishing our project on PyPI, We need to create a build:</p>
<pre><code class="lang-bash">poetry build
</code></pre>
<p>This generates a <code>dist</code> folder that contains a <code>targ.gz</code> and a <code>whl</code> file. Poetry works only for vanilla Python builds (no C/C++/Rust builds 😞). Now, to publish these files to PyPI, we run the command:</p>
<pre><code class="lang-bash">poetry publish
</code></pre>
<p>You will be prompted for your PyPI username and password. Enter them to upload the packages. Instead of running 2 sperate commands, uou could combine the 2 commands and run this instead:</p>
<pre><code class="lang-bash">poetry publish --build
</code></pre>
<p>And congrats, you published a library using poetry!</p>
]]></content:encoded></item><item><title><![CDATA[Encryption and Emojis!]]></title><description><![CDATA[Almost nine months ago, I published my 3rd Python library - Cryptmoji. You may have come across a ton of cryptography libraries on PyPI. Many may be relatively safer, but I aimed to use "Caesar Cipher" and "mapping" to make a fun tool to learn crypto...]]></description><link>https://blog.siddhesh.cc/encryption-and-emojis</link><guid isPermaLink="true">https://blog.siddhesh.cc/encryption-and-emojis</guid><category><![CDATA[Cryptography]]></category><category><![CDATA[Python]]></category><category><![CDATA[encryption]]></category><category><![CDATA[emoji]]></category><dc:creator><![CDATA[Siddhesh Agarwal]]></dc:creator><pubDate>Tue, 15 Aug 2023 16:48:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1692118030987/a058419d-2cd5-4fa3-afeb-db840583a280.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Almost nine months ago, I published my 3rd Python library - <a target="_blank" href="https://pypi.org/projects/cryptmoji">Cryptmoji</a>. You may have come across a ton of cryptography libraries on PyPI. Many may be relatively safer, but I aimed to use "<a target="_blank" href="https://en.wikipedia.org/wiki/Caesar_cipher"><strong>Caesar Cipher</strong></a>" and "<strong>mapping</strong>" to make a fun tool to learn cryptography. To install Cryptmoji, run the following:</p>
<pre><code class="lang-bash">pip install cryptmoji
</code></pre>
<h2 id="heading-how-to-use-cryptmoji">How to use Cryptmoji</h2>
<h3 id="heading-encryption">Encryption</h3>
<p>To encrypt text, we use the <code>encrypt()</code> function.</p>
<pre><code class="lang-python"><span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> cryptmoji <span class="hljs-keyword">import</span> encrypt
<span class="hljs-meta">&gt;&gt;&gt; </span>text = <span class="hljs-string">"H3LL0 W0RLD"</span>
<span class="hljs-meta">&gt;&gt;&gt; </span>encrypted = encrypt(text)
<span class="hljs-string">'🌾🌜🍂🍂🌙🌉🍍🌙🍈🍂🌺'</span>
</code></pre>
<p>The output is much different than the regular encryption algorithms, isn't it?</p>
<h3 id="heading-decryption">Decryption</h3>
<p>To decrypt text, we use the <code>decrypt()</code> function.</p>
<pre><code class="lang-python"><span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> cryptmoji <span class="hljs-keyword">import</span> decrypt
<span class="hljs-meta">&gt;&gt;&gt; </span>encrypted = <span class="hljs-string">"🌾🌜🍂🍂🌙🌉🍍🌙🍈🍂🌺"</span>
<span class="hljs-meta">&gt;&gt;&gt; </span>decrypt(encrypted)
<span class="hljs-string">'H3LL0 W0RLD'</span>
</code></pre>
<p>And Voila! We have our string back!</p>
<h2 id="heading-using-the-key-parameter">using the <code>Key</code> parameter</h2>
<p>As you can see, the output starts to become predictable after some time. So we need another parameter to shuffle the characters. This Parameter is <code>key</code>. This will drastically change the encrypted string.</p>
<p>For example:</p>
<pre><code class="lang-python"><span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">from</span> cryptmoji <span class="hljs-keyword">import</span> encrypt, decrypt
<span class="hljs-meta">&gt;&gt;&gt; </span>key = <span class="hljs-string">"HI_M0M"</span>
<span class="hljs-meta">&gt;&gt;&gt; </span>encrypted = encrypt(<span class="hljs-string">"H3LL0 W0RLD"</span>, key=key)
<span class="hljs-meta">&gt;&gt;&gt; </span>encrypted
<span class="hljs-string">'🎇🍲🎮🎐🍖🍣🎢🍯🎴🎐🍪'</span>
<span class="hljs-meta">&gt;&gt;&gt; </span>decrypt(encrypted, key=key)
<span class="hljs-string">'H3LL0 W0RLD'</span>
</code></pre>
<p>For more details, refer to the <a target="_blank" href="https://siddhesh.tech/cryptmoji/">documentation</a> and <a target="_blank" href="https://github.com/Siddhesh-Agarwal/cryptmoji/">GitHub repo</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Formatter for Jupyter notebooks]]></title><description><![CDATA[Introduction
If you are into Data Science or Machine Learning, you have probably come across jupyter notebooks (.ipynb files). The problem I faced when using jupyter notebooks was that the black formatter didn't work on them. I had tried using the 
$...]]></description><link>https://blog.siddhesh.cc/formatter-for-jupyter-notebooks</link><guid isPermaLink="true">https://blog.siddhesh.cc/formatter-for-jupyter-notebooks</guid><dc:creator><![CDATA[Siddhesh Agarwal]]></dc:creator><pubDate>Sat, 18 Feb 2023 06:14:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1677045138274/2f1baefa-b68a-46f1-9e34-4dfed6d3d780.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-introduction">Introduction</h1>
<p>If you are into Data Science or Machine Learning, you have probably come across jupyter notebooks (.ipynb files). The problem I faced when using jupyter notebooks was that the black formatter didn't work on them. I had tried using the </p>
<pre><code>$ black notebook.ipynb
</code></pre><p>command many times. This article is meant to help with code formatting in Python Notebooks.</p>
<hr />
<h1 id="heading-nbqa">nbQA</h1>
<p>So, we will be using a python library called nbQA along with code formatters like Black and isort.</p>
<h2 id="heading-installation">Installation</h2>
<p>Install the library using:</p>
<pre><code>$ pip install nbqa
</code></pre><h2 id="heading-usage">Usage</h2>
<p>You can use various formatters along with nqba and I will demonstrate how to use a few of them. before trying the formatters, make sure you have installed them already.</p>
<h3 id="heading-black">black</h3>
<p>Format the notebook using black as shown below:</p>
<pre><code>$ nbqa black notebook.ipynb
reformatted notebook.ipynb
All done! ✨ 🍰 ✨
<span class="hljs-number">1</span> files reformatted.
</code></pre><h3 id="heading-isort">isort</h3>
<p>Similarly, format the notebook using isort:</p>
<pre><code>$ nbqa isort notebook.ipynb
Fixing notebook.ipynb
</code></pre><h3 id="heading-yapf">yapf</h3>
<pre><code>$ nbqa yapf --<span class="hljs-keyword">in</span>-place notebook.ipynb
</code></pre><h3 id="heading-autopep8">autopep8</h3>
<pre><code>$ nbqa autopep8 -i notebook.ipynb
</code></pre><h3 id="heading-mdformat">mdformat</h3>
<p>To format the markdown cells in your notebook, use:</p>
<pre><code>$ nbqa mdformat notebook.ipynb --nbqa-md --nbqa-diff
</code></pre><h3 id="heading-doctest">doctest</h3>
<p>To run tests for iPython notebooks using doctypes:</p>
<pre><code>$ nbqa doctest notebook.ipynb
</code></pre><hr />
<p>I hope you liked it. That's all for this time.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1677045136672/01050d6a-43a1-4392-a27c-a49d35ec583d.gif" alt="The end" /></p>
]]></content:encoded></item><item><title><![CDATA[Using if __name__ == '__main__']]></title><description><![CDATA[Many of us have seen the:
import something

def function():
    pass

if __name__ == '__main__':
    # function calls here...
    pass

in one documentation or the other, but what is it?

__main__
'__name__'

Short Answer
It protects users from accid...]]></description><link>https://blog.siddhesh.cc/if-name-main</link><guid isPermaLink="true">https://blog.siddhesh.cc/if-name-main</guid><category><![CDATA[Python]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[best practices]]></category><dc:creator><![CDATA[Siddhesh Agarwal]]></dc:creator><pubDate>Mon, 05 Sep 2022 17:16:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1662398433346/MLY7pPibm.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Many of us have seen the:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> something

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">function</span>():</span>
    <span class="hljs-keyword">pass</span>

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
    <span class="hljs-comment"># function calls here...</span>
    <span class="hljs-keyword">pass</span>
</code></pre>
<p>in one documentation or the other, but what is it?</p>
<ul>
<li><a target="_blank" href="https://docs.python.org/3/reference/toplevel_components.html?highlight=__main__#complete-python-programs"><code>__main__</code></a></li>
<li><a target="_blank" href="https://docs.python.org/3/reference/import.html?highlight=__name__#__name__"><code>'__name__'</code></a></li>
</ul>
<h1 id="heading-short-answer">Short Answer</h1>
<p>It protects users from accidentally invoking the script when they didn't intend to. It also helps the user identify whether the file has to be executed or not. The lack of it will make identification harder for the user.</p>
<h1 id="heading-long-answer">Long Answer</h1>
<p>In a large process, there are 2 types of files:</p>
<ol>
<li>Files that contain function definitions.</li>
<li>Files that call those functions and display output.</li>
</ol>
<p><strong>Files of type 1 do not need to be executed</strong> since they won't display output and simply define the functions and classes and constants used.</p>
<p>On the other hand, <strong>files of type 2 need to be executed</strong> since they display and output. To help the user identify that this file has to be execute, one uses <code>if __name__ == '__main__'</code></p>
<p>When the interpreter runs a module (that is the main program), the <code>__name__</code> variable will have the value  <code>__main__</code>. </p>
<pre><code class="lang-python">print(<span class="hljs-string">f"__name__ = <span class="hljs-subst">{__name__}</span>"</span>)    <span class="hljs-comment"># __name__ = '__main__'</span>
</code></pre>
<p>But If the code is importing from another module, then the <code>__name__</code>  variable will be set to that module’s name.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> something

print(<span class="hljs-string">f"__name__ = <span class="hljs-subst">{__name__}</span>"</span>)    <span class="hljs-comment"># __name__ = 'something'</span>
</code></pre>
<h1 id="heading-conclusion">Conclusion</h1>
<p> We can use an <code>if __name__ == "__main__"</code> block to allow or prevent parts of code from being run when the modules are imported.</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/e/ea/Thats_all_folks.svg" alt="ending gif" /></p>
]]></content:encoded></item><item><title><![CDATA[Packaging and Publishing on PyPI]]></title><description><![CDATA[This post is on "Packaging and Publishing a python library on PyPI".
There is a tutorial on Packaging Python Projects in the official PyPI website, but these docs are... outdated.

What is PyPI?
As the website says:

The Python Package Index (PyPI) i...]]></description><link>https://blog.siddhesh.cc/packaging-and-publishing-on-pypi</link><guid isPermaLink="true">https://blog.siddhesh.cc/packaging-and-publishing-on-pypi</guid><category><![CDATA[Python]]></category><category><![CDATA[Python 3]]></category><category><![CDATA[pypi]]></category><dc:creator><![CDATA[Siddhesh Agarwal]]></dc:creator><pubDate>Tue, 19 Apr 2022 03:17:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1651330935441/5g-Sztwwt.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This post is on "Packaging and Publishing a python library on <a target="_blank" href="https://pypi.org/">PyPI</a>".</p>
<p>There is a tutorial on <a target="_blank" href="https://packaging.python.org/en/latest/tutorials/packaging-projects/">Packaging Python Projects</a> in the official PyPI website, but these docs are... outdated.</p>
<hr />
<h2 id="heading-what-is-pypi">What is PyPI?</h2>
<p>As the website says:</p>
<blockquote>
<p>The Python Package Index (PyPI) is a repository of software for the Python programming language.</p>
</blockquote>
<p>This means that PyPI is the official <strong>third-party software</strong> repository for Python. Anyone (with a PyPI account) can publish a Python Package for the use of the other developers. PyPI hosts these Python packages in the form of sdists (source distributions) or precompiled "wheels".</p>
<hr />
<h2 id="heading-file-structure">File structure</h2>
<p>You have to maintain a certain file structure before packaging your project.</p>
<pre><code>package_name<span class="hljs-operator">/</span>
├── src<span class="hljs-operator">/</span>
<span class="hljs-operator">|</span>    ├── __init__.py
<span class="hljs-operator">|</span>    ├── example.py
<span class="hljs-operator">|</span>    └── py.typed
├── LICENSE
├── pyproject.toml
├── README.md
├── setup.py (or) setup.cfg
└── tests<span class="hljs-operator">/</span>
</code></pre><p>So here is what each file does:</p>
<ol>
<li><code>src/__init__.py</code>: This file contains all the import statements. We add statements that look like <code>from .example import &lt;function names&gt;</code></li>
<li><code>src/example.py</code>: This file contains all the function and class definitions.</li>
<li><code>src/py.typed</code>: An empty file. <a target="_blank" href="https://peps.python.org/pep-0561/#packaging-type-information">Read more here</a></li>
<li><code>LICENSE</code>: This file contains the license for the code you are publishing. <ul>
<li>You can choose a license from <a target="_blank" href="https://choosealicense.com/">choosealicense.com</a></li>
</ul>
</li>
<li><code>pyproject.toml</code>: This file tells build tools (like build and pip) what is required to build your package. For now, this will do:<pre><code class="lang-toml"> <span class="hljs-section">[build-system]</span>
 <span class="hljs-attr">requires</span> = [
     <span class="hljs-string">"setuptools&gt;=42"</span>,
     <span class="hljs-string">"wheel"</span>
 ]
 <span class="hljs-attr">build-backend</span> = <span class="hljs-string">"setuptools.build_meta"</span>
</code></pre>
</li>
<li><code>README.md</code>: This file acts as a guide. It gives developers a detailed description of your project.</li>
<li><code>setup.py</code> (dynamic) or <code>setup.cfg</code> (static) are files that give "setuptools" information about your package (such as the name, version, author etc.). They also inform <code>setuptools</code> which code files to include.<ul>
<li><a target="_blank" href="https://setuptools.pypa.io/en/latest/userguide/declarative_config.html">Writing setup.cfg/setup.py</a></li>
</ul>
</li>
<li><code>tests/</code>: This folder is a placeholder for test files.</li>
</ol>
<hr />
<h2 id="heading-packaging-project">Packaging Project</h2>
<p>First, make sure that the <code>pip</code> installed on the device is of the latest version. To do that, run:</p>
<pre><code>$ pip <span class="hljs-keyword">install</span> <span class="hljs-comment">--upgrade pip</span>
</code></pre><p>After this, install <code>build</code> using:</p>
<pre><code>$ pip <span class="hljs-keyword">install</span> <span class="hljs-comment">--upgrade build</span>
</code></pre><p>Now, let's package the project. To package the project, run:</p>
<pre><code>$ python -m build
</code></pre><p>This command will output lots of text and create a <code>build/</code> folder and a <code>dist/</code> folder. </p>
<p><strong>The project has been packaged!</strong> Now we have to publish it on PyPI.</p>
<hr />
<h2 id="heading-publishing-on-pypi">Publishing on PyPI</h2>
<p>The first step to publishing on PyPI is <strong>creating an account there</strong>. Head over to <a target="_blank" href="https://pypi.org/">PyPI</a> and click on register (the text at the top right corner,  that I highlighted in green):</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1651330929359/tBrqTIj_5.png" alt="PyPI Register Button" /></p>
<p>You will get a form like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1651330931029/wIOxkM1qJ.png" alt="PyPI Registration Form" /></p>
<p>Fill out the form and <strong>remember the username and password</strong>. You will need it while publishing your project.</p>
<p>Now head back to the terminal and run:</p>
<pre><code>$ pip <span class="hljs-keyword">install</span> <span class="hljs-comment">--upgrade twine</span>
</code></pre><p>This command will upgrade twine to the latest version if twine is already present. If it isn't present, then it will install the latest version. Now, it is time to upload the package!</p>
<pre><code>$ twine upload dist/*
</code></pre><p>You will be prompted to enter your PyPI username and password for authentication purposes. After entering them, you will see a URL in the last line of the output. the URL will be of the format <code>https://pypi.org/project/&lt;package_name&gt;</code></p>
<p><strong>Congratulations, the python package has been published on PyPI!!!</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1651330932373/GQKUJ6E26.gif" alt="Congrats" /></p>
<p>Now, let's pip install the library!</p>
<pre><code>$ pip install <span class="hljs-operator">&lt;</span>package_name<span class="hljs-operator">&gt;</span>
</code></pre><hr />
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1651330934115/IAJI5CGra.gif" alt="That's all Folks!" /></p>
]]></content:encoded></item><item><title><![CDATA[print() in python]]></title><description><![CDATA[In this post, I will talk about the print() statement and its parameters.
So, I was experimenting with the help() function in python and tried the following command:
>>> help(print)
Help on built-in function print in module builtins:

print(...)
    ...]]></description><link>https://blog.siddhesh.cc/print-in-python</link><guid isPermaLink="true">https://blog.siddhesh.cc/print-in-python</guid><category><![CDATA[Python]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Siddhesh Agarwal]]></dc:creator><pubDate>Sun, 16 Jan 2022 06:26:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1651370907420/CYDwDf9DB.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this post, I will talk about the <code>print()</code> statement and its parameters.</p>
<p>So, I was experimenting with the <code>help()</code> function in python and tried the following command:</p>
<pre><code class="lang-bash">&gt;&gt;&gt; <span class="hljs-built_in">help</span>(<span class="hljs-built_in">print</span>)
Help on built-in <span class="hljs-keyword">function</span> <span class="hljs-built_in">print</span> <span class="hljs-keyword">in</span> module builtins:

<span class="hljs-built_in">print</span>(...)
    <span class="hljs-built_in">print</span>(value, ..., sep=<span class="hljs-string">' '</span>, end=<span class="hljs-string">'\n'</span>, file=sys.stdout, flush=False)

    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.
</code></pre>
<p>me, after seeing <code>file</code> and <code>flush</code> arguments in the output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1651330942759/5Uvi_sMeG.gif" alt="Haha, Meme based on my pain" /></p>
<p>I knew about the <code>sep</code> and <code>end</code> parameters but not about the other 2 parameters. But what are these <strong>unpopular-parameters-that-online-tutorials-do-not-talk-about</strong>?</p>
<p>Today, I am going to share what they are. But before that, let me explain what the first 2 parameters are.</p>
<hr />
<ul>
<li><code>sep</code> is the string that is inserted between 2 values. For example:</li>
</ul>
<pre><code class="lang-py"><span class="hljs-meta">&gt;&gt;&gt; </span>print(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, sep=<span class="hljs-string">'-'</span>)
<span class="hljs-number">1</span><span class="hljs-number">-2</span><span class="hljs-number">-3</span>
<span class="hljs-meta">&gt;&gt;&gt; </span>print(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>) <span class="hljs-comment"># The default value of "sep" is a space</span>
<span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span>
</code></pre>
<ul>
<li><code>end</code> is the string that is appended after the last value. For example:</li>
</ul>
<pre><code class="lang-py">print(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, end=<span class="hljs-string">'-'</span>)
print(<span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>) <span class="hljs-comment"># The default value of "end" is a newline</span>
print(<span class="hljs-string">"Hello"</span>)
</code></pre>
<p>Will print:</p>
<pre><code class="lang-bash">1 2 3-4 5 6
Hello
</code></pre>
<hr />
<p>Now that I have explained what <code>sep</code> and <code>end</code> are, let's talk about the 3rd parameter. The 3rd parameter is <code>file</code>.</p>
<p>It is a <strong>file-like object</strong> (stream). The default value of <code>file</code> is <code>sys.stdout</code> (sys is a built-in module). If you don't pass this argument, it will default to <code>stdout</code> and the output will be printed to the <strong>standard output</strong>. This is the terminal where you execute your code. The standard output is full for <code>stdout</code> (Python is implemented in C that's the reason we get to see <code>stdout</code> in Python). If you specify a value for <code>file</code>, the output will be <strong>printed to that file</strong>. For example:</p>
<pre><code class="lang-py">print(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, sep=<span class="hljs-string">"\n"</span>, file=open(<span class="hljs-string">"output.txt"</span>, <span class="hljs-string">"w+"</span>))
</code></pre>
<p>the <code>open("output.txt", "w+")</code> will create a file called <code>output.txt</code> (if it doesn't exist already) and write the output to it. So our <code>output.txt</code> file will look like this:</p>
<pre><code class="lang-bash">1
2
3
</code></pre>
<p>This <strong>allows us to write to a file directly without having to convert it to a string</strong>. It also allows us to use the <code>sep</code> and <code>end</code> parameters of the <code>print()</code> function without worrying about how to implement them.</p>
<hr />
<p>Finally, let's talk about the <code>flush</code> parameter. The <code>flush</code> parameter is a boolean value. It "flushes" the internal buffer/stream. Let's see a small example for better understanding:</p>
<pre><code class="lang-py"><span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> sleep

<span class="hljs-comment"># output is not flushed here</span>
print(<span class="hljs-string">"Hello"</span>, end=<span class="hljs-string">', '</span>)
sleep(<span class="hljs-number">5</span>)
print(<span class="hljs-string">"world!"</span>)
</code></pre>
<p>would result in:</p>
<pre><code class="lang-bash">Hello, world!
</code></pre>
<p>The output looks perfect but there is the problem: <strong>the 5-second pause</strong> that was supposed to happen between the 2 words! It is not there. We'll run the same code now, but this time we'll clear the output stream:</p>
<pre><code class="lang-py"><span class="hljs-keyword">from</span> time <span class="hljs-keyword">import</span> sleep

<span class="hljs-comment"># output is flushed this time</span>
print(<span class="hljs-string">"Hello"</span>, end=<span class="hljs-string">', '</span> flush=<span class="hljs-literal">True</span>)
sleep(<span class="hljs-number">5</span>)
print(<span class="hljs-string">"world!"</span>)
</code></pre>
<p>Now, when you run the program "Hello, " will be printed first and then after 5 seconds "world!" will be printed.</p>
<hr />
<p>That's all for now.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1651330944421/KQbguHSJR.gif" alt="That's all folks!" /></p>
]]></content:encoded></item><item><title><![CDATA[id() in python]]></title><description><![CDATA[In this post, I will try to improve your idea about memory in python using the in-built id() function. For those of you who don't know what id() is:

 The id() function returns a unique ID of the object. All objects in python have a unique ID and no ...]]></description><link>https://blog.siddhesh.cc/id-in-python</link><guid isPermaLink="true">https://blog.siddhesh.cc/id-in-python</guid><category><![CDATA[Python]]></category><dc:creator><![CDATA[Siddhesh Agarwal]]></dc:creator><pubDate>Sat, 18 Dec 2021 04:28:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1651371360247/lsuvHhfkF.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this post, I will try to improve your idea about memory in python using the in-built <code>id()</code> function. For those of you who don't know what <code>id()</code> is:</p>
<blockquote>
<p> The <code>id()</code> function returns a unique ID of the object. All objects in python have a unique ID and no 2 different values correspond to the same ID.</p>
</blockquote>
<p>So let us begin with a small example:</p>
<pre><code class="lang-py">a = b = <span class="hljs-number">500</span>
print(id(a) == id(b))
</code></pre>
<blockquote>
<p><strong>Fun fact:</strong> In python, <code>id(a) == id(b)</code> is analogous to <code>a is b</code>.</p>
</blockquote>
<p>The above code prints <code>True</code> because python creates the variable <code>b</code> with the value <code>500</code> and then creates a variable <code>a</code> pointing to the value of <code>b</code>. This implies that <code>a</code> and <code>b</code> are pointing towards the same memory location and hence the same ID.</p>
<hr />

<p>Now let's raise the bar:</p>
<pre><code class="lang-py">a = <span class="hljs-number">500</span>
b = <span class="hljs-number">500</span>
print(id(a) == id(b))
</code></pre>
<p>The above code prints <code>False</code> because: </p>
<ul>
<li>Python creates a variable <code>a</code> pointing to the value <code>500</code> in the memory. </li>
<li>Then, it creates another variable <code>b</code> pointing to another value <code>500</code> (yeah, both 500 are different).</li>
</ul>
<p>Hence, both have different IDs because both point toward different memory locations.</p>
<hr />

<p>I hope this isn't confusing because there is more to come. Guess the output for this:</p>
<pre><code class="lang-py">a = <span class="hljs-number">50</span>
b = <span class="hljs-number">50</span>
print(id(a) == id(b))
</code></pre>
<p>Some of you may think <em>"This is the previous question with different values. I know the answer is <code>False</code>"</em> but not so fast.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1651330953712/aVy-NUY-O.gif" alt="Not so fast" /></p>
<p>For small integers (The CPython range is -5 to 256, both inclusive), then integer objects (<code>&lt;class 'int'&gt;</code>) are shared. This is done entirely to save space. The memory imprint of the console would be significantly larger if these objects weren’t sharing their memory.</p>
<p>So the correct answer is <code>True</code></p>
<hr />

<p>Okay, okay. Just one more to go. The last one:</p>
<pre><code class="lang-py">a = <span class="hljs-number">500</span>
id1 = id(a)
a = <span class="hljs-number">500</span>
id2 = id(a)
print(id1 == id2)
</code></pre>
<p>Well, even though I am re-declaring the same variable with the same value, the answer is <strong>most likely</strong> to be <code>False</code>. I'll explain to you why. When you re-declare a variable in python, the interpreter works in the same way as a declaration. i.e. It entirely deletes the previous existing value and creates a variable with the new value. So when we give <code>a = 500</code>, the second time the interpreter deletes the previously existing value of <code>a</code> and creates a new memory location for <code>500</code> where <code>a</code> would point towards. Both of these IDs are most likely different.</p>
<p>SO, the answer is <code>False</code>.</p>
<p><strong>NOTE:</strong> If the above example had a number belonging to the inclusive range -5 to 256, the answer would have been <code>True</code>. this is because numbers belonging to the inclusive range have a fixed memory location.</p>
]]></content:encoded></item></channel></rss>