<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Eunice Adewusi on Medium]]></title>
        <description><![CDATA[Stories by Eunice Adewusi on Medium]]></description>
        <link>https://medium.com/@euniceadewusic?source=rss-c8751a1ad000------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*hvqcoSG97o6JQaJg</url>
            <title>Stories by Eunice Adewusi on Medium</title>
            <link>https://medium.com/@euniceadewusic?source=rss-c8751a1ad000------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 26 Jun 2026 18:00:26 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@euniceadewusic/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[My First Deep Learning Indaba & Ideathon Experience: Science, AI, and Finding My Place]]></title>
            <link>https://medium.com/@euniceadewusic/my-first-deep-learning-indaba-experience-81bdc90c31df?source=rss-c8751a1ad000------2</link>
            <guid isPermaLink="false">https://medium.com/p/81bdc90c31df</guid>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[indaba]]></category>
            <category><![CDATA[deep-learning-indaba]]></category>
            <category><![CDATA[dli2025]]></category>
            <category><![CDATA[deep-learning]]></category>
            <dc:creator><![CDATA[Eunice Adewusi]]></dc:creator>
            <pubDate>Tue, 02 Sep 2025 02:06:50 GMT</pubDate>
            <atom:updated>2025-12-19T21:59:52.540Z</atom:updated>
            <content:encoded><![CDATA[<p>Attending the <a href="https://deeplearningindaba.com/2025/">Deep Learning Indaba 2025</a> in Kigali, Rwanda, from August 17th to 22nd was truly surreal. As my very first Indaba, it felt like stepping into a space that reminded me of where I started before specializing in machine learning, where I am now as a student in the field, and where I envision myself going.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*N8bXC-zq8NZN_IsKjLNdxQ.jpeg" /><figcaption>Deep Learning Indaba Rwanda 2025</figcaption></figure><p>What made this year’s Indaba so special was not just the high-level technical sessions, but the entire experience. From the inspiring keynotes to the sponsor showcases, from engaging poster sessions to hands-on workshops, every moment was an opportunity to learn, connect, and dream bigger. The cultural dinner and the beauty of Kigali added even more depth, making it a celebration of both knowledge and community.</p><p>As a kid, I was deeply intrigued by science and studied it for six years in high school, though I left that part of me behind when I moved into tech. Recently, being named a finalist for the <a href="https://falling-walls.com/foundation/people/eunice-adewusi">Falling Walls Engage 2025 Science Engagement category</a> in Germany rekindled that early passion. At Indaba, it all came full circle when I attended Max Welling’s keynote, <em>“How AI Could Transform the Sciences.”</em></p><p>Max presented a powerful argument for <strong>#AI4Science</strong>, calling it the “fifth paradigm of scientific discovery.” He showed how AI is already proving math theorems, accelerating molecular simulations for drug discovery, and enabling breakthroughs in sustainable materials. It was a compelling reminder that AI is more than today’s applications; it is becoming a new superpower for scientists tackling humanity’s greatest challenges.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-mHBflM1Gfg49ggqNqNZGg.jpeg" /><figcaption>Sponsor Session with Google Team</figcaption></figure><p>I attended several sponsor sessions and found them highly informative and inspiring:</p><p><strong>Google Research Africa (GRA):</strong> I joined the session by Mohammed Elfatih MohamedKhair and Nasha Meoli, which focused on AI applications in disaster response, healthcare, and climate resilience. As a climate activist, I was intrigued by how GRA leverages AI to drive sustainable development and social good across Africa.</p><blockquote>Through Indaba, I was accepted into the <strong>Google Career Launchpad + DeepMind AI Research Foundations program</strong>, and I am so excited about this opportunity.</blockquote><p><strong>Microsoft Research:</strong> I attended the talk by Muchai Mercy and Millicent Ochieng on equitable AI. The discussion on reducing biases in generative models and promoting representation across languages and cultures resonated strongly with me. It helped with my interest in applying AI for climate and social impact.</p><p><strong>InstaDeep:</strong> Arnu Pretorius’ session on Geospatial Machine Learning for Good was extremely valuable. I learned about end-to-end deployment of AI solutions for climate challenges, responsible use of data, and actionable strategies for scaling projects across African contexts.</p><blockquote>I was pained that I could not attend the <strong>Research In Africa Showcase</strong> on Tuesday because I fell sick. This showcase invites researchers to present substantial, original, and impactful work addressing Africa’s unique challenges.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ll9jzRXco5KoHrstGT--VQ.jpeg" /><figcaption>3rd Workshop on Robotics and Automation in Africa</figcaption></figure><p>For workshops, I attended the <strong>3rd Workshop on Robotics and Automation in Africa</strong>, which aimed to advance robotics and machine learning research across the continent while exploring practical applications in agriculture, healthcare, energy, and manufacturing. I was fascinated by the projects, particularly <strong>Open Organic Robotics</strong>, where you simply write a prompt to build a robot; absolutely intriguing.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sC1pec3CqlOIup-hw59v8w.jpeg" /><figcaption>Tutorial - Reinforcement Learning: The Intuition Behind Policy Gradients</figcaption></figure><p>Another highlight for me was the tutorial by <strong>Arnu Pretorius, “Reinforcement Learning: The Intuition Behind Policy Gradients,” </strong>followed by the practical sessions. I recently discovered reinforcement learning and even worked on a project in it <em>(see </em><a href="https://youtu.be/e-xKJaF3pfo?t=209"><em>quick demo</em></a><em>)</em>, so choosing RL over LLMs felt natural.</p><p>The tutorial was engaging and focused on intuition rather than heavy math. It clarified fundamentals of agents, environments, rewards, and policies, and I took extensive notes.</p><p>The <a href="https://github.com/deep-learning-indaba/indaba-pracs-2025">RL practical</a>, on the other hand, was eye-opening. The questions asked and discussions sparked were proof of how brilliant and curious Africans are. For the first time, I was introduced to <strong>JAX</strong> and discovered the <em>animate</em> method that helps visualize RL agents’ behaviors. For someone used to TensorFlow, PyTorch, and VS Code over Colab, this was a breakthrough moment.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CCqlW7lMOogN0aeYPw6LZw.jpeg" /><figcaption>Indaba 2025 Participants Posters</figcaption></figure><p>Beyond the technical side, I was inspired by my fellow women winning awards left and right. As a strong intersectional feminist, I felt proud of my queens leading the way. I also saw my fellow Nigerians doing bold and innovative work like building Nollywood datasets and working on a reinforcement learning project with IoT. It reminded me of a female Nollywood producer’s call years ago to take action.</p><blockquote>What if the best dataset design didn’t come from experts but from the people living the problem every day?</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*is1nRjPnHYOH8hLSdocskA.jpeg" /></figure><p>I participated in the <strong>Ideathon</strong> with my team, pitching <strong>Ikimera (AI-Powered Multimodal Crop Disease Detection and Precision Intervention System for Smallholder Farmers)</strong>, an idea we worked on at the ALU-x-Meta-AI-Hackathon in 2024 as Team CAESA, where we came fifth with an overall score of 4.1/5.0 amongst nine teams. Launched in 2022, the Ideathon creates a unique platform where diverse pan-African teams collaborate across borders to develop groundbreaking ML projects. Congratulations to us; our improved idea has proceeded to the next stage 🎉.</p><p>🎉<strong>UPDATE:</strong> The Ikimera team, led by me, was awarded an <strong>Honourable Mention</strong> in the 2025 Deep Learning Indaba Ideathon (Applications Track).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TU8L0KTb9ItS9cruAc7Tvw.png" /><figcaption>Ikimera’s Ideathon Certificate</figcaption></figure><p>Out of 54 submissions, 11 in research and 35 in applications, we were one of the 14 teams that advanced to the review stage to pitch our project and engage in discussions with the judges.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RbZIwNAUeVQcc9tN77fP0Q.png" /><figcaption>Final stage pitch with the 2025 Indaba Ideathon Judges</figcaption></figure><p>During the final stage, teams and judges were assigned to different rooms. Among the three teams in our room, the Ikimera team emerged as the sole winner, earning us the honourable mention.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KjbiESfZUxwImEZphw7RFg.png" /><figcaption>Official Announcement on Deep Learning Indaba Website</figcaption></figure><p>The competition this year was exceptionally strong, and receiving this recognition is a significant achievement that my team is incredibly proud of. Watch our <a href="https://youtu.be/SfBcSUdnjWc"><em>demo video here</em></a> and learn more about <a href="https://deeplearningindaba.com/2025/ideathon-2025/"><em>all the 2025 Ideathon projects here</em></a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mVUjVCGEQ6wx0Q5Z9pV_HA.png" /><figcaption>Ikimera Certificate of Incorporation</figcaption></figure><p>My team decided to take things up a notch by getting legally registered in Rwanda. Now that our idea and solution have been officially validated by the Indaba Ideathon team as, in their words, “great idea and good problem space to be working in,” we lock in this coming year, 2026!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UMXEigbmcaIXVavGYM5bHw.jpeg" /><figcaption>Campus Tour with Indaba Delegates. From left to right: Mbuotidem Awak (MB), Oluwaferanmi Oladepo, &amp; Myself</figcaption></figure><p>A special part of this Indaba was hosting delegates on a tour of my campus, the African Leadership University. That simple act sparked potential collaborations with the EU in Nigeria and even opened MB’s mind to applying to CMU-Africa for graduate school.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*v8e8BKhfvG7S3-cR3yB6jw.jpeg" /><figcaption>From left to right: Chambeline Nkah, Samuel Babalola, Myself, and two other Nigerians 🇳🇬</figcaption></figure><p>As Amal Nammouchi wrote in her blog post <em>“</em><a href="https://medium.com/@amal.nammouchi12/did-you-do-your-homework-for-the-deep-learning-indaba-a698ccb2cdce"><em>Did you do your homework for the Deep Learning Indaba?</em></a><em>” which</em> I highly recommend as a pre-read for every future participant, <em>“The Indaba isn’t just one conference. It’s more like ten conferences happening at once.”</em> I felt so overwhelmed by the sheer number of things happening, but having a community changes everything. You go through the trials and tribulations together and have fun while at it 😅.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*C9z9JCvXAakTJzb0WBTYKg.jpeg" /></figure><p>Some of the lessons I carry with me from this Indaba are simple but profound:</p><ul><li>Instead of being led by the methods you know, focus on solving a specific problem.</li><li>Define clear, measurable goals and build your solution with those targets in mind.</li><li>Understand the limitations of AI, and work within those realistic boundaries.</li><li>Leverage AI as a powerful tool to create meaningful change.</li></ul><p>What an extraordinary week it has been at the 7th edition of the Deep Learning Indaba! For six days, over 1,000 of us came together under the inspiring theme <em>“Urunana (Hand in Hand) for AI in Africa.”</em></p><p>I leave this Indaba not only with new skills and ideas but also with new knowledge, new friendships, and renewed clarity about the future I want to build in AI. This was not just a conference; it was a community experience that reminded me of my roots, my passions, and the power of African voices shaping AI for the world. I look forward to the ripple effect of the inspiration I received in my work with the <a href="https://lnk.bio/cr_foundation"><strong>Climiradi Roberts Foundation</strong></a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MmQRwKM5nmFSKeICfW2Mxw.jpeg" /></figure><p>To the organizers: I am deeply grateful for creating a space that combines <a href="https://deeplearningindaba.us11.list-manage.com/track/click?u=1011d772d48def6e742e87136&amp;id=fb25fba9d8&amp;e=d9c6748641">technical learning</a>, community engagement, and cultural celebration. I hope the Indaba continues to expand opportunities for interaction, mentorship, and hands-on projects, especially for first-time attendees and participants from underrepresented regions. I would be excited to contribute to future events in any way I can.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LgSDqFD_6UgdjNKzRc_lNA.jpeg" /><figcaption>Indaba 2025 In-person Participants</figcaption></figure><p>To the Indaba community: Being part of Africa’s largest gathering of AI minds was an honor. The brilliance, creativity, and passion of participants reminded me of the talent Africa has to offer. Stay curious, problem-driven, and collaborative, and continue building solutions that address real challenges in our communities.</p><p>PS: I think we can all agree that there’s a special glow that comes with attending Indaba; see for yourself :)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7zINbM1PN2_USuXL6F-JvA.jpeg" /><figcaption>Me, Myself &amp; I</figcaption></figure><p>If you’ve attended Indaba before, don’t lose your spark, and if you will be attending for the first time, let’s meet at subsequent Indaba(s). Until then, keep building!</p><p><em>My Links: </em><a href="https://linktr.ee/climiradi"><em>https://linktr.ee/climiradi</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=81bdc90c31df" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Deep Learning 101: Optimisation in Machine Learning]]></title>
            <link>https://medium.com/@euniceadewusic/deep-learning-101-optimisation-in-machine-learning-fcee8dea7d67?source=rss-c8751a1ad000------2</link>
            <guid isPermaLink="false">https://medium.com/p/fcee8dea7d67</guid>
            <category><![CDATA[artificial-neural-network]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[machine-learning-ai]]></category>
            <dc:creator><![CDATA[Eunice Adewusi]]></dc:creator>
            <pubDate>Mon, 17 Feb 2025 13:04:35 GMT</pubDate>
            <atom:updated>2025-02-17T14:55:55.744Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>If you have ever thought about how those fancy AI models like ChatGPT, Claude, Gemini, or even DeepSeek learn so quickly, this post is for you.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1010/1*kG_cGEa6jJKUB-0Gj91wyQ.png" /><figcaption>Image from my Water Potability project -<em> L2 Regularised model using SGD (Stochastic Gradient Descent). The plots illustrate how the model improves over time, balancing generalisation and overfitting.</em></figcaption></figure><p>You are here because you still struggle with slow learning models, exploding gradients, or training instability. You see, a fast learning model is not just about having massive dataset; it is also about using clever optimisation techniques.</p><blockquote>Think of it like this: training a deep learning model is like teaching a dog a new trick. You need patience, the right approach, and maybe a few treats along the way. Optimisation techniques act as “you- the coach” that refine these models, ensuring they learn efficiently from data.</blockquote><p>You know, in my recent Water Potability project, I used an L2 Regularised Model with the SGD (Stochastic Gradient Descent) optimiser. Over time, the model learned to make better predictions, decreasing the loss and increasing the accuracy (as shown in the image above). This process is heavily influenced by the choice of optimisation technique.</p><p>In this post, we will demystify some of the most popular optimisation techniques used in deep learning. We will break down what they do, how they work, and when to use them. No complicated jargon, just plain English (and maybe a little bit of Python!).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/220/1*Ou4c243Pic455MShe3Bwlw.gif" /><figcaption>Come on!</figcaption></figure><p>Before we get started, let’s define our key word: <em>Optimisation techniques</em>.</p><p><strong>What are Optimisation Techniques?</strong></p><p>Optimisation techniques are like the secret sauce behind successful deep learning models. They are algorithms and methods used to adjust the parameters of a model (think of them as knobs and dials) to minimise the difference between the model’s predictions and the actual values (the error). By fine-tuning these parameters, the model gradually learns to make more accurate predictions. Optimisation techniques play a vital role in training deep learning models efficiently and effectively, enabling them to solve complex problems across various domains.</p><p>Imagine you are trying to sculpt a statue, and you start with a big block of marble. Optimisation techniques are like the different tools you use — the chisel, the hammer, the file — to gradually shape the marble into the desired form.</p><p><strong>Common Optimisation Techniques</strong></p><h4>1. Feature Scaling or Normalisation: Getting Your Data in Shape</h4><p>Imagine trying to build a house with bricks of all different sizes and shapes. It would be a nightmare, right? Feature scaling is like making sure all your bricks are the same size so your model can build a solid foundation.</p><p><strong>Mechanics:</strong> Feature scaling involves transforming the range of your features (input variables). Two common methods are:</p><ul><li><strong>Min-Max Scaling (Rescaling/Min-Max Normalisation):</strong> Scales values to a range between 0 and 1. <strong><em>Formula: </em></strong><em>x_scaled = (x - x_min) / (x_max - x_min)</em></li><li><strong>Standardisation (Z-score normalisation):</strong> Scales values to have a mean of 0 and a standard deviation of 1. <strong><em>Formula:</em></strong><em> </em><em>x_scaled = (x - mean) / standard_deviation</em></li></ul><p><strong>Example:</strong></p><pre>import numpy as np<br>from sklearn.preprocessing import MinMaxScaler, StandardScaler<br><br># Sample data<br>data = np.array([[1, 10], [2, 20], [3, 30]])<br><br># Min-Max Scaling<br>scaler = MinMaxScaler()<br>scaled_data = scaler.fit_transform(data)<br>print(&quot;Min-Max Scaled Data:\n&quot;, scaled_data)<br><br># Standard Scaler<br>scaler = StandardScaler()<br>scaled_data = scaler.fit_transform(data)<br>print(&quot;Standard Scaled Data:\n&quot;, scaled_data)</pre><blockquote>Other feature scaling techniques are <strong>Mean Normalisation</strong>, where values are centered around the mean and scaled between -1 and 1. <strong><em>Formula: </em></strong><em>x_p = (x - mean) / (x_max - x_min)</em></blockquote><blockquote>Another method is <strong>Unit Length Normalisation</strong>, which transforms feature values into unit vectors by dividing by their <strong>L2 norm</strong> (Euclidean distance) or <strong>L1 norm</strong> (sum of absolute values). <strong><em>Formula: </em></strong><em>x_p = x / ||x||_2</em> or <em>x_p = x / ||x||_1</em></blockquote><blockquote>These methods are useful in cases where the magnitude of features matters, such as text classification and clustering algorithms.</blockquote><p><strong>Pros:</strong></p><ul><li><strong>Faster Convergence:</strong> Helps gradient descent converge faster.</li><li><strong>Improved Accuracy:</strong> Prevents features with larger values from dominating the learning process.</li><li><strong>Better for Algorithms Sensitive to Feature Scales: </strong>Essential for algorithms like Support Vector Machines (SVMs) and k-Nearest Neighbors (KNN).</li></ul><p><strong>Cons:</strong></p><ul><li><strong>Not Always Necessary: </strong>Algorithms like decision trees are not affected by feature scaling.</li><li><strong>Can Distort Data:</strong> Outliers can have a significant impact on the scaled range.</li></ul><blockquote><strong>Note:</strong> Not all machine learning algorithms require Feature Scaling</blockquote><h4>2. Batch Normalisation: Keeping Things Stable</h4><p>Batch normalisation is like adding a stabiliser to a shaky camera, it helps to keep the image clear and steady, even when things get a little bumpy. It helps to stabilise the learning process and allows you to use higher learning rates.</p><p><strong>Mechanics:</strong></p><ul><li>Batch normalisation standardises the output of each hidden layer by applying <strong>Z-score normalisation</strong> to the pre-activated output.</li><li>Calculates the mean and variance of the output in the mini-batch.</li><li>Instead of just applying standard normalisation (i.e., setting the mean to 0 and variance to 1), we introduce learnable parameters: <strong>gamma</strong> (scaling factor) and <strong>beta</strong> (shifting factor).</li><li>This makes the process more flexible, allowing the network to <em>scale and shift the normalised values as needed to retain useful patterns</em>.</li></ul><blockquote><strong><em>Formula: </em></strong><em>z_bn = gamma * z_norm + beta</em></blockquote><blockquote>where, <strong>z_norm</strong> is the normalised pre-activated output, <strong>gamma</strong> and <strong>beta</strong> are parameters learned during training</blockquote><p>By doing this, batch normalisation helps to maintain the stability of the learning process and improves convergence speed, even with higher learning rates.</p><p><strong>Pros:</strong></p><ul><li><strong>Higher Learning Rates</strong>: Allows for faster training and can be paired with other optimisation methods like SGD w/ momentum, RMSprop, and Adam.</li><li><strong>Deeper Networks with Shorter Training Time</strong>: Facilitates building deeper networks without increasing training time significantly.</li><li><strong>Stability with Large Batch Sizes</strong>: Maintains stability, especially when working with larger batch sizes.</li><li><strong>Reduced Internal Covariate Shift</strong>: Helps make the learning process more stable, improving the overall performance.</li><li><strong>Regularisation Effect</strong>: Adds regularising effects, potentially reducing the need for additional regularisation techniques like dropout, early stopping, or batch normalisation, because it already imposes a form of control on the model’s complexity, depending on the specific model and problem being addressed.</li></ul><p><strong><em>Regularisation techniques</em></strong><em> produce </em><strong><em>regularising effects</em></strong><em> like improved generalisation, reduced overfitting, stabilised learning process, and improved convergence speed.</em></p><p><strong>Cons:</strong></p><ul><li><strong>Increased Complexity:</strong> Adds extra parameters to the model.</li><li><strong>Mini-Batch Dependency: </strong>Performance can be affected by small batch sizes.</li><li>Not good for RNNs <strong><em>(Recurrent Neural Networks)</em></strong> / LSTMs (<strong><em>Long Short-Term Memory</em></strong><em> networks</em>).</li><li>Have to use a different calculation between training and testing.</li></ul><h4>3. Mini-Batch Gradient Descent or Stochastic Gradient Descent (SGD): Taking Smaller Steps</h4><p>Imagine climbing a mountain, but instead of trying to leap to the summit in one go, you take lots of small, manageable steps. That is mini-batch gradient descent!</p><p><strong>Mechanics:</strong></p><ul><li>Splits the training data into smaller batches (mini-batches).</li><li><strong>Perform Back-propagation: </strong>Calculates the gradient of the loss function for each mini-batch. Completing back-prop on all mini-batches is an <strong><em>epoch</em></strong>. Some forms randomise the data at the beginning of each epoch.</li><li>Updates the model’s parameters based on the average gradient across the mini-batch.</li></ul><p><strong>Pros:</strong></p><ul><li><strong>Faster Updates:</strong> This means <strong>speeding up gradient descent</strong> because the parameters are updated more frequently than in <strong>batch gradient descent</strong>, where updates only happen after processing the entire dataset. In mini-batch gradient descent, updates are made after each mini-batch, speeding up the convergence process.</li><li><strong>Less Memory Intensive:</strong> Requires less memory than batch gradient descent.</li><li><strong>Escapes Local Minima:</strong> The noise introduced by mini-batches can help the model escape local minima, giving it a more stable convergence.</li></ul><p><strong>Cons:</strong></p><ul><li><strong>Hyperparameter Tuning</strong>: Requires selecting an appropriate mini-batch size, which can be difficult to determine.</li><li><strong>Noisy Updates</strong>: Updates tend to be noisier compared to batch gradient descent, leading to more fluctuation in the learning process.</li><li><strong>Optimisation Challenges</strong>: Can struggle with saddle points, ravines, and local optima, making it harder to find the global minimum.</li></ul><blockquote>Saddle points, ravines, and local optima are types of regions in the loss landscape of a neural network: <strong>saddle points</strong> are where the gradient is zero but they are not minima (the surface curves up in some directions and down in others), <strong>ravines</strong> are steep, narrow areas that can slow down convergence due to large gradients in one direction and small gradients in another, and <strong>local optima</strong> are points where the loss function is lower than in neighbouring areas but not necessarily the lowest point overall (which is the global optimum).</blockquote><h4>4. SGD w/ Momentum: Speeding Things Up</h4><p>Stochastic Gradient Descent (SGD) with Momentum is like a car accelerating downhill. Once it picks up speed, it keeps going faster, even if you briefly take your foot off the pedal. It helps the model converge more quickly by reducing oscillations and speeding up the learning process.</p><p><strong>Mechanics:</strong></p><p>Momentum builds on the idea of storing a running average of past gradients, allowing the model to keep moving in the same direction and avoid unnecessary back-and-forth adjustments.</p><blockquote><strong><em>Formula:</em></strong></blockquote><blockquote><em>v_t = beta * v_t-1 + alpha * Grad(w)</em></blockquote><blockquote><em>w = w — v_t</em></blockquote><blockquote>Where: <strong>v_t</strong>​ is the velocity (momentum), <strong>beta </strong>is the momentum coefficient (usually between 0.8 and 0.99), <strong>alpha </strong>is the learning rate, and <strong>Grad(w)</strong> is the gradient of the loss with respect to the weights.</blockquote><p>By using the previous gradients, the model gains momentum in directions with consistent gradients, leading to faster and more stable convergence.</p><p><strong>Pros:</strong></p><ul><li><strong>Faster Convergence: </strong>Helps the model reach optimal weights more quickly.</li><li><strong>Reduces Oscillations:</strong> More stable learning, particularly in areas with high curvature like ravines and local optima.</li><li><strong>Smoother Updates:</strong> Helps escape shallow local minima by smoothing out updates.</li></ul><p><strong>Cons:</strong></p><ul><li><strong>Hyperparameter Sensitivity:</strong> Requires tuning the momentum and learning rate.</li><li><strong>Can Over-Accelerate:</strong> Too much momentum can cause the model to overshoot the minimum. One has to remember to scale down the learning rate by a factor of (1 — beta)</li></ul><h4>5. Gradient Descent with Momentum: Remembering the Past</h4><p>Back to the mountain analogy — Imagine that as you are climbing that mountain, you remember the direction you were previously heading. That is momentum! It helps you to keep moving in the right direction and avoid getting stuck in small dips.</p><p><strong>Mechanics:</strong></p><ul><li>Adds a fraction of the previous update to the current update.</li><li>Helps to accelerate gradient descent in the relevant direction and dampen oscillations.</li></ul><p><strong>Pros:</strong></p><ul><li><strong>Faster Convergence: </strong>Can converge faster than standard gradient descent.</li><li><strong>Reduces Oscillations: </strong>Dampens oscillations in the learning process.</li><li><strong>Escapes Local Minima:</strong> Can help the model escape local minima.</li></ul><p><strong>Cons:</strong></p><ul><li><strong>Additional Hyperparameter:</strong> Requires tuning the momentum parameter.</li></ul><h4>6. RMSProp Optimisation: Adapting to the Terrain</h4><p>RMSProp is like having a smart hiking pole that adjusts to the terrain. If the slope is steep, it shortens your stride; if it is shallow, it lengthens it.</p><p>Divide the gradient by the square <strong>root</strong> of the moving (propagated) average (<strong>mean</strong>) of the <strong>square</strong> of the gradient</p><blockquote><strong><em>Formula:</em></strong></blockquote><blockquote><em>s_t = beta * s_t-1 + (1-beta)square(Grad(w))</em></blockquote><blockquote><em>w_t = w_t-1—alpha * Grad(w) / sqrt(s_t)</em></blockquote><p><strong>Mechanics:</strong></p><ul><li>Adapts the learning rate for each parameter based on the historical squared gradients.</li><li>Divides the learning rate by the root mean square of the past gradients.</li></ul><p><strong>Pros:</strong></p><ul><li><strong>Handles Sparse Gradients and Faster Convergence</strong>: Well-suited for problems with sparse gradients, enabling faster convergence compared to standard gradient descent.</li><li><strong>Reduces Oscillations and Helps with Ravines/Saddle Points</strong>: Reduces oscillations in the learning process, making it easier to navigate challenging regions like ravines and saddle points.</li><li><strong>Allows Larger Learning Rates</strong>: The stability and faster convergence enable the use of larger learning rates without overshooting.</li></ul><p><strong>Cons:</strong></p><ul><li><strong>Hyperparameter Tuning: </strong>Requires tuning the learning rate and decay rate.</li></ul><h4>7. Adam Optimisation: The Best of Both Worlds</h4><p>Adam is like having a combination of SGD w/ momentum and RMSProp, it is like the ultimate hiking companion!</p><blockquote><strong><em>Formula:</em></strong></blockquote><blockquote><em>m_t = beta1 * m_t-1 + (1-beta1) * Grad(w); v_t = beta2 * v_t-1 + (1-beta2) * (Grad(W)^ 2)</em></blockquote><blockquote><em>m_tnorm = m_t / (1 — (beta1 ^ t)); v_tnorm = m_t/ 1-(beta2 ^ t))</em></blockquote><blockquote><em>w_t = w_t-1 — alpha * m_tnorm / sqrt(v_tnorm)</em></blockquote><p><strong>Mechanics:</strong></p><ul><li>Combines the ideas of momentum and RMSProp.</li><li>Calculates an exponentially decaying average of past gradients and squared gradients.</li><li>Adapts the learning rate for each parameter based on these averages.</li></ul><p><strong>Pros:</strong></p><ul><li><strong>Fast Convergence</strong>: Often converges faster than other optimisation algorithms, especially in cases with sparse gradients and ravines.</li><li><strong>Adaptive Learning Rates</strong>: Adapts the learning rate for each parameter, making it efficient for problems with sparse gradients and online learning.</li><li><strong>Good at Navigating Ravines and Saddle Points</strong>: Particularly effective in avoiding local minima and accelerating optimisation in areas with complex landscape.</li></ul><p><strong>Cons:</strong></p><ul><li><strong>More Complex:</strong> More complex than other optimisation algorithms.</li><li><strong>Hyperparameter Tuning:</strong> Requires tuning multiple hyperparameters.</li></ul><blockquote><strong>Note</strong>:</blockquote><blockquote>Adam does not always achieve the optimal results relative to other optimisation methods.</blockquote><blockquote>When using RMSprop or Adam optimisers, it is essential to include a small epsilon value in the denominator to prevent division by zero.</blockquote><h4>8. Learning Rate Decay: Slowing Down to Reach the Goal</h4><p>Imagine that as you get closer to the summit of the mountain, you start taking smaller and smaller steps. That is learning rate decay! It helps you to fine-tune your position and avoid overshooting the peak.</p><p><strong>Mechanics:</strong></p><ul><li>Gradually reduces the learning rate as it approaches the optimum during training so that it does not overshoot</li><li>Can be implemented using various schedules, such as step decay, exponential decay, or cosine annealing.</li></ul><p><strong>Learning Rate Decay Methods:</strong></p><ol><li><strong>Exponential decay:</strong> <em>lr = lr_0 * e^(-d * t)</em></li></ol><p><em>The learning rate decreases exponentially over time, controlled by a decay factor </em><em>d and time step </em><em>t. This method allows for smooth decay as the training progresses.</em></p><p>2. <strong>Time-based decay:</strong> <em>lr = lr_0 / (1 + d*t)</em></p><p><em>The learning rate decreases gradually over time. The rate of decay depends on the decay factor </em><em>d and time step </em><em>t, ensuring that the learning rate decreases over epochs but at a slower pace compared to exponential decay.</em></p><p>3. <strong>Step decay:</strong> <em>lr = lr_0 * d^(epoch // epoch_drops)</em></p><p><em>The learning rate is reduced by a factor </em><em>d after a fixed number of epochs (defined by epoch_drops). This creates a more sudden decrease in the learning rate at certain intervals.</em></p><p><strong>Pros:</strong></p><ul><li><strong>Improved Convergence:</strong> Can help the model converge to a better solution.</li><li><strong>Fine-Tuning: </strong>Allows for fine-tuning the model’s parameters in the later stages of training.</li></ul><p><strong>Cons:</strong></p><ul><li><strong>Hyperparameter Tuning:</strong> Requires tuning the decay rate and schedule, which can be challenging due to the large number of hyperparameters.</li><li>Difficult to determine when the learning rate should drop during training.</li><li>Traditional methods lack adaptability, making them less efficient compared to adaptive learning rate optimisation methods like RMSprop and Adam.</li></ul><p>Since I used L2 regularisation in my Water Potability project, you may be curious about what it does. Read about it in my previous blog post <a href="https://medium.com/@euniceadewusic/how-to-prevent-overfitting-in-machine-learning-8f8cbe4b4b25">here</a>.</p><p>So, there you have it! A tour of some common optimisation techniques. Remember, choosing the right optimisation technique depends on your specific problem and dataset and experimentation is key!</p><p>The more you understand them, the better equipped you will be to build powerful and accurate models. Even with the best tools, it takes practice to master the art of deep learning!</p><p><em>As Albert Einstein once said, “If you can’t explain it simply, you don’t understand it well enough.” </em>I hope this post has helped simplify these concepts for you.</p><p>Let’s meet again in my next post to unravel another AI/ML mystery :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fcee8dea7d67" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Prevent Overfitting in Machine Learning]]></title>
            <link>https://medium.com/@euniceadewusic/how-to-prevent-overfitting-in-machine-learning-8f8cbe4b4b25?source=rss-c8751a1ad000------2</link>
            <guid isPermaLink="false">https://medium.com/p/8f8cbe4b4b25</guid>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[machine-learning-ai]]></category>
            <category><![CDATA[ai-ml-solution]]></category>
            <dc:creator><![CDATA[Eunice Adewusi]]></dc:creator>
            <pubDate>Mon, 17 Feb 2025 03:18:24 GMT</pubDate>
            <atom:updated>2025-02-17T03:27:12.507Z</atom:updated>
            <content:encoded><![CDATA[<p>Ever built a machine learning model that performs really well on your training data but then completely bombs when you throw new data at it? You are not alone! This is a classic problem called <strong>overfitting</strong>, and it is like training a student so well on the practice exam that they can’t answer anything on the real test if the questions are worded slightly differently.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*E2XzQNSCpEfaG5RQAnXxqg.png" /><figcaption>Source: GeeksforGeeks</figcaption></figure><p>One of the most effective ways to combat overfitting is by <strong>using regularisation techniques.</strong></p><blockquote>Think of regularisation as adding a little bit of “noise” or a constraint to your model’s learning process, preventing it from memorising the training data and forcing it to learn more generalisable patterns.</blockquote><p>In this blog post, we will explore some popular regularisation techniques, breaking down the mechanics, pros, and cons of each. Let’s dive in!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/220/1*K5Eaulz7IyJHRTfPTyL2iA.gif" /></figure><p>Before jumping into the techniques, let’s solidify our understanding of overfitting. Imagine you are trying to fit a curve to some data points.</p><ul><li><strong><em>What is Overfitting?</em></strong></li></ul><p>An overfit model is like drawing a super wiggly line that passes through every single data point, even the outliers (noisy data). While it perfectly matches the training data, it won’t generalise well to new, unseen data.</p><p>Regularisation helps us find a “sweet spot” — a curve that fits the data reasonably well without being overly complex.</p><p><strong>Now, let’s meet the regularisation techniques.</strong></p><h4>1. L1 Regularisation (Lasso Regression)</h4><p>L1 regularisation adds a penalty to the cost function of your model based on the absolute value of the coefficients (weights) of the features. The cost function is what the model is trying to minimise during training.</p><p>Mathematically, it looks like this:</p><blockquote>Cost Function = Original Cost Function + λ * Σ |coefficients|</blockquote><blockquote>Where:</blockquote><blockquote>λ (lambda) is the regularisation parameter (a hyperparameter you need to tune). A larger λ means a stronger penalty.</blockquote><blockquote>Σ |coefficients| is the sum of the absolute values of all the model&#39;s coefficients.</blockquote><p><strong>Pros:</strong></p><ul><li><strong>Feature Selection:</strong> L1 regularisation can drive some coefficients to exactly zero. This effectively performs feature selection, as features with zero coefficients are removed from the model. This can lead to simpler, more interpretable models.</li><li><strong>Sparsity:</strong> L1 regularisation promotes sparsity in the model, meaning it encourages a model with fewer non-zero coefficients.</li></ul><p><strong>Cons:</strong></p><ul><li><strong>Non-Differentiable:</strong> The absolute value function is not differentiable at zero, which can cause some optimisation challenges.</li><li><strong>Can be unstable:</strong> In situations where features are highly correlated, L1 regularisation may arbitrarily select one feature over another.</li></ul><p><strong>Example:</strong></p><p><em>Imagine you are building a model to predict house prices. You have features like square footage, number of bedrooms, location, and the color of the front door. L1 regularisation might identify that the color of the front door is not a significant predictor and set its coefficient to zero, effectively removing it from the model.</em></p><h4>2. L2 Regularisation (Ridge Regression)</h4><p>L2 regularisation is similar to L1, but instead of penalising the absolute value of the coefficients, it penalises the square of the coefficients.</p><p>Mathematically:</p><blockquote>Cost Function = Original Cost Function + λ * Σ (coefficients)^2</blockquote><p><strong>Pros:</strong></p><ul><li><strong>Differentiable:</strong> The squared term is differentiable, making it easier to optimise.</li><li><strong>Reduces Overfitting:</strong> L2 regularisation shrinks the coefficients towards zero, preventing any single feature from dominating the model and reducing overfitting.</li></ul><p><strong>Cons:</strong></p><ul><li><strong>No Feature Selection:</strong> L2 regularisation doesn’t force coefficients to zero, so it doesn’t perform feature selection. All features are kept in the model, although their impact is reduced.</li><li><strong>Less Robust to Outliers:</strong> Because it squares the coefficients, L2 regularisation is more sensitive to outliers than L1 regularisation.</li></ul><p><strong>Example:</strong></p><p><em>Again, consider predicting house prices. L2 regularisation will shrink the impact of all features (square footage, bedrooms, location, etc.) but won’t eliminate any of them completely. This prevents the model from relying too heavily on any single feature.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/635/1*v4eF8gzhhZVGBHKVelI_kg.png" /><figcaption>Source: BotPenguin</figcaption></figure><h4>3. Dropout</h4><p>Dropout is a regularisation technique specifically used in neural networks. During training, dropout randomly “drops out” (sets to zero) a certain percentage of neurons in a layer. This means these neurons are temporarily ignored during that training iteration.</p><p><strong>Pros:</strong></p><ul><li><strong>Prevents Co-adaptation:</strong> Dropout prevents neurons from becoming overly reliant on each other. Each neuron is forced to learn more robust and independent features.</li><li><strong>Simple to Implement:</strong> Dropout is relatively easy to implement in most deep learning frameworks.</li></ul><p><strong>Cons:</strong></p><ul><li><strong>Increases Training Time:</strong> Because dropout effectively creates a different network for each training iteration, it can increase training time.</li><li><strong>Inference Time Adjustment:</strong> During inference (when you are using the trained model to make predictions), you need to adjust the activations of the neurons to account for the fact that dropout was used during training.</li></ul><p><strong>Example:</strong></p><p><em>Imagine a neural network trying to recognise faces. Without dropout, some neurons might learn to only activate when they see a specific combination of features (e.g., a particular nose shape and eye spacing). Dropout forces other neurons to learn to recognise faces even when those specific features are missing, making the model more robust.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9XkkKpqhDcnarj5JW1uQmA.jpeg" /><figcaption>Source: ingoampt</figcaption></figure><h4>4. Data Augmentation</h4><p>Data augmentation involves creating new training data by applying various transformations to the existing data. These transformations could include:</p><ul><li><strong>Image Data:</strong> Rotations, flips, zooms, crops, color adjustments.</li><li><strong>Text Data: </strong>Synonym replacement, random insertion, deletion, or swapping of words.</li><li><strong>Audio Data: </strong>Adding noise, time stretching, pitch shifting.</li></ul><p><strong>Pros:</strong></p><ul><li><strong>Increases Dataset Size:</strong> Data augmentation artificially increases the size of your training dataset, which can significantly improve model performance, especially when you have limited data.</li><li><strong>Improves Generalisation:</strong> By exposing the model to variations of the training data, data augmentation helps it learn more robust and generalisable features.</li></ul><p><strong>Cons:</strong></p><ul><li><strong>Can Introduce Noise:</strong> If not done carefully, data augmentation can introduce unrealistic or irrelevant variations, which can hurt model performance.</li><li><strong>Requires Domain Knowledge:</strong> Choosing appropriate data augmentation techniques requires some understanding of the underlying data and the problem you’re trying to solve.</li></ul><p><strong>Example:</strong></p><p><em>If you are training a model to recognise cats, you could augment your data by rotating the cat images, flipping them horizontally, zooming in, or changing the brightness. This helps the model learn to recognise cats in different poses, lighting conditions, and angles.</em></p><h4>5. Early Stopping</h4><p>Early stopping involves monitoring the performance of your model on a validation set during training. Training is stopped when the performance on the validation set starts to degrade (i.e., the validation loss starts to increase).</p><blockquote>The validation set is a portion of your data that is not used for training but is used to evaluate the model’s performance</blockquote><p><strong>Pros:</strong></p><ul><li><strong>Simple and Effective: </strong>Early stopping is a very simple and effective way to prevent overfitting.</li><li><strong>Reduces Training Time:</strong> By stopping training early, you can save significant time and computational resources.</li></ul><p><strong>Cons:</strong></p><ul><li><strong>Requires a Validation Set:</strong> Early stopping requires you to split your data into training and validation sets, which reduces the amount of data available for training.</li><li><strong>Sensitivity to Validation Set:</strong> The performance of early stopping can be sensitive to the choice of the validation set.</li></ul><p><strong>Example:</strong></p><p><em>You are training a neural network. After each epoch (a complete pass through the training data), you evaluate the model on the validation set. You notice that the validation loss is decreasing for the first 10 epochs, but then it starts to increase. Early stopping would stop the training at epoch 10, preventing the model from overfitting to the training data.</em></p><p>Regularisation is a crucial tool in machine learning. Knowing when to use <strong>L1 Regulariser (Lasso Regression)</strong> for feature selection, <strong>L2 Regulariser (Ridge Regression)</strong> for reducing overfitting, <strong>Dropout</strong> for deep learning, <strong>Data Augmentation</strong> for expanding datasets, and <strong>Early Stopping</strong> for efficient training can make or break your model’s performance.</p><p>Experiment with these techniques and find what works best for your specific problem. Happy modeling, and I will see you in the next post!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8f8cbe4b4b25" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My Journey as a Python Developer Intern at Oasis Infobyte]]></title>
            <link>https://medium.com/@euniceadewusic/my-journey-as-a-python-developer-intern-at-oasis-infobyte-e7faca0b4812?source=rss-c8751a1ad000------2</link>
            <guid isPermaLink="false">https://medium.com/p/e7faca0b4812</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[summer-internships]]></category>
            <category><![CDATA[python-programming]]></category>
            <category><![CDATA[python-web-developer]]></category>
            <category><![CDATA[oasis-infobyte-internship]]></category>
            <dc:creator><![CDATA[Eunice Adewusi]]></dc:creator>
            <pubDate>Tue, 23 Jul 2024 16:37:12 GMT</pubDate>
            <atom:updated>2024-07-23T16:39:07.675Z</atom:updated>
            <content:encoded><![CDATA[<p>As my internship at Oasis Infobyte comes to an end, I reflect on the incredible journey and learning experiences that have shaped my skills and deepened my love for Python programming. This internship provided me with the opportunity to work on three distinct projects, each presenting unique challenges and learning opportunities.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EeRWoBcEGDtskQtWq7ngug.png" /><figcaption>Me! Me!! Me!!!</figcaption></figure><p>Come with me, as I share insights from my internship, detailing the projects I worked on and the valuable lessons learned along the way.</p><blockquote><em>Project 1: Random Password Generator</em></blockquote><p>The first project I tackled was developing a Random Password Generator. This command-line tool was designed to help users generate secure passwords based on specific criteria. It was a fantastic introduction to Python, allowing me to explore concepts like randomisation, user input validation, and character set handling.</p><p>Key Features:</p><ul><li>Random Password Generation: Creates passwords with a specified length and character set.</li><li>Character Types: Includes options for uppercase and lowercase letters, numbers, and symbols.</li><li>User Input Validation/Error Handling: Ensures valid input for password length and character types.</li></ul><p>Learning Outcomes:</p><p>This project taught me the importance of secure coding practices and user input validation, both critical for creating reliable software applications.</p><ul><li>Mastery of Python’s random module for generating random characters.</li><li>Developing robust input validation to ensure user inputs meet specific criteria.</li><li>Enhancing user experience by incorporating error handling mechanisms.</li></ul><p>Demo Video:</p><ul><li>YouTube | Click <a href="https://youtu.be/7uCQfN4d4Bk?si=UpnD9P-RcTv1Zcax">Here</a></li></ul><blockquote><em>Project 2: Voice Assistant — Asiri</em></blockquote><p>Building Asiri, a semi-advanced voice assistant, was a really challenging yet rewarding experience. Asiri can respond to various voice commands, perform web searches, play YouTube videos, send emails, and provide interesting facts, making it a versatile assistant. This project was particularly exciting as it combined multiple functionalities and required integrating several Python libraries.</p><p>Key Features:</p><ul><li>Greeting Response: The assistant responds to greetings.</li><li>Date and Time: Provides the current date and time.</li><li>Web Search: Searches the web for information and reads out the results.</li><li>YouTube Video Playback: Plays videos based on user commands.</li><li>Email Sending: Sends emails as per user requests.</li><li>Interesting Facts: Shares interesting facts with the user.</li></ul><p>Learning Outcomes:</p><p>Working on Asiri enhanced my understanding of natural language processing and integrating various APIs to build a functional voice assistant.</p><ul><li>Implementing voice recognition and processing using Python.</li><li>Integrating web scraping for information retrieval.</li><li>Managing asynchronous tasks to handle multiple commands efficiently.</li></ul><p>Demo Video:</p><ul><li>YouTube | Click <a href="https://youtu.be/-T0gJqJ0NUo?si=rIGm6Z6yzIYq4sOi">Here</a></li></ul><blockquote><em>Project 3: BMI Calculator</em></blockquote><p>The final project was the BMI Calculator, a command-line tool that calculates the Body Mass Index based on user inputs for weight and height. It helps the users to understand their BMI and its classification according to Wikipedia health standards.</p><p>Key Features:</p><ul><li>User-friendly Interface: Simple and intuitive command-line interactions.</li><li>Input Validation: Ensures valid entries for weight and height.</li><li>BMI Calculation: Accurately calculates BMI using the standard formula.</li><li>Classification: Categorises BMI into health ranges (Underweight, Normal weight, Overweight, Obesity). It also sub-classify these categories into different classes like Severe Thinness, Class III Obesity, etc</li></ul><p>Learning Outcomes:</p><p>This project reinforced the importance of user input validation and provided insights into developing health-related applications.</p><ul><li>Accurate implementation of mathematical formulas in Python.</li><li>Enhancing user experience through clear prompts and feedback.</li><li>Categorising and interpreting BMI results for health awareness.</li></ul><p>Demo Video:</p><ul><li>YouTube | Click <a href="https://youtu.be/WGevpQAsOmk?si=h1Y0La4Bvg1mGcT0">Here</a></li></ul><h3>Reflections and Future Directions</h3><p>This internship has been an invaluable experience. It provided me with hands-on experience in Python development, enabling me to work on projects that are both functional and educational. Each project taught me something new, from secure coding practices to integrating APIs and validating user input.</p><p>As I look to the future, I am excited about the endless possibilities that Python offers. I am particularly interested in exploring more advanced topics like machine learning and artificial intelligence, where I can further integrate my love for technology with impactful real-world applications.</p><p>I am deeply grateful to <a href="https://www.linkedin.com/in/oasis-infobyte-478338228/">Oasis Infobyte</a> for this opportunity and for the supportive environment that fostered my growth. Thank you to my supervisor, <a href="https://www.linkedin.com/in/oreolnoumodong/">Oreol Noumodong</a> &amp; friend, <a href="https://www.linkedin.com/in/emmanuel-obolo/">Emmanuel Obolo</a> for their never-ending encouragement. This experience has reaffirmed my commitment to continuous learning and innovation in the field of technology.</p><p>Contact Information:</p><p>If you have any questions, feedback, or collaboration requests, please feel free to reach out to me at;</p><ul><li>Email: <a href="mailto:e.adewusi@alustudent.com">e.adewusi@alustudent.com</a></li><li>Links: <a href="https://linktr.ee/climiradi">https://linktr.ee/climiradi</a></li><li>Oasis Infobyte: <a href="http://oasisinfobyte.com/">http://oasisinfobyte.com/</a></li><li>GitHub: <a href="https://github.com/eadewusic">https://github.com/eadewusic</a></li></ul><p>Thank you for taking the time to read about my journey. Stay tuned for more updates and feel free to share your thoughts and experiences!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e7faca0b4812" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Understanding Class and Instance Attributes in Python]]></title>
            <link>https://medium.com/@euniceadewusic/understanding-class-and-instance-attributes-in-python-e3ae12eb3e66?source=rss-c8751a1ad000------2</link>
            <guid isPermaLink="false">https://medium.com/p/e3ae12eb3e66</guid>
            <category><![CDATA[python-dict]]></category>
            <category><![CDATA[class-attribute]]></category>
            <category><![CDATA[python3]]></category>
            <category><![CDATA[instance-attribute]]></category>
            <category><![CDATA[python-programming]]></category>
            <dc:creator><![CDATA[Eunice Adewusi]]></dc:creator>
            <pubDate>Sun, 30 Jul 2023 08:28:35 GMT</pubDate>
            <atom:updated>2023-07-30T08:28:35.693Z</atom:updated>
            <content:encoded><![CDATA[<p>When working with object-oriented programming (OOP) in Python, it’s essential to understand the concepts of class attributes and instance attributes. These attributes play a crucial role in defining the behavior and characteristics of objects. In this blog post, we will explore what class and instance attributes are, how to create them, their differences, advantages, and drawbacks.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/765/0*vP3ffMS3VTxbxm4P.png" /><figcaption>Photo Credit: Toptal</figcaption></figure><p>Before we dive in, let’s understand the keywords in the topic: Class, instance, and attribute.</p><ul><li><strong><em>What is a Class?</em></strong></li></ul><p>Imagine a class as a blueprint or a set of instructions that helps us create specific types of objects. It’s like a recipe for baking cookies. The class defines the properties and behaviors (characteristics and actions) that all objects of that type will have. For example, if we have a class called “Car,” it will describe what a car should have, such as the number of wheels, color, and how it can drive.</p><ul><li><strong><em>What is an Instance?</em></strong></li></ul><p>An instance is like a real cookie made from the recipe we have in the class. It is a specific, individual object created using the instructions provided by the class. For instance, if we have the “Car” class, an instance of that class would be a particular car with its unique properties, like a red car with four wheels.</p><ul><li><strong><em>What is an Attribute?</em></strong></li></ul><p>An attribute is a characteristic or property of an object. It’s like an adjective that describes the object. For example, going back to our “Car” class, attributes could be the car’s color, the number of wheels it has, and its speed. Each car (instance) created from the “Car” class will have its own set of attribute values, which makes them unique.</p><blockquote>In simple terms, think of a class as a blueprint for creating objects, an instance as a specific object created from that blueprint, and an attribute as a characteristic that tells us something about the object. Just like how a recipe guides us to make cookies (class), and each cookie made is a unique cookie (instance) with its own taste, shape, and size (attributes).</blockquote><p>Refer to my last blog post <a href="https://medium.com/@euniceadewusic/python3-exploring-the-power-of-mutable-and-immutable-objects-452a3dd16be3">here</a> for other definitions.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*eO1oCBnzGnFMW-6h.png" /></figure><h4>What is a Class Attribute?</h4><p>A class attribute is a property that belongs to the class itself rather than to its instances (objects). It is shared among all instances of the class and remains the same across all instances. Class attributes are defined within the class body but outside of any methods. They are accessed using the class name.</p><p>Example:</p><pre>#!/usr/bin/python3<br>class Car:<br>    wheels = 4  # &#39;wheels&#39; is a class attribute<br><br>car1 = Car()<br>car2 = Car()<br><br>print(car1.wheels)  # Output: 4<br>print(car2.wheels)  # Output: 4</pre><h4>What is an Instance Attribute?</h4><p>An instance attribute, on the other hand, is unique to each instance of the class. It is defined inside the class’s methods and is initialised for each object created from the class. Instance attributes represent the specific characteristics or state of individual objects.</p><p>Example:</p><pre>#!/usr/bin/python3<br>class Car:<br>    def __init__(self, color):<br>        self.color = color  # &#39;color&#39; is an instance attribute<br><br>car1 = Car(&quot;red&quot;)<br>car2 = Car(&quot;blue&quot;)<br><br>print(car1.color)  # Output: &quot;red&quot;<br>print(car2.color)  # Output: &quot;blue&quot;</pre><blockquote><strong>A class attribute </strong>is a property that belongs to the class itself and is shared among all instances of that class. It is defined within the class body and accessed using the class name. Class attributes are used to maintain values that remain the same for all objects created from the class.</blockquote><blockquote><strong>An instance attribute</strong> is a property that is unique to each individual object (instance) created from the class. It is defined within the methods of the class and accessed using the self keyword. Instance attributes represent the specific characteristics or state of each object.</blockquote><h4>Creating Class and Instance Attributes:</h4><p>There are several ways to create class and instance attributes in Python but we will discuss just one:</p><ul><li><strong>Class Attributes:</strong> As shown earlier, class attributes are defined within the class body and outside any methods. They are usually initialised directly with a value.</li><li><strong>Instance Attributes:</strong> Instance attributes are created within the __init__ method of the class. They are unique to each object and are assigned values specific to that instance.</li></ul><p><strong>The Pythonic Way:</strong></p><p>This is the most common and recommended approach that follows the conventions and best practices of the Python programming language.</p><p>The Pythonic way of creating class attributes is by defining them directly in the class body. For instance attributes, it is recommended to initialise them within the __init__ method using the self keyword.</p><p>Example:</p><pre>#!/usr/bin/python3<br>class MyClass:<br>    class_attr = &quot;I am a class attribute&quot;<br>    <br>    def __init__(self, instance_attr):<br>        self.instance_attr = instance_attr</pre><h4>Differences between Class and Instance Attributes:</h4><ul><li>Class attributes are shared among all instances, while instance attributes are unique to each object.</li><li>Class attributes are defined at the class level and accessed using the class name, whereas instance attributes are defined within methods and accessed using the self keyword.</li></ul><h4>Advantages and Drawbacks:</h4><ol><li><strong>Class Attributes:</strong></li></ol><p>Advantages:</p><ul><li>Efficient memory usage as the attribute is shared among all instances.</li><li>Easy to update and maintain values that are consistent across instances.</li></ul><p>Drawbacks:</p><ul><li>Lack of flexibility as the attribute’s value remains the same for all objects of the class.</li></ul><p>2. <strong>Instance Attributes:</strong></p><p>Advantages:</p><ul><li>Flexibility to have different values for each instance.</li><li>Encapsulation, as instance attributes can have different access levels (public, private, etc.).</li></ul><p>Drawbacks:</p><ul><li>Slightly higher memory usage when creating many instances.</li></ul><h4>Python’s dict and Attributes:</h4><ul><li><strong><em>What is __dict__?</em></strong></li></ul><p>__dict__ is a special attribute in Python that exists for every object, whether it&#39;s a class or an instance. It behaves like a dictionary and stores all the attributes and their corresponding values associated with that particular object.</p><p>You can say __dict__ is a dictionary containing the object’s attributes.</p><blockquote>For instance attributes, __dict__ contains the names of the instance-specific attribute names and their values, while for class attributes, it stores the names of the class attributes and their values.</blockquote><p>Example:</p><pre>#!/usr/bin/python3<br>class MyClass:<br>    class_attr = &quot;I am a class attribute&quot;<br><br>    def __init__(self, instance_attr):<br>        self.instance_attr = instance_attr<br><br>obj1 = MyClass(&quot;Instance 1&quot;)<br>print(obj1.__dict__)<br># Output: {&#39;instance_attr&#39;: &#39;Instance 1&#39;}<br><br>print(MyClass.__dict__)<br># Output: {..., &#39;class_attr&#39;: &#39;I am a class attribute&#39;, ...}</pre><blockquote>Explanation of dict in simple terms:</blockquote><blockquote>Think of __dict__ as a magical drawer that holds a list of all the special features (attributes) of a thing (object). This drawer is available for every object you create, whether it&#39;s a blueprint (class) or a real thing made from the blueprint (instance). Inside the drawer, you can find the names of the features and their values. For example, if you have a &quot;Car&quot; blueprint, inside the drawer of each car you create (instances), you can find the attributes like color, number of wheels, and speed, along with their specific values.</blockquote><blockquote>The __dict__ attribute helps Python keep track of all the characteristics of an object, making it easy to access and update them when needed. It&#39;s like a handy organiser that makes sure your objects know everything about themselves, just like a car knows its own color and how fast it can go!</blockquote><h4>Access Flow to an Instance Attribute:</h4><ul><li>An instance attribute is directly accessible as a public attribute of the instance. For example, car1.color in the earlier example.</li><li>If an instance attribute is not found, Python looks for it in the class attributes. If present, it returns the class attribute value. However, this does not affect the actual instance attribute.</li></ul><h4>Impact of Updating Class Attributes:</h4><p>When a class attribute is updated, the new value applies to all future instances created from that class, but it does not affect the existing instances.</p><p>Example:</p><pre>#!/usr/bin/python3<br>class MyClass:<br>    class_attr = 10<br><br>obj1 = MyClass()<br>obj2 = MyClass()<br><br>print(obj1.class_attr)  # Output: 10<br>print(obj2.class_attr)  # Output: 10<br><br>MyClass.class_attr = 20<br><br>print(obj1.class_attr)  # Output: 20<br>print(obj2.class_attr)  # Output: 20</pre><h4>Cases to Use Class Attributes:</h4><p>Class attributes are particularly useful in the following scenarios:</p><ul><li><strong>Constants:</strong> Values that remain the same for all instances, such as mathematical constants, configuration values, etc.</li><li><strong>Default Values: </strong>Setting default values for attributes that are commonly used by instances.</li><li><strong>Tracking Values Between Instances: </strong>Maintaining values that need to be tracked across all instances of a class.</li></ul><p>In Python, class attributes and instance attributes play different roles in defining the characteristics and behavior of objects.</p><p>Class attributes provide consistency across instances, while instance attributes allow customisation and encapsulation.</p><p>Understanding their distinctions and use cases is crucial to effective object-oriented programming.</p><p>Let’s meet again in my next post to unravel another Python mystery :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e3ae12eb3e66" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Python3: Exploring the Power of Mutable and Immutable Objects]]></title>
            <link>https://medium.com/@euniceadewusic/python3-exploring-the-power-of-mutable-and-immutable-objects-452a3dd16be3?source=rss-c8751a1ad000------2</link>
            <guid isPermaLink="false">https://medium.com/p/452a3dd16be3</guid>
            <category><![CDATA[object-oriented]]></category>
            <category><![CDATA[python-mysteries]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[python-programming]]></category>
            <category><![CDATA[python3]]></category>
            <dc:creator><![CDATA[Eunice Adewusi]]></dc:creator>
            <pubDate>Fri, 28 Jul 2023 18:15:22 GMT</pubDate>
            <atom:updated>2023-07-28T20:19:43.322Z</atom:updated>
            <content:encoded><![CDATA[<h4>In this realm, everything is an object, and each object has a magical essence of its own!</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*j4peNav4fh-8Vu0y.jpg" /><figcaption>Image Cc: Portfolio Courses on YouTube</figcaption></figure><p>Greetings from the Python world, inquisitive minds! It’s been an intense few weeks of learning about this programming language and running programs; therefore, I want to take you on a tour of what I have learned so far in studying the mysteries of Python programming.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/498/1*c2HHVQBZv1CfrgEQzaiXJw.gif" /><figcaption>Shall we?</figcaption></figure><p>Python is a versatile and powerful object-oriented language, which means you can define classes and create objects to build complex systems in a more structured and organised way. Everything in Python is an object and each object has its own unique properties and behavior. But before we dive in, we need to understand some basics;</p><ul><li><strong><em>What is object-oriented programming?</em></strong></li></ul><p>Object-Oriented Programming is a programming style that revolves around the concept of objects. It allows developers to organise code by modelling real-world entities or abstract concepts as objects with specific behaviors. OOP promotes code reusability, making it easier to manage large projects and create modular and maintainable code.</p><p>Digest this sample about classes and objects before moving on;</p><blockquote>Think of a class as a blueprint or slides presentation for constructing multiple objects called slides, and an object (each slide) as a single entity created from that blueprint.</blockquote><ul><li><strong><em>What is an object?</em></strong></li></ul><p>In Python, an object is a fundamental building block that represents a piece of data and the operations that can be performed on it. Everything in Python, like numbers or integers, strings, lists, and even functions, is an object. Each object has its own unique characteristics, like the data it holds, known as attributes, and the actions it can perform, known as methods.</p><ul><li><strong><em>What is Class?</em></strong></li></ul><p>A class is like a blueprint or a template that defines how an object should look and behave. It specifies the attributes (data) the object will have and the methods (functions) it can use.</p><p>Remember our example about slide presentations? Let’s finish up;</p><blockquote>Each of these slides is meant to do something, like passing on certain knowledge to the audience or viewer. That&#39;s it’s <strong><em>function, </em></strong>which is defined within the class as<strong><em> method. </em></strong>Each font, colour, image, and text used in each slide make up the quality of the information to be passed; thus, they can be referred to as <strong><em>fields</em></strong> or <strong><em>instance</em></strong> <strong><em>variables </em></strong>or<strong><em> attributes</em></strong> in Python.</blockquote><p>In this blog post, we’ll explore the fundamentals of Python objects, their types, and the distinction between mutable and immutable objects. Understanding objects allows us to leverage their capabilities to create elegant and reusable code, and knowing these concepts is essential for writing efficient and bug-free Python code.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*cZVX-vNeJy2itVLb.png" /></figure><h4><strong>- ID and Type:</strong></h4><p>In Python, each object has a unique identifier (ID) that represents its memory address. The built-in function id() provides this identifier, enabling us to verify whether two variables point to the same object. The type() function, on the other hand, helps us identify the type of an object, such as int, str, list, tuple, etc.</p><pre>#!/usr/bin/python3<br># Example illustrating ID and Type<br>a = 10<br>b = a<br>print(&quot;ID of &#39;a&#39;:&quot;, id(a))<br>print(&quot;ID of &#39;b&#39;:&quot;, id(b))<br>print(&quot;Are &#39;a&#39; and &#39;b&#39; identical?&quot;, a is b)<br><br># Output:<br># ID of &#39;a&#39;: 140714611212128<br># ID of &#39;b&#39;: 140714611212128<br># Are &#39;a&#39; and &#39;b&#39; identical? True<br><br>print(&quot;Type of &#39;a&#39;:&quot;, type(a))<br>print(&quot;Type of &#39;b&#39;:&quot;, type(b))<br><br># Output:<br># Type of &#39;a&#39;: &lt;class &#39;int&#39;&gt;<br># Type of &#39;b&#39;: &lt;class &#39;int&#39;&gt;</pre><h4><strong>- Mutable vs. Immutable Objects:</strong></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/617/0*k2vDyN9U_wtY0D0U" /></figure><ul><li><strong>Mutable Objects:</strong></li></ul><p>Mutable objects are those that can be modified after creation. Lists, dictionaries, and sets are examples of mutable objects in Python. When we modify a mutable object, such as appending an element to a list, the object itself is changed, but its ID remains the same.</p><pre>#!/usr/bin/python3<br># Example illustrating Mutable Objects<br>lst1 = [1, 2, 3]<br>lst2 = lst1<br>lst2.append(4)<br>print(&quot;lst1:&quot;, lst1)<br>print(&quot;lst2:&quot;, lst2)<br>print(&quot;Are &#39;lst1&#39; and &#39;lst2&#39; identical?&quot;, lst1 is lst2)<br><br># Output:<br># lst1: [1, 2, 3, 4]<br># lst2: [1, 2, 3, 4]<br># Are &#39;lst1&#39; and &#39;lst2&#39; identical? True</pre><ul><li><strong>Immutable Objects:</strong></li></ul><p>Immutable objects, as the name suggests, cannot be altered after creation. Examples of immutable objects include integers, strings, and tuples. When we perform an operation on an immutable object, a new object is created with the updated value, preserving the original object’s integrity and the original object’s ID remains unchanged.</p><pre>#!/usr/bin/python3<br># Example illustrating Immutable Objects<br>x = 42<br>y = x<br>x += 10<br>print(&quot;x:&quot;, x)<br>print(&quot;y:&quot;, y)<br>print(&quot;Are &#39;x&#39; and &#39;y&#39; identical?&quot;, x is y)<br><br># Output:<br># x: 52<br># y: 42<br># Are &#39;x&#39; and &#39;y&#39; identical? False</pre><ul><li><strong>How an immutable object is stored in memory:</strong></li></ul><p>Immutable objects in Python are stored in memory with a fixed allocation of space during their creation. Each immutable object is given a unique memory address (ID) that remains constant throughout its lifetime, as its value cannot be modified. Since immutable objects cannot change their value after creation, they are <strong>hashable</strong> (meaning they can be used as dictionary keys or elements in sets) and can be safely shared across multiple <strong>threads</strong>.</p><p><strong>Examples of immutable objects and how they are stored in memory using a simple memory schema representation:</strong></p><ul><li><strong>Immutable Object: Integer</strong></li></ul><pre>#!/usr/bin/python3<br># Example with an immutable object (integer)<br>x = 42</pre><ul><li><strong>Memory Schema Representation:</strong></li></ul><pre>Memory Address: 0x1000<br>+------------------+<br>|       42         |<br>+------------------+<br>       ↑<br>       x</pre><p>Explanation:</p><p>A memory block at address 0x1000 is allocated to store the integer value 42. The variable x points to the memory location 0x1000, representing the integer object.</p><ul><li><strong>Immutable Object: String</strong></li></ul><pre>#!/usr/bin/python3<br># Example with an immutable object (string)<br>name = &quot;John&quot;</pre><ul><li><strong>Memory Schema Representation:</strong></li></ul><pre>#!/usr/bin/python3<br>Memory Address: 0x2000<br>+------------------+<br>|   &quot;John&quot;         |<br>+------------------+<br>       ↑<br>      name</pre><p>Explanation:</p><p>A memory block at address 0x2000 is allocated to store the string value &quot;John&quot;. The variable name points to the memory location 0x2000, representing the string object.</p><ul><li><strong>Differences between mutable and immutable objects:</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6BkNAKCCaG52dz8Pa7m29Q.jpeg" /></figure><ul><li><strong>Why Does It Matter and How Python Treats Mutable and Immutable Objects Differently:</strong></li></ul><p>Understanding mutable and immutable objects is crucial for managing data and preventing unintended side effects. Python treats mutable and immutable objects differently due to their unique characteristics. Immutable objects are more memory-efficient since they don’t change, whereas mutable objects might require more memory as they grow. Additionally, mutable objects can lead to unexpected behavior when used as default arguments in functions, while immutable objects are safer in this context.</p><pre>#!/usr/bin/python3<br># Example illustrating the impact of mutable and immutable objects on function arguments<br>def modify_list(lst):<br>    lst.append(4)<br>    print(&quot;Inside the function:&quot;, lst)<br><br>my_list = [1, 2, 3]<br>print(&quot;Before function call:&quot;, my_list)<br>modify_list(my_list)<br>print(&quot;After function call:&quot;, my_list)<br><br># Output:<br># Before function call: [1, 2, 3]<br># Inside the function: [1, 2, 3, 4]<br># After function call: [1, 2, 3, 4]</pre><ul><li><strong>How Arguments are Passed to Functions and Implications for Mutable and Immutable Objects:</strong></li></ul><p>In Python, function arguments are passed using a reference mechanism. When passing immutable objects to functions, the function works with a copy of the object, leaving the original object unaffected. On the other hand, passing mutable objects to functions creates an alias, meaning any changes made within the function affect the original object outside of it.</p><pre>#!/usr/bin/python3<br># Example illustrating how function arguments behave with mutable and immutable objects<br>def modify_immutable(x):<br>    x += 10<br>    print(&quot;Inside the function:&quot;, x)<br><br>def modify_mutable(lst):<br>    lst.append(4)<br>    print(&quot;Inside the function:&quot;, lst)<br><br>a = 42<br>print(&quot;Before function call:&quot;, a)<br>modify_immutable(a)<br>print(&quot;After function call:&quot;, a)<br><br># Output:<br># Before function call: 42<br># Inside the function: 52<br># After function call: 42<br><br>my_list = [1, 2, 3]<br>print(&quot;Before function call:&quot;, my_list)<br>modify_mutable(my_list)<br>print(&quot;After function call:&quot;, my_list)<br><br># Output:<br># Before function call: [1, 2, 3]<br># Inside the function: [1, 2, 3, 4]<br># After function call: [1, 2, 3, 4]</pre><ul><li><strong>Special Case of Tuple and Frozen Set: Immutable Containers of Mutable Objects</strong></li></ul><p>In Python, a tuple is an ordered collection of elements, and a frozen set is an immutable version of a set. Both tuples and frozen sets are considered immutable data types because once created, their elements cannot be changed or modified.</p><p>However, there’s a special case with tuples and frozen sets when their elements are mutable objects. While the tuples and frozen sets themselves are immutable and their sizes cannot be changed, the mutable objects contained within them can still be modified.</p><p>For example, consider a tuple that contains a list:</p><pre>#!/usr/bin/python3<br>my_tuple = ([1, 2, 3], &quot;hello&quot;)</pre><p>In this case, the tuple my_tuple contains a list [1, 2, 3] and a string &quot;hello&quot;. The tuple itself cannot be changed or resized, but the list inside it can be modified because lists are mutable objects.</p><pre>my_tuple[0].append(4)<br>print(my_tuple)  # Output: ([1, 2, 3, 4], &#39;hello&#39;)</pre><p>As you can see, we modified the list within the tuple by appending the value 4 to it. The tuple remains unchanged, but the list it contains has been modified.</p><p>Similarly, the same applies to frozen sets. While a frozen set itself cannot be modified, if it contains mutable objects (like lists or other sets), those objects can still be modified.</p><pre>my_frozen_set = (frozenset({1, 2}), [3, 4])</pre><p>In this example, the frozen set my_frozen_set contains a frozen set {1, 2} and a list [3, 4]. The frozen set cannot be changed, but the list inside it can be modified.</p><pre>my_frozen_set[1].append(5)<br>print(my_frozen_set)  # Output: (frozenset({1, 2}), [3, 4, 5])</pre><p>Here, we modified the list within the frozen set by appending the value 5 to it.</p><p>This special case demonstrates that while tuples and frozen sets are generally considered immutable containers, the objects they contain can still be mutable and subject to modification.</p><p>It’s essential to be aware of this behavior when working with tuples and frozen sets containing mutable objects to avoid unintended changes and to design your code accordingly. If you need a fully immutable data structure, you should ensure that all elements within the container are themselves immutable.</p><h4><strong>- Differences between Assignment and Referencing:</strong></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/267/0*jCUx9OSEtRFjTmkG" /></figure><p><strong>Arguments:</strong></p><ul><li>Assignment refers to the process of giving a value to a variable.</li><li>When you assign a value to a variable, you are storing that value in a specific memory location associated with the variable’s name.</li><li>In programming, the assignment operator (=) is used to perform assignment.</li><li>After assigning a value to a variable, you can use that variable to access and manipulate the stored data.</li><li>Reassigning a value to the same variable will overwrite the previous value in the memory location.</li></ul><pre>#!/usr/bin/python3<br># Assignment<br>x = 10<br>y = &quot;Hello&quot;</pre><p><strong>Referencing:</strong></p><ul><li>Referencing refers to creating a reference or pointer to an existing variable or object in memory.</li><li>Instead of creating a new copy of the data, referencing allows multiple variables to point to the same memory location where the data is stored.</li><li>When you reference a variable, any changes made to the data through one reference will be reflected in all other references to that memory location.</li><li>Referencing is especially relevant when dealing with mutable objects like lists or dictionaries.</li></ul><pre>#!/usr/bin/python3<br># Referencing<br>list1 = [1, 2, 3]<br>list2 = list1  # Both list1 and list2 now point to the same list object in memory<br>list2.append(4)<br>print(list1)  # Output: [1, 2, 3, 4] (changes made through list2 are reflected in list1)</pre><ul><li><strong>How variable values are managed when passed to a function in Python using assignment by reference:</strong></li></ul><p>When a variable is passed to a function in Python, the value of the variable is assigned to a new parameter inside the function. This assignment is done by reference, which means that the parameter inside the function becomes an alias or a reference to the original variable outside the function. Changes made to the parameter inside the function affect the original variable outside the function, as they both point to the same memory location.</p><p>Examples:</p><ul><li><strong>Passing Immutable Objects to a Function (Assignment by Reference):</strong> When you pass an immutable object (e.g., an integer, string, or tuple) to a function, any changes made to the parameter inside the function do not affect the original variable outside the function.</li></ul><pre>#!/usr/bin/python3<br>def modify_immutable(x):<br>    x += 10<br>    print(&quot;Inside the function:&quot;, x)<br><br>a = 42<br>print(&quot;Before function call:&quot;, a)<br>modify_immutable(a)<br>print(&quot;After function call:&quot;, a)<br><br># Output:<br># Before function call: 42<br># Inside the function: 52<br># After function call: 42</pre><p>Explanation:</p><p>The variable a is an integer (immutable) and is passed to the function modify_immutable. Inside the function, the parameter x is created and assigned the value of a. Any changes made to x inside the function (e.g., x += 10) do not affect the original variable a.</p><ul><li><strong>Passing Mutable Objects to a Function (Assignment by Reference):</strong> When you pass a mutable object (e.g., a list or dictionary) to a function, changes made to the parameter inside the function affect the original variable outside the function.</li></ul><pre>#!/usr/bin/python3<br>def modify_mutable(lst):<br>    lst.append(4)<br>    print(&quot;Inside the function:&quot;, lst)<br><br>my_list = [1, 2, 3]<br>print(&quot;Before function call:&quot;, my_list)<br>modify_mutable(my_list)<br>print(&quot;After function call:&quot;, my_list)<br><br># Output:<br># Before function call: [1, 2, 3]<br># Inside the function: [1, 2, 3, 4]<br># After function call: [1, 2, 3, 4]</pre><p>Explanation:</p><p>The variable my_list is a list (mutable) and is passed to the function modify_mutable. Inside the function, the parameter lst is created and assigned the reference to my_list. Any changes made to lst inside the function (e.g., lst.append(4)) also affect the original variable my_list.</p><p>— -</p><h4><strong>Python’s Integer Pre-allocation: NSMALLPOSINTS and NSMALLNEGINTS</strong></h4><p>CPython is the most commonly used implementation of Python, specifically for Python 3 which is the latest major version of the Python programming language. It is written in the C programming language, and it is a “Python interpreter.”</p><p><em>An interpreter is a program that reads and executes Python code line by line, converting it into machine-understandable instructions.</em></p><p>In CPython, the reference implementation of Python, there is a fascinating mechanism called “integer pre-allocation.” This involves creating and storing a fixed number of small integer objects during the Python interpreter’s startup.</p><p>CPython maintains two constants, NSMALLPOSINTS and NSMALLNEGINTS, representing the number of pre-allocated small positive and negative integer objects, respectively. As of CPython 3.9, both are set to 257, meaning that Python pre-allocates 257 small positive integers (ranging from 0 to 256) and 257 small negative integers (ranging from -1 to -257).</p><p>The primary purpose of this pre-allocation is to enhance Python’s performance and optimise memory usage. Small integers are frequently used in Python code for various tasks such as loop counters, arithmetic calculations, and list indexing. Instead of creating new integer objects every time these small values are used, Python reuses the pre-allocated small integer objects, which reduces memory overhead and speeds up operations.</p><p>By pre-allocating the first 257 small positive and negative integers, Python covers a range of commonly used small values, enabling efficient and speedy execution of integer-related operations.</p><p>For instance, when you assign the value 42 to two variables a and b, both variables reference the same pre-allocated integer object for the value 42. This intelligent memory management allows Python to avoid unnecessary object creation for frequently used small integer values, making it a more efficient programming language.</p><p>The specific value 257 for NSMALLPOSINTS and NSMALLNEGINTS is chosen based on practical considerations and performance optimisations. It strikes a balance between memory usage and covering a broad range of frequently used small integer values.</p><p>Let’s see demonstration of the pre-allocation behavior in Python:</p><pre>#!/usr/bin/python3<br>a = 10<br>b = 10<br><br>print(a is b)  # Output: True</pre><p>Explanation:</p><p>In this example, we assign the value 10 to variables a and b. Since 10 is within the range of pre-allocated integers (-5 to 256), both a and b reference the same pre-allocated integer object for the value 10. Therefore, a is b returns True, indicating that a and b point to the same memory location.</p><p>This intelligent memory management allows Python to avoid unnecessary object creation for frequently used small integer values, making it a more efficient programming language.</p><p>The specific value 257 for NSMALLPOSINTS and NSMALLNEGINTS is chosen based on practical considerations and performance optimisations. It strikes a balance between memory usage and covering a broad range of frequently used small integer values.</p><blockquote>Note: It’s important to note that the constants NSMALLPOSINTS and NSMALLNEGINTS are specific to the CPython implementation and may not apply to other Python implementations.</blockquote><p>— -</p><h4>- Mechanism of aliases:</h4><p>In Python, an alias refers to multiple variables that point to the same memory location, sharing the same underlying object. When you assign one variable to another or pass a variable to a function, you are creating an alias. Changes made through one alias are reflected in all other aliases that point to the same memory location.</p><p><strong>Example 1: Creating Aliases</strong></p><pre>#!/usr/bin/python3<br># Creating an alias<br>x = [1, 2, 3]<br>y = x<br><br># Both x and y now reference the same list object in memory</pre><p>Variables x and y here are aliases as they point to the same list object in memory. Changes made through one variable affect the other.</p><p><strong>Example 2: </strong>Modifying Through Aliases</p><pre>#!/usr/bin/python3<br># Modifying through aliases<br>x = [1, 2, 3]<br>y = x<br><br>y.append(4)<br><br>print(x)  # Output: [1, 2, 3, 4] (changes made through y are reflected in x)</pre><p>Here, we modify the list through the alias y, and the changes are reflected in the original list referenced by x.</p><p><strong>Example 3: </strong>Function Arguments as Aliases</p><pre>#!/usr/bin/python3<br># Function arguments as aliases<br>def modify_list(lst):<br>    lst.append(4)<br><br>my_list = [1, 2, 3]<br>modify_list(my_list)<br><br>print(my_list)  # Output: [1, 2, 3, 4] (changes made inside the function affect the original list)</pre><p>This example shows how function arguments can also act as aliases. When we pass my_list to the function modify_list, the parameter lst becomes an alias to the original list. Changes made to lst inside the function affect the original list my_list.</p><p>Congratulations! You made it to the end. With the knowledge you and I have gained from this project, we can confidently navigate the world of Python programming together, leveraging the strengths of mutable and immutable objects to design efficient and elegant solutions.</p><p>Ensure we meet again in my next post :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=452a3dd16be3" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>