<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Samuel Abolo</title>
    <description>The latest articles on Forem by Samuel Abolo (@tecnosam).</description>
    <link>https://forem.com/tecnosam</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F629386%2F9881ba6e-0a5e-4ece-b56d-58f53f6e174e.png</url>
      <title>Forem: Samuel Abolo</title>
      <link>https://forem.com/tecnosam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tecnosam"/>
    <language>en</language>
    <item>
      <title>How to ship code fast: Like a 10x developer</title>
      <dc:creator>Samuel Abolo</dc:creator>
      <pubDate>Sat, 18 May 2024 19:04:33 +0000</pubDate>
      <link>https://forem.com/tecnosam/how-to-ship-code-fast-like-a-10x-developer-42an</link>
      <guid>https://forem.com/tecnosam/how-to-ship-code-fast-like-a-10x-developer-42an</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;We all want to ship features as fast as possible. Especially when we have a long wishlist of other features waiting to be shipped. The catch is our shipped code must be clean, scalable, and working as expected. The big question is, can we have the best of both worlds? This article explores how to release quality code and still have time to watch the Champions League finals.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1ojgu64gcqslu3oqomu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1ojgu64gcqslu3oqomu.jpg" alt="Just saying..." width="600" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do developers fail to ship fast?
&lt;/h2&gt;

&lt;p&gt;Developers fail to ship fast for a couple of reasons&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Developers often struggle with understanding complex features. They spend a significant amount of time analyzing ambiguous feature requests and translating them into detailed specifications and algorithms. Breaking down a feature into smaller, logical components can be a challenging process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They spend too much time on things that don't matter much. Spending hours or even days trying to make a function 1% faster or turning that for loop to a list comprehension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It can be demotivating to write unit tests, documentation, and change logs, often resulting in taking longer than necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Developers often get sidetracked by fixing bugs unrelated to the feature.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fixing bugs takes a lot of time, especially when found by QA instead of yourself.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Luckily for us, all these problems have solutions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build Early, Validate Continuously
&lt;/h3&gt;

&lt;p&gt;Instead of spending so much time worrying about whether you designed the right feature, build what you understand. Keep the client in the loop. Design a version or prototype and demo it to the client. Let the client tell you how far away you are from what they want. Always remember that success is just iterative failure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lyasthuzrw59d16f2g1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lyasthuzrw59d16f2g1.jpg" width="500" height="672"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Lay the foundation: Write clean code from the onset
&lt;/h3&gt;

&lt;p&gt;Avoid technical debt by writing code that's clean and reusable from the very beginning of the project. Apply design patterns that support extensibility and reduce coupling. You shouldn't have to refactor your entire codebase for every new feature. Having a good project directory also goes a long way.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Zen of Testing
&lt;/h3&gt;

&lt;p&gt;Always write your tests before you code, while you're still full of energy. It keeps you focused on the task at hand. Every piece of code you write should aim at passing those test cases. Start by designing integration tests (tests that cover the entire feature) then decompose them into smaller units, testing each function or module to be written. If the requirements change, remember to adjust the tests first before updating the actual code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fww5mrnbe51hrpzdgr07i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fww5mrnbe51hrpzdgr07i.png" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Solve first, optimize later
&lt;/h3&gt;

&lt;p&gt;Most times, the client doesn't care about how fast your product is, as long as it is fast enough. They don't care if it is multithreaded or runs on the GPU. Don't waste everyone's time trying to make the code faster when the code doesn't even exist. It doesn't hurt for your product to be the fastest bunny in town, but fast code that's full of bugs or doesn't work means nothing. Focus on getting it working first, and spend time speeding it up later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we've looked at the various reasons why we developers may fail to deliver on time and how we can tackle each of these reasons. Overall, it promotes an agile culture and a Test Driven Development methodology. It also encourages developers to embrace clean code and proper use of design patterns throughout their projects. This article is helpful to all developers from interns, to seniors across all niches.&lt;/p&gt;

&lt;h2&gt;
  
  
  Relevant Reads and Watches
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.atlassian.com/agile" rel="noopener noreferrer"&gt;Agile Development&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLmmYSbUCWJ4x1GO839azG_BBw8rkh-zOj" rel="noopener noreferrer"&gt;Clean Code by Uncle Bob&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=tv-_1er1mWI" rel="noopener noreferrer"&gt;Design Patterns&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=u6QfIXgjwGQ" rel="noopener noreferrer"&gt;Software Testing&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://katalon.com/resources-center/blog/tdd-vs-bdd" rel="noopener noreferrer"&gt;Test Driven Development&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>productivity</category>
      <category>career</category>
      <category>testing</category>
      <category>community</category>
    </item>
    <item>
      <title>Mastering PR Messages: Why worry about them when there's AI (Part 2)</title>
      <dc:creator>Samuel Abolo</dc:creator>
      <pubDate>Fri, 08 Dec 2023 14:41:43 +0000</pubDate>
      <link>https://forem.com/tecnosam/mastering-pr-messages-why-worry-about-them-when-theres-ai-part-2-2dae</link>
      <guid>https://forem.com/tecnosam/mastering-pr-messages-why-worry-about-them-when-theres-ai-part-2-2dae</guid>
      <description>&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Scenario&lt;/li&gt;
&lt;li&gt;PR messages with GitHub Copilot&lt;/li&gt;
&lt;li&gt;PR messages with CodiumAI&lt;/li&gt;
&lt;li&gt;Which is better?&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7u66lt1hxk717fahlayz.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7u66lt1hxk717fahlayz.jpeg" width="257" height="196"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's face it. We're developers. We all want to ship fast. When that new feature is requested or that issue is raised, we want to get it checked out ASAP and focus on other things. We hate the extras; standups, emails, testing. We want to focus on writing the code.&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/tecnosam/mastering-pr-messages-how-to-get-your-prs-merged-part-1-19e3"&gt;last article&lt;/a&gt;, we looked at the qualities of a good PR message and how to write one. Crafting the perfect PR message takes a lot of work. But what if you don't have to do it yourself?&lt;/p&gt;

&lt;p&gt;Today, we've observed a boom in generative AI and LLMs (Large Language Models). We have generative AI models like GPT-4, DALL-E, Stable DIffusion, LLaMA, and more. We've also seen tools that use these models to solve problems and automate tasks like never before. If you're reading this, you have probably used ChatGPT at some point in time to do things that would take you hours in seconds.&lt;/p&gt;

&lt;p&gt;In this article, we will be exploring how we can take advantage of some of these tools to help us write better PR messages and allow us to focus on what truly matters, the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenario
&lt;/h2&gt;

&lt;p&gt;To illustrate how we can let AI handle our PR messages, I'm going to be using an open-source project written by a good friend of mine (Alfred) on Microservices; a simple illustration of how to build, deploy, and scale (locally) microservices using Docker and Nginx.&lt;/p&gt;



&lt;p&gt;Let's head over to the repo and fork it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faovs0up7vs0ak3u23mcp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faovs0up7vs0ak3u23mcp.png" alt="Image of the Repository" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;It's a system that helps you keep track of popular TV shows. I'm going to be making changes to one of the microservices called  "search-service" because it's written in my favorite programming language (Python). "search-service" handles searching for TV shows using a search query.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkzns8gsz683wn7fr15m5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkzns8gsz683wn7fr15m5.png" alt="Here's what the code we will be changing looks like." width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;We clone our fork to our local computer and create a new branch called "feature/subquery-search" using the following commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/your-username/tv-shows-microservice

git branch feature/subquery-search

git checkout feature/subquery-search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're going to be making a PR to enhance the search service. If you take a look at the code, you will observe that it takes in a search parameter, and searches for tv-shows with that parameter using regular expressions. What happens when what you searched doesn't match any of the TV shows?&lt;/p&gt;

&lt;p&gt;We'd also like to return some shows that closely match. A simple way to do this is to break down the search query into different queries and search for those instead. For example, if a user searches for "The Walking Nun", our algorithm will also search for "The Walking", "The Nun", "Walking Nun", "The", "Walking", and "Nun".&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fln46g5kzils18jre94rr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fln46g5kzils18jre94rr.png" alt="Here's A look at what the function looks like." width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;To make things neater, let's create a function called search_for_shows to handle the regular expressions search for us.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft85msiuscnrs7nsvq22u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft85msiuscnrs7nsvq22u.png" alt="Image of the search_for_shows function" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Finally, here's what the search endpoint looks like now.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsudsrp067p28mpqec3yd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsudsrp067p28mpqec3yd.png" alt="Image of the search endpoint" width="800" height="603"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Once that has done, we commit our changes and push back to GitHub so we can make our PR.&lt;/p&gt;

&lt;h2&gt;
  
  
  PR messages with &lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;GitHub Copilot&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;One of the tools we can use to help us create our PR message is GitHub Copilot. GitHub Copilot is an AI-powered peer programmer developed by GitHub. It has recently launched a new feature called GitHub Copilot Chat on VS Code To set up GitHub Copilot, you can check &lt;a href="https://docs.github.com/en/copilot/using-github-copilot/getting-started-with-github-copilot" rel="noopener noreferrer"&gt;this link&lt;/a&gt;. After that, you can ask GitHub Copilot to give you a good PR message based on the changelog.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3yr2erdcbkrawvtzolof.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3yr2erdcbkrawvtzolof.png" alt="Prompting Copilot chat to write the PR Message" width="450" height="940"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;h2&gt;
  
  
  PR messages with &lt;a href="https://www.codium.ai/products/git-plugin/" rel="noopener noreferrer"&gt;CodiumAI&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Another tool to structure your PR message is CodiumAI's PR Agent. I recommend CodiumAI's PR Agent for a couple of reasons.&lt;/p&gt;

&lt;p&gt;CodiumAI's PR Agent is easy to integrate. You don't need to install CodiumAI on VS Code (though that option is also available).&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fedoy2bqoh3y3yovhttzx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fedoy2bqoh3y3yovhttzx.gif" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;You can mention the CodiumAI's PR Agent in the comment section of the Pull Request. it automatically makes the necessary changes to the title and description. To use this feature, you will need to add CodiumAI either as a GitHub App or GitHub Action in your repository to make it work. You can check out &lt;a href="https://github.com/Codium-ai/pr-agent/blob/main/INSTALL.md#run-as-a-github-app" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; on how to get that done.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftoemhzyollzjgcpj3nun.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftoemhzyollzjgcpj3nun.gif" alt="CodiumAI rewriting PR messages like a cha" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;CodiumAI works on both sides of the table. It's not just a great tool for writing good PR messages, but it's also a great tool for reviewing the PRs of your teammates. With the CodiumAI command "/review", you get to see an analysis of the branch's changelog, including things like a general summary of the changes, how long it will take you to go through the PR, the type of PR, and suggestions on the PR. So even if your teammates didn't use CodiumAI to structure their PR messages, you can use CodiumAI to review the PRs.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7co5iypkkyvpp48sv99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7co5iypkkyvpp48sv99.png" alt="Using the /review command" width="800" height="706"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;CodiumAI also provides an "/ask" command which lets you ask questions about the PR and what has changed. Think of this as having ChatGPT inside the PR.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnssnhdjl26j6y7mfw9bo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnssnhdjl26j6y7mfw9bo.png" alt="Using the /ask command" width="800" height="702"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;You can ask any questions about the code and what has changed. You also get an "/improve" command that shows code suggestions for the PR.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fas7bz6itsxv2fu5ltm10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fas7bz6itsxv2fu5ltm10.png" alt="using the /improve command" width="800" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Alfred-Onuada/tv-shows-microservice/pull/2/files/e1b087c3947266252e0f3527b3a139f3937738bd" rel="noopener noreferrer"&gt;Here's a link with all the recommendations from CodiumAI&lt;/a&gt; You also have the option to just commit the changes directly to the pull request. (Pretty cool right?)&lt;/p&gt;



&lt;h2&gt;
  
  
  GitHub Copilot VS CodiumAI's PR Agent
&lt;/h2&gt;

&lt;p&gt;In this article, we have discussed two AI tools that can assist us in creating our PR messages. The question now arises as to which one should we use. &lt;/p&gt;

&lt;p&gt;GitHub Copilot is an excellent tool for generating code, as it is its primary function. It is a pair programmer AI trained on all open-source code repositories on GitHub, making it extremely powerful for coding tasks. However, its strength in writing effective PR messages may not be as comprehensive or tailored specifically for PR needs.&lt;/p&gt;

&lt;p&gt;CodiumAI's PR Agent, on the other hand, specializes in structuring PR messages. It automatically adjusts titles and descriptions based on the content of the PR. Since this AI agent is designed specifically for PRs, it is easier to work with and has more commands that help in other aspects of code collaboration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, AI-powered tools like CodiumAI's PR Agent and GitHub Copilot can help us write better PR messages and save us time. With these tools, we can focus on writing quality code and let the AI handle the tedious tasks of structuring and reviewing PR messages. Consider using one of these AI-powered tools to help you out next time you're creating a PR message.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>opensource</category>
      <category>productivity</category>
      <category>ai</category>
    </item>
    <item>
      <title>Mastering PR Messages: How to get your PRs merged (Part 1)</title>
      <dc:creator>Samuel Abolo</dc:creator>
      <pubDate>Mon, 04 Dec 2023 06:18:15 +0000</pubDate>
      <link>https://forem.com/tecnosam/mastering-pr-messages-how-to-get-your-prs-merged-part-1-19e3</link>
      <guid>https://forem.com/tecnosam/mastering-pr-messages-how-to-get-your-prs-merged-part-1-19e3</guid>
      <description>&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;The Art of Writing Great PR Messages&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As a computer programmer, you've probably been in a situation where you need to work with others on projects. Whether it's a project at work, school, an open-source project, or even a side project you and your friends decided to work on it.&lt;/p&gt;

&lt;p&gt;As a computer programmer in this category, you most likely used a tool called Git as a VCS (Version Control System) and GitHub, Bit Bucket, or any of the others. If so, you must be familiar with the term called "pull request" or "PR", related to something called a branch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Branches and PRs
&lt;/h3&gt;

&lt;p&gt;A branch is like a duplicate of the main code folder. You can edit its content and then merge it with the main folder. You can also collaborate with others by merging your folder with theirs.&lt;/p&gt;

&lt;p&gt;When merging your branch with others, you can add a nice message stating why your code should be merged. In really chill environments (say your school project or side project), this message helps the team know what exactly has changed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3mf8h7cmh5tpyre4phz7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3mf8h7cmh5tpyre4phz7.jpg" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's a slightly different case if it's a work or open source project. You don't just merge your branch with the main one as that can break things. What you do instead is to create a Pull Request. In the case of a pull request, the message tells the team what will change if they merge your code and whether or not they should let it through. In short, everyone else looks at your changes and decides if they should be merged.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4a3ktq12wrvn1yr3jqu.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4a3ktq12wrvn1yr3jqu.jpeg" alt="Image description" width="279" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Art of Writing Great PR Messages
&lt;/h2&gt;

&lt;p&gt;When writing a pull request, a clear and straightforward message is important. A poorly written message can lead to confusion among team members about code changes, making them reluctant to adopt your changes. There are various things to look for when writing a great PR&lt;/p&gt;

&lt;h3&gt;
  
  
  Write good PRs
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3dhmd8ncn4pp5ylc1uv2.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3dhmd8ncn4pp5ylc1uv2.jpeg" width="216" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great PR messages require great PRs. Ensure your PRs contain clear, straightforward, and well-written code with context. Avoid adding too many features in one PR. PRs should focus on a new feature, a bug fix, a refactored feature, feature tests, or documentation changes.&lt;/p&gt;

&lt;p&gt;When submitting a pull request (PR), it's important to ensure that the changes made are neither too little nor too much. If the changes made are too little, it might not be considered worthy of a PR. On the other hand, if it's too much, it should be broken down into multiple PRs for better clarity.&lt;/p&gt;

&lt;p&gt;A useful tip is to create a new branch for each PR or proposed change. Once the objective of the branch has been completed and the PR has been merged, the branch should be deleted.&lt;/p&gt;

&lt;p&gt;For instance, if you create a branch called "login-feature", after creating and merging the login feature to the main branch, the branch should be deleted. Even if there's a change or bug fix to the login feature, the change should have its branch. This helps keep things organized and makes the process a lot cleaner.&lt;/p&gt;

&lt;h3&gt;
  
  
  Plan your PR message before creating the branch
&lt;/h3&gt;

&lt;p&gt;Now that you've got a great PR, you need a great PR message to explain what's in the PR. A great way to always have a clear and brief PR message is to write it before writing code. Let the PR message be your guide to the changes you'll make. This makes your work easy and helps you stay on track while coding, thus making your PR message a perfect description of PR.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Clear Language
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzkg80jlytbuz3hh0bi9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzkg80jlytbuz3hh0bi9.png" width="750" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Always remember that not everyone who reads your PR message will have technical knowledge. So, it's best to avoid using technical terms as much as possible. Only use programming words when necessary, and always write your message as if it's being read by someone who is not a coder. This will ensure that your message is clear and easily understood by everyone.&lt;br&gt;
Lastly, when writing a PR in English, use common words instead of uncommon ones. For instance, use "brief" instead of "succinct".&lt;/p&gt;

&lt;h3&gt;
  
  
  Add Images if necessary
&lt;/h3&gt;

&lt;p&gt;There's this saying that an image is worth a thousand words. If your changes also affect design, it's not a bad idea to include pictures of the new design. Whether it's the database design, system design, or even changes to some form of front end, images go a long way in explaining what has changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tag your teammates
&lt;/h3&gt;

&lt;p&gt;When you want your teammates to review your code, make sure to tag them. If your teammates are also working on the same feature, they should also be tagged. Additionally, it's important to mention everyone who is involved in your change in your PR message. This will help draw attention to your change and ensure that everyone stays informed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Follow the crowd
&lt;/h3&gt;

&lt;p&gt;When writing PR messages, it's important to ensure they follow the same structure and format that other team members use. If you are contributing to an open-source project, likely, there are already guidelines in place for how PR messages should be structured. It's essential to follow these guidelines strictly to ensure clarity and consistency across the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Writing clear and concise PR messages is crucial for getting your PRs merged&lt;/li&gt;
&lt;li&gt;Avoid using technical jargon and use simple language that is easy to understand&lt;/li&gt;
&lt;li&gt;Tag your teammates in the message if necessary&lt;/li&gt;
&lt;li&gt;Consider including images to help explain the changes you've made&lt;/li&gt;
&lt;li&gt;Following these tips will help your teammates understand your changes and make the review process more efficient.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Watch out for Part 2 and if you have any questions, feel free to reach out to me via E-mail: &lt;a href="mailto:ikabolo59@gmail.com"&gt;ikabolo59@gmail.com&lt;/a&gt; or  &lt;a href="https://twitter.com/samuel_abolo" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>git</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Celery: Python's Silent Hero</title>
      <dc:creator>Samuel Abolo</dc:creator>
      <pubDate>Sun, 01 Oct 2023 22:00:50 +0000</pubDate>
      <link>https://forem.com/tecnosam/celery-pythons-silent-hero-4839</link>
      <guid>https://forem.com/tecnosam/celery-pythons-silent-hero-4839</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;A few days ago, I was working on this cool personal project of mine (no spoilers till I release it). I needed to work on a microservice that read image data from Kafka and perform operations on them. These operations involved heavy image processing and machine learning tasks that could take about 1 second to finish. Sounds pretty small right? Here's the problem. These messages coming from Kafka were arriving in real-time. Imagine getting ready to spend 1 second on one image when the other has already arrived.&lt;/p&gt;

&lt;p&gt;One solution I considered (which I will still implement) was to horizontally scale this microservice since I'm already using a Publisher/Subscriber architecture with Kafka. It means that I have multiple instances of this microservice subscribed to Kafka, so while one is busy with an image, the other has already picked it up and is working on it. But this wasn't enough. I needed this microservice to be as scalable as possible. That's when it hit me. Why don't I use Celery?&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Celery?
&lt;/h2&gt;

&lt;p&gt;I needed some way to receive these messages as quickly as possible and perform these computations on each image. That's where Celery came in. Celery is a Python-based task queue that helps us queue up tasks in a separate thread allowing the main process of our app to run smoothly. In other words, it's an asynchronous task queue. These tasks get executed in the order that they arrive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Celery?
&lt;/h2&gt;

&lt;p&gt;Now, I know many of you are probably wondering, why Celery? Why didn't Samuel use multithreading? After all, he has written an article on how to use multithreading and multiprocessing in Python.&lt;/p&gt;

&lt;p&gt;The answer is the queue in the task queue. Celery allows us to use robust message brokers such as RabbitMQ and Redis making our lives better. Celery then lets us create Workers. You can think of these workers as threads that keep checking the message brokers for jobs to execute.&lt;/p&gt;

&lt;p&gt;Even if our celery workers aren't running, the jobs get queued until a worker gets back up. Also, since we can spawn multiple celery workers connected to the same RabbitMQ or Redis Queue, we've achieved horizontal scalability within each instance of my awesome microservice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Celery in Python
&lt;/h2&gt;

&lt;p&gt;If you're still reading this, you'd also like to use Celery in your project. To use Celery, you only need four things installed on your computer.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A message broker (RabbitMQ, Redis, Amazon SQS, or Zookeeper)&lt;/li&gt;
&lt;li&gt;Python3 installed&lt;/li&gt;
&lt;li&gt;The Celery Framework&lt;/li&gt;
&lt;li&gt;A celery backend (optional) for queuing up the results from our celery workers. The best choice here is Redis.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first thing you'd want to do is to get a message broker installed on your computer or server. I recommend RabbitMQ because it's the default message broker for Celery and should work best, but you should use a message broker that you're most comfortable with. Here are some links on how to install these brokers&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-setting-up.html" rel="noopener noreferrer"&gt;How to install Amazon SQS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rabbitmq.com/download.html" rel="noopener noreferrer"&gt;How to install RabbitMQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://redis.io/download/" rel="noopener noreferrer"&gt;How to install Redis&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would assume you already have Python3 installed on your computer so I won't say so much about it. I'd also recommend you create a virtual environment rather than using your global Python environment.&lt;/p&gt;

&lt;p&gt;Lastly, you can install Celery using your favorite package manager in Python (pip, easyinstall, and lots more)&lt;/p&gt;

&lt;p&gt;The first step to using Celery is to create a Celery object in a file called tasks.py (it's just a convention. You can name it anything you like). This object tells Python how we'd like our Celery worker to behave. This is where we specify what message broker Celery should use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;celery&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Celery&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Celery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;tasker&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;backend&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;redis://localhost&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;broker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;amqp://127.0.0.1:5672&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step is to copy our computationally expensive code and paste it into a function in our tasks.py file. You'll then decorate this function with the @app.task decorator from our Celery object. This decorator tells Celery that the code is a possible task in Celery.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="nd"&gt;@app.task&lt;/span&gt; 
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;awesome_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# We pretend as if the task is taking some time.
&lt;/span&gt;    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Time taken: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;awesome_task&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# We create a new task and fire it to celery
&lt;/span&gt;    &lt;span class="n"&gt;awesome_task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then add tasks to our Celery task queue that can be picked up by any of the Celery workers and executed.&lt;/p&gt;

&lt;p&gt;To create a Celery worker, run the command in the terminal.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;celery -A tasks worker --loglevel=INFO&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When we run our app, you will notice that we aren't seeing the output in the app's shell but rather, in the shell that's running the Celery task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope I've been able to show you how awesome Celery is at helping scale your apps.&lt;/p&gt;

&lt;p&gt;Of course, this isn't the only way you can use Celery. You can use Celery to make your Flask or Django app asynchronous. This means that the requests made to your app don't have to wait for it to be less busy to get a response. A lot of people also use Celery to run background tasks like sending successful E-mails or storing application logs.&lt;/p&gt;

&lt;p&gt;If you have any questions about using Celery in Python, feel free to reach out to me through my E-mail or the comment section.&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>computerscience</category>
      <category>learning</category>
    </item>
    <item>
      <title>How to NOT overfit in Deep Learning</title>
      <dc:creator>Samuel Abolo</dc:creator>
      <pubDate>Mon, 23 Jan 2023 22:34:46 +0000</pubDate>
      <link>https://forem.com/tecnosam/how-to-not-overfit-in-deep-learning-69a</link>
      <guid>https://forem.com/tecnosam/how-to-not-overfit-in-deep-learning-69a</guid>
      <description>&lt;h2&gt;
  
  
  CONTENTS
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction: What is overfitting&lt;/li&gt;
&lt;li&gt;Why overfitting happens in neural networks&lt;/li&gt;
&lt;li&gt;Techniques to preventing overfitting: L2 Regularization&lt;/li&gt;
&lt;li&gt;Techniques to preventing overfitting: Dropout Regularization&lt;/li&gt;
&lt;li&gt;Other things that can help: Batch normalization.&lt;/li&gt;
&lt;li&gt;Other things that can help: Diversify your dataset
Summary and Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When you're using deep learning, sometimes your neural network can do really well on the data you're training it with, but not as well when you test it or use it in real life. This can be really frustrating because it's not always easy to fix. In this article, we'll talk about what overfitting is in neural networks and what you can do to fix it when it happens in your model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Overfitting is
&lt;/h2&gt;

&lt;p&gt;Overfitting is when your neural network is doing really well on the data you're training it with, but not as well when you test it or use it in real life. It happens when the neural network has learned patterns that only appear in the data you're training it with, but not in the actual problem you're trying to solve. These patterns are like noise, and they're not helpful for your final solution.&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhik2qco4890x9z4h6mrw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhik2qco4890x9z4h6mrw.png" alt="Overfitting illustration from Data Science Stack Exchange" width="640" height="480"&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;In the above image, notice how the model does really well on the data that was used to train it but performs poorly on the evaluation data. We could say in simple terms, that the model has gotten used to the training data. &lt;/p&gt;

&lt;p&gt;It's kind of like how students can get so caught up in practicing past questions for an exam, that they can't answer any question that didn't fall into past questions &lt;em&gt;training set&lt;/em&gt;.&lt;/p&gt;



&lt;h2&gt;
  
  
  Why overfitting happens
&lt;/h2&gt;





&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Complex network structure&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The simplest and most obvious reason why overfitting occurs is the complexity of our network. The more layers we add, the more our neural network tries to derive insights from our data. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Insufficient data&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another reason why overfitting happens is when you're trying to learn from not enough data or data that all looks the same, or when you're running too many "epochs" (repeated training cycles) with a big network on not enough data. For example, let's say you're training a neural network to recognize the difference between a cat and a dog. If all the dogs in your training set are bulldogs, it might have trouble recognizing a chihuahua.&lt;/p&gt;

&lt;p&gt;Another problem that can happen when you have little or similar data is that your network will stop learning too soon and will only find patterns that exist in that specific data set and not in the problem you're trying to solve.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Poorly Synthesized data&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A technique to fix the problem of "homogeneous" data is called data synthesis. This means creating new data by combining different sources. For example, if you're training a neural network to recognize a specific word (like "Hey Siri") but you want it to also work well in a noisy environment, you can make new data by combining sounds of that specific word with sounds of different noisy places. This will make the network better at recognizing the word in different environments.&lt;/p&gt;

&lt;p&gt;Using data synthesis can be helpful in making sure your data is diverse and not too similar, but it can also cause problems if not done correctly. One way it can lead to overfitting is if the network starts to learn the noise that was used to create the new data. In other words, if the network starts to focus on the wrong things instead of the main feature you're trying to train it on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Techniques for preventing Overfitting
&lt;/h2&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;L2 regularization&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;L2 regularization is an idea borrowed from classical machine learning and regression. It works by adding a regularization term to the loss function. This term is the &lt;a href="https://en.wikipedia.org/wiki/Matrix_norm" rel="noopener noreferrer"&gt;Frobenius/Matrix Norm&lt;/a&gt; of the weights of the neural network&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4z78kwwy9ub99fhzvsie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4z78kwwy9ub99fhzvsie.png" alt="L2 Normalization Formula" width="800" height="125"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;The lambda value is a number that can be adjusted to change how much regularization is used to prevent overfitting. Regularization is a technique that helps the network not to focus too much on the noise in the data. If the lambda value is zero, then regularization is not applied at all. If the lambda value is very high, then regularization becomes too strong, and the network will not learn enough from the data, which is called underfitting.&lt;/p&gt;

&lt;p&gt;So the intuition is that the higher the value of lambda, the stronger the effect L2 regularization has on our network&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Dropout Regularization&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The main Idea behind Dropout Regularization is randomly temporarily shutting off a small percentage of units within layers of our neural network to reduce the chances of our neural network depending on strong signals from any of these units. &lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuucgqb5k05rc3ju78iox.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuucgqb5k05rc3ju78iox.gif" alt="Dropout Regularization in action" width="524" height="348"&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;We should however be careful not to shut off a large portion of our network layers because it can cause our network to underfit our data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other things that can help
&lt;/h2&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Batch Normalization&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Batch Normalization has this regularization effect that can help prevent overfitting. &lt;/p&gt;

&lt;p&gt;The first benefit it gives is that it helps to set all your features to be on the same scale (i.e having the same standard deviation), helping your Neural Network to converge faster and better. Your neural network would also be less likely to depend on features that are on a higher scale than others. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Diversify your Data&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One simple way to fix overfitting is to add more diverse data to your dataset. However, this might not always be possible or easy. By having more varied data, your model will learn to recognize features that appear throughout the dataset instead of just in a small part of it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Transfer Learning&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a way of addressing the issue of overfitting caused by not having enough data. By using a neural network that has been trained with a lot of data, you can use it to solve similar problems and make it better. Often, all you need to do is retrain the input and output layers of the network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks for Reading!
&lt;/h2&gt;

&lt;p&gt;Thanks for reading this article! I would love to hear your thoughts, questions, or any other feedback you may have. Don't hesitate to share your thoughts in the comments section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reach out to me
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="mailto:ikabolo59@gmail.com"&gt;ikabolo59@gmail.com&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/samuel-abolo-24431a176/" rel="noopener noreferrer"&gt;My LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/samuel_abolo" rel="noopener noreferrer"&gt;My Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Multiprocessing in Python (Part 2)</title>
      <dc:creator>Samuel Abolo</dc:creator>
      <pubDate>Sun, 07 Aug 2022 00:01:00 +0000</pubDate>
      <link>https://forem.com/tecnosam/multiprocessing-in-python-part-2-584g</link>
      <guid>https://forem.com/tecnosam/multiprocessing-in-python-part-2-584g</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;FACE DETECTION WITH PYTHON AND MULTIPROCESSING&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In this post, we will be writing a simple script to illustrate how handy multiprocessing and multithreading can be in real world situations.&lt;br&gt;
We will be writing a simple program that loads images from our computer, detects and draws rectangles on all human faces and upload to a server.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Tools&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;OpenCV&lt;/li&gt;
&lt;li&gt;Flask for our server&lt;/li&gt;
&lt;li&gt;The Python &lt;code&gt;requests&lt;/code&gt; module to push our images&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;OUR FACIAL RECOGNITION ALGORITHM&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;So this code basically handles all the local processing, To understand more about how the face detection works, check out &lt;br&gt;
&lt;a href="https://realpython.com/face-recognition-with-python/" rel="noopener noreferrer"&gt;realpython.com&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;

&lt;span class="c1"&gt;# Create the haar cascade
&lt;/span&gt;&lt;span class="n"&gt;cascPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;haarcascade_frontalface_default.xml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;faceCascade&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CascadeClassifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cascPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;draw_face&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="n"&gt;gray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cvtColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;COLOR_BGR2GRAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Detect faces in the image
&lt;/span&gt;    &lt;span class="n"&gt;faces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;faceCascade&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detectMultiScale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;scaleFactor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;minNeighbors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;minSize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Draw a rectangle around the faces
&lt;/span&gt;    &lt;span class="nf"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;faces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;write_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output.jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;out-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imwrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;upload_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:5000/upload&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;file&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;THE SIMPLE SERVER&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This is a simple WSGI server written in Flask, to allow us to upload our files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/upload&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;upload_file&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;file&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./temp/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this in a new terminal window&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h3&gt;
  
  
  &lt;strong&gt;THE NORMAL WAY OF PROCESSING (Synchronously)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If we were to test this function with 1000 images, running our flask server locally, it’s gonna take A LOT of time because it’s processing it synchronously.&lt;/p&gt;

&lt;p&gt;Synchronous programming or execution basically means that the next process has to wait for the current process to finish before it starts. &lt;/p&gt;

&lt;p&gt;Synchronous execution is only suitable if the current process needs the data generated by the previous process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;normal_way&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_paths&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;image_path&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;image_paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;draw_face&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;write_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;upload_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Trying this 100 times to simulate 100 images
&lt;/span&gt;    &lt;span class="n"&gt;image_paths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a.jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;

    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;normal_way&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_paths&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;stop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Time taken for synchronous: 309.1052303314209
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Time taken for synchronous: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;If we were to have 1000 samples, the time taken would be approximately 3091.05 seconds.&lt;/em&gt;&lt;/p&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;OUR OPTIMISED CODE (ASYNCHRONOUS EXECUTION)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Asynchronous programming is basically the opposite of synchronous programming, the next process can start concurrently or in parallel with the current process. &lt;/p&gt;

&lt;p&gt;There are many ways to achieve this: An Event Loop, Multithreading, Multiprocessing, etc.  For the purpose of this tutorial, we will be using Multithreading and Multiprocessing only.&lt;/p&gt;

&lt;p&gt;We will be using multithreading for the IO-based functions: reading the images from the disc, writing to the disc, and uploading to the server.&lt;/p&gt;

&lt;p&gt;We will be using multiprocessing for the CPU-intensive function, which is the function that detects and draws rectangles on the faces.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;concurrent.futures&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ThreadPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ProcessPoolExecutor&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;optimised_solution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="c1"&gt;# Define our pool executors
&lt;/span&gt;    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nc"&gt;ThreadPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;thread_pool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nc"&gt;ProcessPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;process_pool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

            &lt;span class="c1"&gt;# We use threading to read our images
&lt;/span&gt;            &lt;span class="n"&gt;images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;thread_pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;read_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_paths&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# We use multiprocessing to process our images
&lt;/span&gt;            &lt;span class="n"&gt;processed_images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;process_pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;draw_face&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# We use multithreadfing to write our images to disk
&lt;/span&gt;            &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;thread_pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;write_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;processed_images&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# And finally, we use multithreading to push our images to our server
&lt;/span&gt;            &lt;span class="n"&gt;responses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;thread_pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;upload_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processed: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Trying this 100 times to simulate 100 images
&lt;/span&gt;    &lt;span class="n"&gt;image_paths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a.jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;

    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;optimised_solution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_paths&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;stop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Time taken for Optimised 1: 147.17485308647156
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Time taken for Optimised 1: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;KEY TAKEAWAYS&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;As we observe, notice that our solution optimised with multiprocessing took about half the time to finish executing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Our program now has the ability to scale &lt;em&gt;horizontally&lt;/em&gt; with the number of CPUs because of the concept of &lt;em&gt;parrallel computing&lt;/em&gt; discussed in part 1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If we where to have an Asynchronous server (ASGI), our program would be more optimised, but lets leave that for another day.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;THE FULL CODE&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;concurrent.futures&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ThreadPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ProcessPoolExecutor&lt;/span&gt;



&lt;span class="n"&gt;cascPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;haarcascade_frontalface_default.xml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Create the haar cascade
&lt;/span&gt;&lt;span class="n"&gt;faceCascade&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CascadeClassifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cascPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;draw_face&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# More Info: https://realpython.com/face-recognition-with-python/
&lt;/span&gt;
    &lt;span class="n"&gt;gray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cvtColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;COLOR_BGR2GRAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Detect faces in the image
&lt;/span&gt;    &lt;span class="n"&gt;faces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;faceCascade&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detectMultiScale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;scaleFactor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;minNeighbors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;minSize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Draw a rectangle around the faces
&lt;/span&gt;    &lt;span class="nf"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;faces&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;read_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;write_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output.jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;out-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;cv2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;imwrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fn&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;upload_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:5000/upload&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;file&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;normal_way&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_paths&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;image_path&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;image_paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;draw_face&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;write_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;upload_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;optimised_solution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="c1"&gt;# Define our pool executors
&lt;/span&gt;    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nc"&gt;ThreadPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;thread_pool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nc"&gt;ProcessPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;process_pool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

            &lt;span class="c1"&gt;# We use threading to read our images
&lt;/span&gt;            &lt;span class="n"&gt;images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;thread_pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;read_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_paths&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# We use multiprocessing to process our images
&lt;/span&gt;            &lt;span class="n"&gt;processed_images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;process_pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;draw_face&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# We use multithreadfing to write our images to disk
&lt;/span&gt;            &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;thread_pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;write_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;processed_images&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# And finally, we use multithreading to push our images to our server
&lt;/span&gt;            &lt;span class="n"&gt;responses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;thread_pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;upload_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processed: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Trying this 100 times to simulate 100 images
&lt;/span&gt;    &lt;span class="n"&gt;image_paths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a.jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;

    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;normal_way&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_paths&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;stop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Time taken for synchronous: 309.1052303314209
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Time taken for synchronous: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;optimised_solution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_paths&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;stop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Time taken for Optimised 1: 147.17485308647156
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Time taken for Optimised 1: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;CONCLUSION&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Multiprocessing and Multithreading can be combined to boost our code performance by a lot.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Synchronous execution can only scale up if we have faster CPUs, but multiprocessing allows us to scale up with more CPUs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Feel free to ask any questions in the comment section, or reach me at &lt;a href="mailto:ikabolo59@gmail.com"&gt;ikabolo59@gmail.com&lt;/a&gt; and on  &lt;a href="https://twitter.com/samuel_abolo" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

</description>
      <category>python</category>
      <category>computerscience</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Multiprocessing in Python (Part 1)</title>
      <dc:creator>Samuel Abolo</dc:creator>
      <pubDate>Fri, 29 Jul 2022 20:43:00 +0000</pubDate>
      <link>https://forem.com/tecnosam/multiprocessing-in-python-3g8p</link>
      <guid>https://forem.com/tecnosam/multiprocessing-in-python-3g8p</guid>
      <description>&lt;p&gt;A lot of you have probably been in a situation where you need to carry out multiple tasks, or a repetitive action on multiple items, like doing your homework, or even something as little as doing your laundry. It’s so much easier when we have the ability to do multiple things at the same time. Like have multiple washing machines for our laundry, or 5 people do your homework.&lt;/p&gt;

&lt;p&gt;The same principle also applies to computing. There are times when we have lots of data and we would like to perform the same action on all of our data. The problem now is, that it’s the same action and we have lots of data. This slows down our program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;our_function&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processing stuff...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Done&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;normal_linear_method&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="nf"&gt;our_function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;our_function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;our_function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;normal_linear_method&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# Time taken: about 15 seconds
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s assume it takes exactly 5 seconds to complete the action or function on the data. If we have 100 units of data to process, it's going to take us 500 seconds, which is about 8 minutes of our time. What if I told you there was a way we could speed things up from 8 minutes back to our unit time of 5 seconds?&lt;/p&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Multithreading in Python&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The first technique we will use to solve our problem is something called multithreading. Multithreading works by constantly switching the context (basically the state of the task it’s working on at the moment) such that an illusion of parallel processing is achieved. This concept is also known as concurrency.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Example of task speed up using multithreading
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;threading&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Thread&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;using_multithreading&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="c1"&gt;# Our threads
&lt;/span&gt;    &lt;span class="n"&gt;t1&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;our_function&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;our_function&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;t3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;our_function&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Starting our threads
&lt;/span&gt;    &lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;t3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# We join the threads/processes so our main thread/process
&lt;/span&gt;    &lt;span class="c1"&gt;# can wait for it to be completed before terminating
&lt;/span&gt;
    &lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;t3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;using_multithreading&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# time taken: about 5 seconds
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  &lt;strong&gt;Multiprocessing in Python&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The second technique we will use to solve our problem is multiprocessing. While multithreading in python makes use of context switching, multiprocessing in python runs each of the processes in parallel. Each process has its own copy of the entire program's memory and runs on its own core.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Example of task speed up using multiprocessing
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;multiprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Process&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;using_multiprocessing&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Our processes
&lt;/span&gt;    &lt;span class="n"&gt;p1&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;our_function&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;our_function&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Starting our processes
&lt;/span&gt;    &lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perf_counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;using_multiprocessing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;stop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perf_counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Time taken {}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  &lt;strong&gt;Multiprocessing vs Multithreading: Parallelism vs Concurrency&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Both multiprocessing and multithreading come in handy. The question is, when should we use what.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We use multithreading for IO-bound operations, like reading data from a file, or pooling data from a server. &lt;/li&gt;
&lt;li&gt;We use multiprocessing for CPU-bound operations, like image processing, training a machine learning model, big data processing, etc.&lt;/li&gt;
&lt;/ul&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Running multiple processes at once&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;There are times when we want to run a function on a sequence of data. Say we have a list of 100 units of data, and we would like to apply our function to all of them in parallel or concurrently. There are different approaches we can take:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Approach 1: iteratively create processes and start them&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In this approach, we’ve used a loop to create a process for all our data and start them. The problem with this approach is that we can’t really get the output of the processes easily.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;multiprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Process&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiple_processes&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="c1"&gt;# Spawn our processes iteratively
&lt;/span&gt;    &lt;span class="n"&gt;processes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,))&lt;/span&gt; 
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;processes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Iteratively start all processes
&lt;/span&gt;        &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;processes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; 

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perf_counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;multiple_processes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;stop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perf_counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Time taken {}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="c1"&gt;# time taken: about 8 seconds
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h3&gt;
  
  
  &lt;strong&gt;Approach 2: The ProcessPoolExecutor&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In this approach, we’ve used something called a pool, which is an easier and neater way to manage our computing resources. Although this is slower than spawning the processes iteratively, its way neater and allows us to use the output of those processes in our main process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Using multiprocessing with ProcessPoolExecutor
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;concurrent.futures&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; \
    &lt;span class="n"&gt;ProcessPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;as_completed&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiple_processes_pooling&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nc"&gt;ProcessPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;process_futures&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; 
            &lt;span class="nf"&gt;as_completed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;process_futures&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perf_counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;multiple_processes_pooling&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;stop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perf_counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Time taken {}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="c1"&gt;# time taken: about 50 seconds
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h3&gt;
  
  
  &lt;strong&gt;Approach 3: ProcessPoolExecutor().map&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In this approach, instead of iteratively submitting a process to our pool executor, we’ve used the executor.map method to submit all of the data in the list at once. The output of this function is the result of all the completed processes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;concurrent.futures&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ProcessPoolExecutor&lt;/span&gt;

&lt;span class="c1"&gt;# Using the executor.map
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pooling_map&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nc"&gt;ProcessPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perf_counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;pooling_map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;stop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perf_counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Time taken {}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="c1"&gt;# time taken: about 50 seconds
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;h2&gt;
  
  
  &lt;strong&gt;Very Important to remember&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you look at the time output, you’d notice that the time taken isn't exactly the unit time, there are four main factors that affect this.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The computer in use can affect its time, as well as other programs running on your PC. The code was tested using an intel Core i5 7th generation computer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It takes a few microseconds for our program to properly set up our processes and start it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When there are more processes than we have CPU cores, our system automatically queues the pending processes and helps us manage them properly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And finally, it takes a few microseconds for our program to properly close processes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That being said, it’s important to note that we only use multiprocessing when there’s a lot of data and the operation takes a lot of time to be completed.&lt;/p&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Multiprocessing and Multithreading help us to speed up our programs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multiprocessing is most suited for CPU-bound operations, like machine learning and data processing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multithreading is most suited for IO-bound operations, like communicating with servers, or the file system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multiprocessing is not a magic wand; Don't use it unless you have to, or it could actually slow down your code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>computerscience</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Will NoSQL Databases Replace SQL Databases in the future</title>
      <dc:creator>Samuel Abolo</dc:creator>
      <pubDate>Mon, 25 Jul 2022 22:08:58 +0000</pubDate>
      <link>https://forem.com/tecnosam/will-nosql-databases-replace-sql-databases-in-the-future-3hoa</link>
      <guid>https://forem.com/tecnosam/will-nosql-databases-replace-sql-databases-in-the-future-3hoa</guid>
      <description>&lt;h2&gt;
  
  
  WILL NOSQL REPLACE SQL DATABASES IN THE FUTURE
&lt;/h2&gt;

&lt;p&gt;In this article, we will be discussing The following&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What SQL is (Pros and Cons)&lt;/li&gt;
&lt;li&gt;What NoSQL is (Pros and Cons)&lt;/li&gt;
&lt;li&gt;When to use SQL and to use NoSQL (ACID vs BASE)&lt;/li&gt;
&lt;li&gt;Will NoSQL replace SQL in the future? Why (not)?&lt;/li&gt;
&lt;li&gt;What the future of databases looks like (Databases supporting both SQL and NoSQL databases)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is SQL?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Freiqv6l8xmlntairo07v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Freiqv6l8xmlntairo07v.png" alt="An Example of an SQL query" width="800" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SQL stands for the structured query language. It’s the standard programming language for data definition, insertion, and manipulation in relational databases. &lt;br&gt;
An SQL database is basically a term used to classify relational databases that use SQL. &lt;br&gt;
The most popular ones are MySQL, PostgreSQL, Oracle SQL, and T-SQL. Data in SQL databases are represented in rows and columns, making it easier to write intuitive queries&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Pros&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ACID properties (Atomicity, Consistency, Isolation, and Durability)&lt;/strong&gt;&lt;br&gt;
SQL databases follow ACID principles in transactions.&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Atomicity&lt;/strong&gt; means that the data change in a transaction is interpreted as one. This means that if the transaction fails halfway for some reason, the database state is rolled back.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt; means that the data from the transaction is still checked against constraints placed on it in the database schema.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolation&lt;/strong&gt; means that any changes in a transaction is isolated and would'nt affect any changes in another transaction that's running concurrently. This means that two transactions manipulating the same data resource can't run at the same time but must be queued.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Durability&lt;/strong&gt; means that once the transaction is complete, it's changes will permanently reflect on the database.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easier to query&lt;/strong&gt;&lt;br&gt;
Data is normalized in rows and columns in SQL, making SQL databases perfect for complex queries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Larger community&lt;/strong&gt;&lt;br&gt;
It’s quite popular, so knowing how to work with SQL databases could improve your chances of landing a job as a data scientist, data analyst, or software engineer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Cons&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consistency for Performance tradeoff&lt;/strong&gt;&lt;br&gt;
SQL databases achieve atomicity, consistency, and isolation of data through something called data locks, which basically prevents a transaction from modifying or reading from a resource (row or column) while it’s being used by a different transaction. While this ensures consistency, it takes its toll on the performance of SQL databases compared to NoSQL databases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Difficult to scale&lt;/strong&gt;&lt;br&gt;
Horizontally scaling an SQL database can be painful. Techniques such as data sharding/partitioning and master-slave replication can be implemented, but they aren’t as easy as they sound making them difficult and expensive to scale.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is NoSQL?
&lt;/h2&gt;

&lt;p&gt;NoSQL is a term used to classify databases that don’t store data in a relational manner. While SQL databases only support storing data in rows and columns, we have different kinds of NoSQL databases that we can use, depending on our business needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Pros&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easier to scale&lt;/strong&gt;&lt;br&gt;
Database Sharding in NoSQL is a lot easier than Partitioning in SQL databases. Most NoSQL databases, in fact, do this for you, allowing you to focus on the business logic&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Faster queries&lt;/strong&gt;&lt;br&gt;
NoSQL databases do not follow ACID principles, instead, follow BASE principles. NoSQL databases also, don’t have to worry about joins, making NoSQL database queries faster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;More diverse&lt;/strong&gt;&lt;br&gt;
Ranging from key-value databases like dynamo DB to document-based databases like MongoDB, to graph databases like neo4j and Tigergraph, NoSQL databases could be a perfect fit for our business needs. &lt;br&gt;
For example, a road network database could make use of Graph databases, and a social media app could use MongoDB to store posts. A business can decide to use multiple NoSQL databases in its architecture&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Cons&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance for Consistency tradeoff&lt;/strong&gt;&lt;br&gt;
NoSQL databases don’t implement data locks, while this makes transactions/queries a lot faster than in SQL databases, data is not immediately consistent in the database, making it inappropriate for systems like FinTech applications or MedTech (systems that require data to be immediately consistent after a modification).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Smaller user community&lt;/strong&gt;&lt;br&gt;
SQL is more popular than NoSQL databases. Also, NoSQL is relatively new in the market, meaning most existing companies already have their database systems implemented in SQL.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to use SQL or NoSQL
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;When to use SQL&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We use SQL in systems whose data needs can be solved with ACID properties—finance Applications, Invoice Applications, and systems that value data consistency over faster queries.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;When to use NoSQL&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We use NoSQL databases in systems that require a high volume of data to be processed and stored. This is because NoSQL databases are highly scalable both in storage and in read-write performance. E.g Social media, Blogs, Streaming services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Will NoSQL replace SQL in the future?
&lt;/h2&gt;

&lt;p&gt;Both databases at this point in history, can’t replace each other, and it’s looking like it’ll stay that way. &lt;/p&gt;

&lt;p&gt;The only way NoSQL databases will surface as a replacement for SQL databases is if NoSQL can find a way to ensure that data is immediately consistent and still maintain its query speed.&lt;/p&gt;

&lt;p&gt;On the other hand, SQL could potentially replace NoSQL databases in some use cases in the future if they find ways to ensure ACID properties and at the same time not trade its query performance.&lt;/p&gt;

&lt;p&gt;Another key point is that most developers and data professionals find querying data with SQL easier and more intuitive than with any other method implemented by NoSQL databases. NoSQL databases like Apache Hive and Tigergraph have solved this problem by providing an SQL interface for querying data stored in its NoSQL databases&lt;/p&gt;

&lt;h2&gt;
  
  
  The future of DBMS
&lt;/h2&gt;

&lt;p&gt;The future of database systems is the best of both worlds. Combining the ACID properties of SQL with the BASE properties of NoSQL databases&lt;/p&gt;

&lt;p&gt;This can be achieved in our present day by implementing a microservices architecture. That way, services that require their database to possess ACID properties could use SQL, and those that require BASE properties could use NoSQL. A good example is Facebook, which uses MySQL, Apache Cassandra, and a lot more NoSQL and SQL databases&lt;/p&gt;

</description>
      <category>database</category>
      <category>sql</category>
      <category>nosql</category>
      <category>mongodb</category>
    </item>
  </channel>
</rss>
