<?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: Osahenru</title>
    <description>The latest articles on Forem by Osahenru (@osahenru).</description>
    <link>https://forem.com/osahenru</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%2F862520%2F73d9499b-d547-4f93-a91a-6ee6d8724244.jpg</url>
      <title>Forem: Osahenru</title>
      <link>https://forem.com/osahenru</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/osahenru"/>
    <language>en</language>
    <item>
      <title>Using dj-rest-auth to integrate GitHub authentication in your Django project</title>
      <dc:creator>Osahenru</dc:creator>
      <pubDate>Wed, 20 Nov 2024 08:33:34 +0000</pubDate>
      <link>https://forem.com/osahenru/using-dj-rest-auth-to-integrate-github-authentication-in-your-django-project-40gg</link>
      <guid>https://forem.com/osahenru/using-dj-rest-auth-to-integrate-github-authentication-in-your-django-project-40gg</guid>
      <description>&lt;p&gt;This article is a simple guide on how to implement GitHub OAuth for a secure user authentication.&lt;/p&gt;

&lt;p&gt;In this guide we will be able to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;seamlessly create or login a user using their GitHub credentials&lt;/li&gt;
&lt;li&gt;save users credentials for later use&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Prerequisite
&lt;/h3&gt;

&lt;p&gt;To get the best out of this article users should have a fair understanding on&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/get-started/start-your-journey/git-and-github-learning-resources" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.djangoproject.com/start/" rel="noopener noreferrer"&gt;Django&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.django-rest-framework.org/community/tutorials-and-resources/" rel="noopener noreferrer"&gt;Django rest framework&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are going to implement this in 3 simple steps&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. setup GitHub&lt;/li&gt;
&lt;li&gt;2. setup Django&lt;/li&gt;
&lt;li&gt;3. test authentication endpoint&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. Setup GitHub
&lt;/h3&gt;

&lt;p&gt;Create your GitHub OAuth credentials by going to to &lt;code&gt;settings&lt;/code&gt; on your GitHub account, scroll down to where you see &lt;code&gt;Developer settings&lt;/code&gt;, click on &lt;code&gt;OAuth Apps&lt;/code&gt; as shown below.&lt;br&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%2F0pf3re5fd1u3t2cijsp5.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%2F0pf3re5fd1u3t2cijsp5.png" alt="Image description" width="800" height="372"&gt;&lt;/a&gt;If you have an existing app you can edit it else you can create a new one by clicking on &lt;code&gt;New OAuth App&lt;/code&gt; and create a new one, give a clear and descriptive name for the app, add to your Homepage URL &lt;code&gt;http://localhost:8000/&lt;/code&gt; you might want to substitute &lt;code&gt;localhost:&lt;/code&gt; for &lt;code&gt;127.0.0.1:&lt;/code&gt; if that's how you've configured your Django app to run point been that whatever configuration you setup on GitHub should match with what you have on your app to avoid server errors been thrown, add to Authorization callback URL this callback url &lt;code&gt;http://localhost:8000/api/auth/github/login/callback/&lt;/code&gt; your setup should reflect what you see in the image below.&lt;br&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%2Fqjqk3ax4mqwon0c1d830.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%2Fqjqk3ax4mqwon0c1d830.png" alt="Image description" width="800" height="626"&gt;&lt;/a&gt;Copy and save your &lt;code&gt;Client ID&lt;/code&gt; and &lt;code&gt;Client Secrets&lt;/code&gt; as shown below for later use on your Django project &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%2Fs6y4cyqx155mqrmsyyzm.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%2Fs6y4cyqx155mqrmsyyzm.png" alt="Image description" width="800" height="206"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  2. Setup Django
&lt;/h3&gt;

&lt;p&gt;Run &lt;code&gt;pip install django-allauth  dj-rest-auth requests&lt;/code&gt; in other to install these packages. In the &lt;code&gt;settings.py&lt;/code&gt; file of your app add the following code block to your&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="n"&gt;SOCIALACCOUNT_PROVIDERS&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;github&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;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;APP&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;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;client_id&lt;/span&gt;&lt;span class="sh"&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;&amp;lt;github_client_id&amp;gt;&lt;/span&gt;&lt;span class="sh"&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;secret&lt;/span&gt;&lt;span class="sh"&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;&amp;lt;github_secret_keys&amp;gt;&lt;/span&gt;&lt;span class="sh"&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;key&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;SITE_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if you wish to capture the email of an authenticated users in the admin you can include this line of code to your projects &lt;code&gt;settings.py&lt;/code&gt; file&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="n"&gt;ACCOUNT_EMAIL_REQUIRED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We continue to modify our &lt;code&gt;settings.py&lt;/code&gt; file by adding the following code block&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;rest_framework&lt;/span&gt;&lt;span class="sh"&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;rest_framework.authtoken&lt;/span&gt;&lt;span class="sh"&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;dj_rest_auth&lt;/span&gt;&lt;span class="sh"&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;django.contrib.sites&lt;/span&gt;&lt;span class="sh"&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;allauth&lt;/span&gt;&lt;span class="sh"&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;allauth.account&lt;/span&gt;&lt;span class="sh"&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;allauth.socialaccount&lt;/span&gt;&lt;span class="sh"&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;allauth.socialaccount.providers.github&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
 in the middlesware of your &lt;code&gt;settings.py&lt;/code&gt; file include this line of code&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;allauth.account.middleware.AccountMiddleware&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;Lastly we modify the projects &lt;code&gt;urls.py&lt;/code&gt; file by adding the following code block&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;allauth.socialaccount.providers.github&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;github_views&lt;/span&gt;

&lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;api/auth/github/login/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;github_views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;oauth2_login&lt;/span&gt;&lt;span class="p"&gt;,&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;github_login&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;api/auth/github/login/callback/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;github_views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;oauth2_callback&lt;/span&gt;&lt;span class="p"&gt;,&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;github_callback&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;strong&gt;NB: The modification should be done in the project's &lt;code&gt;urls.py&lt;/code&gt; file and not the app's &lt;code&gt;urls.py&lt;/code&gt; file&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Test authentication endpoint
&lt;/h3&gt;

&lt;p&gt;All done ? visit the endpoint &lt;code&gt;http://localhost:8000/api/auth/github/login/&lt;/code&gt; you should be redirected to a page like this &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%2Fnt38690gnmzm4yryn3b0.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%2Fnt38690gnmzm4yryn3b0.png" alt="Image description" width="800" height="198"&gt;&lt;/a&gt; and when you click on the &lt;code&gt;Continue&lt;/code&gt; button you should be redirected to GitHub's authorization page &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%2Fscvgyucs079858xh9nyt.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%2Fscvgyucs079858xh9nyt.png" alt="Image description" width="800" height="626"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional consideration
&lt;/h3&gt;

&lt;p&gt;You notice after a successful authentication you're been redirected to &lt;code&gt;http://localhost:8000/accounts/profile/&lt;/code&gt; which displays a 404 error page. &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%2Fze5jxvbm86bii5p1g42t.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%2Fze5jxvbm86bii5p1g42t.png" alt="Image description" width="800" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To fix this we can create an endpoint &lt;code&gt;/accounts/profile&lt;/code&gt; to your apps &lt;code&gt;urls.py&lt;/code&gt; file and then create a relative views for that endpoint. If your endpoint and views are setup correctly then you should now see this instead of 404 error page &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%2Fm8a8zkx1y0p7w2w8lwzu.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%2Fm8a8zkx1y0p7w2w8lwzu.jpeg" alt="Image description" width="508" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Difference between dj-auth-rest and social-auth-app-django
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://dj-rest-auth.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;dj-auth-rest&lt;/a&gt; and &lt;a href="https://python-social-auth.readthedocs.io/en/latest/configuration/django.html" rel="noopener noreferrer"&gt;social-auth-app-django&lt;/a&gt; are both libraries used to facilitate authentication in Django projects, but they cater to different needs and operate differently&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dj-auth-rest&lt;/code&gt; is used for an API based project while &lt;code&gt;social-auth-app-django&lt;/code&gt; is used for a web based project and both can be used on the same project&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Integrating GitHub OAuth into your Django application provides a secure and user-friendly way for individuals to log in using their GitHub credentials. &lt;/p&gt;

&lt;p&gt;Using this guide, you can enhance your application's security, streamline the login process, and improve the overall user experience while accessing relevant user data.&lt;/p&gt;

</description>
      <category>github</category>
      <category>django</category>
      <category>python</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Using Canonical URLs for your next Django project</title>
      <dc:creator>Osahenru</dc:creator>
      <pubDate>Sat, 17 Aug 2024 03:34:10 +0000</pubDate>
      <link>https://forem.com/osahenru/using-canonical-urls-for-your-next-django-project-59kj</link>
      <guid>https://forem.com/osahenru/using-canonical-urls-for-your-next-django-project-59kj</guid>
      <description>&lt;h3&gt;
  
  
  What is a canonical URL?
&lt;/h3&gt;

&lt;p&gt;A canonical URL is the preferred version of a web page when there are multiple URLs that could lead to the same content. A canonical URL helps search engines understand which version of a web page should be considered the primary one for indexing. &lt;/p&gt;

&lt;p&gt;The concept of canonical URLs is important for search engine optimization (SEO) which helps prevent issues with duplicate content.&lt;/p&gt;

&lt;p&gt;When multiple URLs point to the same content, search engines might get confused and may not know which URL to prioritize in search results.&lt;/p&gt;

&lt;p&gt;Ensuring that each page has a canonical URL improves the clarity of your website structure to search engines. It consolidates link signals for duplicate or similar content, thus enhancing the overall ranking of your website.&lt;/p&gt;

&lt;p&gt;Example, we could have two URLs like this &lt;code&gt;http://127.0.0.1:8000/note/2024/7/18/how-to-become-more-self-disciplined/&lt;/code&gt; and this &lt;code&gt;http://127.0.0.1:8000/note/life-style/2024/7/18/how-to-become-more-self-disciplined/&lt;/code&gt; both pointing to the same content, to avoid duplicate content issues we can choose to canonicalize the former without a &lt;code&gt;life-style&lt;/code&gt; filter tags.&lt;/p&gt;

&lt;p&gt;Now, you might be wondering why a page will be rendering similar or nearly similar contents. Below are some highlighted reasons why a website might have duplicate contents&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Language: same content(duplicate), but different languages.&lt;/li&gt;
&lt;li&gt;URL Parameters: different URL parameters might lead to the same or similar content e.g., &lt;code&gt;/products/?category=shoes&amp;amp;sort=price&lt;/code&gt; vs. &lt;code&gt;/products/?sort=price&amp;amp;category=shoes&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Paginated Content: Content split across multiple pages e.g., &lt;code&gt;/articles/page/2&lt;/code&gt;, which might appear as duplicate content.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Canonical tag
&lt;/h3&gt;

&lt;p&gt;Canonical tag guides search engines in managing and prioritizing content this helps you define your primary page in search engines which in turn affects how performance metrics are tracked and analyzed.&lt;/p&gt;

&lt;p&gt;A canonical tag is found in the head section of an HTML page&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"canonical"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s see how we can use a canonical URL in a Django project&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing canonical URLs in Django
&lt;/h3&gt;

&lt;p&gt;Django allows you to implement the &lt;code&gt;get_absolute_url()&lt;/code&gt; on a model class to return a canonical URL for that object&lt;/p&gt;

&lt;p&gt;You can use the &lt;code&gt;get_absolute_url()&lt;/code&gt; method on Django models to generate a canonical URL for objects. This method typically returns the absolute URL for a model instance, which can be used as the canonical URL. In the &lt;code&gt;models.py&lt;/code&gt; file we can implement the  &lt;code&gt;get_absolute_url()&lt;/code&gt; method there&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SlugField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="err"&gt;…&lt;/span&gt;
    &lt;span class="n"&gt;publish&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&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;get_absolute_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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;reverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;note:detailed_note&lt;/span&gt;&lt;span class="sh"&gt;'&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slug&lt;/span&gt; &lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then implement this in the views by passing in the necessary arguments.&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;single_note&lt;/span&gt;&lt;span class="p"&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;year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;note&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_object_or_404&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Note&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;publish__year&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;publish__month&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;publish__day&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;day&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and lastly represent a canonical url in the template as shown&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;{% block head %} &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"canonical"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ note.get_absolute_url }}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; {% endblock %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;In summary, canonical URLs in Django are a best practice for managing how your content is indexed by search engines, preventing duplicate content issues, and ensuring that your website is optimized by search engines.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>seo</category>
      <category>django</category>
      <category>html</category>
    </item>
    <item>
      <title>Enhancing your Python code with decorators</title>
      <dc:creator>Osahenru</dc:creator>
      <pubDate>Mon, 03 Jun 2024 14:40:08 +0000</pubDate>
      <link>https://forem.com/osahenru/enhancing-your-python-code-with-decorators-27j4</link>
      <guid>https://forem.com/osahenru/enhancing-your-python-code-with-decorators-27j4</guid>
      <description>&lt;h4&gt;
  
  
  Introduction
&lt;/h4&gt;

&lt;p&gt;In this article, you'll learn about decorators in Python: how they work, why they are useful, and when to use them. We'll also explore some common decorators and their use cases.&lt;/p&gt;

&lt;p&gt;While I aim to explain concepts from a beginner's perspective, this article is not tailored for absolute beginners. A fundamental understanding of OOP in Python is required to fully benefit from this article. With that in mind, let's dive in.&lt;/p&gt;

&lt;p&gt;In Python and most programming languages, a decorator is a tool that allows you to modify the behavior of a function or method without changing it’s main behavior.&lt;/p&gt;

&lt;p&gt;They help add more functionality before a function is called or after it has been called. Decorators give you the ability to modify the behavior of functions without altering their main implementation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating Decorators
&lt;/h4&gt;

&lt;p&gt;A decorator in Python is a function that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accepts another function as an argument,&lt;/li&gt;
&lt;li&gt;Defines a new function inside itself,&lt;/li&gt;
&lt;li&gt;Returns that new function.
This is the basic template for creating decorators in Python.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, if we want to create a simple decorator function that multiplies the return value of any function by 10, we can do it like this:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mul_by_ten_decorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&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;wrapper_function&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;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

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


&lt;span class="c1"&gt;# target function
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;


&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nf"&gt;mul_by_ten_decorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;demo&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="nf"&gt;result&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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Notes📝
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;We have the mul_by_ten_decorator that takes a function as an argument. Inside, the wrapper_function calls func() (i.e., the passed function) and multiplies the result by 10.&lt;/p&gt;

&lt;p&gt;Moving to the demo function, which we use to test our decorator, it simply returns 2. The mul_by_ten_decorator wraps the demo function, so when demo is passed as an argument, the decorator multiplies its return value by 10. Calling result() is equivalent to calling wrapper_function(), which returns 20. This value is then printed to the screen when we run the code from the terminal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can further simplify our code by introducing the &lt;code&gt;@&lt;/code&gt; symbol&lt;/p&gt;

&lt;h4&gt;
  
  
  Introducing &lt;code&gt;@&lt;/code&gt; symbol in decorators
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mul_by_ten_decorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&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;wrapper_function&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;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

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

&lt;span class="c1"&gt;# target function
&lt;/span&gt;&lt;span class="nd"&gt;@mul_by_ten_decorator&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;


&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;demo&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;result&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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Notes📝
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;When we introduce the decorator symbol @, we can wrap our target function with our decorator function, making our code more encapsulated. By simply calling the demo() function, it is similar to calling the wrapper_function(), which internally calls func() (the demo function). The demo function returns 2, which is then multiplied by 10. The wrapper_function returns 20, which is assigned to result and printed out.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Passing Arguments to Wrapper Functions
&lt;/h4&gt;

&lt;p&gt;Sometimes, functions can take multiple arguments. If we modify our demo function to take two arguments, a and b, and return their product multiplied by 2, it would look like this:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mul_by_ten_decorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&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;wrapper_function&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;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

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


&lt;span class="nd"&gt;@mul_by_ten_decorator&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&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="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we run our code, we encounter a type error.&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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="nb"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;mul_by_ten&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;locals&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;takes&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;positional&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt; &lt;span class="n"&gt;but&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;were&lt;/span&gt; &lt;span class="n"&gt;given&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The error message implies that the wrapper_function is also expecting a number of arguments. We can modify our wrapper_function as follows:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapper_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&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;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;so the entire code block can further be modified like this&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mul_by_ten_decorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&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;wrapper_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&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;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

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


&lt;span class="c1"&gt;# target function
&lt;/span&gt;&lt;span class="nd"&gt;@mul_by_ten_decorator&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&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="n"&gt;result&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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Notes📝
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;Calling demo() is the same as calling the wrapper_function(), which in turn calls func(). Therefore, we must ensure these functions accept the same number of arguments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What if we want to add 20 numbers using this same decorator? Do we need to pass 20 arguments to both the target function and the wrapper function? We cannot always define the number of arguments for both functions explicitly. Instead, we can use Python's *args and **kwargs keywords.&lt;/p&gt;

&lt;p&gt;The *args keyword allows us to pass a variable number of positional arguments to the function, while **kwargs allows us to pass a variable number of keyword arguments.&lt;/p&gt;

&lt;p&gt;We can make our code block more Pythonic by introducing these keywords.&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mul_by_ten_decorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&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;wrapper_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&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;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

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


&lt;span class="c1"&gt;# target function
&lt;/span&gt;&lt;span class="nd"&gt;@mul_by_ten_decorator&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&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="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Notes📝
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;Now, our target function takes in two arguments, while our wrapper function accepts an arbitrary number of arguments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With a good understanding of how to use decorator functions, we can proceed to explore some use cases and the importance of using decorator functions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Use Case of Decorators in Python
&lt;/h4&gt;

&lt;p&gt;Let's examine some real-world examples where using a decorator comes in handy.&lt;/p&gt;

&lt;h5&gt;
  
  
  Logging
&lt;/h5&gt;

&lt;p&gt;It is often helpful to have logs of which functions are executed, along with relevant information. A logger is useful when you're trying to debug your code.&lt;/p&gt;

&lt;p&gt;Here is a simple example of how to create a logger using Python's built-in logging package. The information about the script is saved to a file named test.log:&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;logging&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;function_logger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&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;basicConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;test.log&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;wrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&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="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; ran with positional arguments: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; and keyword arguments: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. Return value: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&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="n"&gt;result&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;wrapper&lt;/span&gt;


&lt;span class="c1"&gt;# target function
&lt;/span&gt;&lt;span class="nd"&gt;@function_logger&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;addition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&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="nf"&gt;addition&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="mi"&gt;5&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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you first run this code, a &lt;strong&gt;test.log&lt;/strong&gt; file is created, which looks like this.&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="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;addition&lt;/span&gt; &lt;span class="n"&gt;ran&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;positional&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;keyword&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}.&lt;/span&gt; &lt;span class="n"&gt;Return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To see different log messages, we can change the values of the arguments passed, for example, &lt;strong&gt;(11, 12)&lt;/strong&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="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;addition&lt;/span&gt; &lt;span class="n"&gt;ran&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;positional&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;keyword&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}.&lt;/span&gt; &lt;span class="n"&gt;Return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;
&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;addition&lt;/span&gt; &lt;span class="n"&gt;ran&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;positional&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;keyword&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}.&lt;/span&gt; &lt;span class="n"&gt;Return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Notes📝
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;You can see our repeated template for creating a decorator:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; The decorator takes a function as an argument. ✅&lt;/li&gt;
&lt;li&gt;The wrapper function calls and returns a function. ✅&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We import Python’s logging module with import logging, which includes a &lt;strong&gt;BasicConfig&lt;/strong&gt; method that sets up the logging configuration. We pass the logging level, which can be &lt;strong&gt;logging.INFO&lt;/strong&gt;, &lt;strong&gt;logging.DEBUG&lt;/strong&gt;, or &lt;strong&gt;logging.ERROR&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once we wrap this logger decorator around a function, we can get information about the function, including the arguments passed and the returned value. This can be a very useful tool for debugging and error tracking.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For more about logging in Python, checkout the official documentation &lt;a href="https://docs.python.org/3/howto/logging.html"&gt;https://docs.python.org/3/howto/logging.html&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Caching
&lt;/h5&gt;

&lt;p&gt;Caching is another use case where the knowledge of decorators comes in very handy. Caching is a technique used to store the results of expensive functions that take the same arguments and return the same value each time they are called. Instead of always recalculating the results, we can cache the process. This approach ensures that too many resources aren’t used up on such expensive functions.&lt;/p&gt;

&lt;p&gt;To implement a caching function in Python, we use the &lt;strong&gt;@lru_cache&lt;/strong&gt; decorator from &lt;strong&gt;functools&lt;/strong&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Notes📝
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;LRU stands for Least Recently Used. The LRU function has a default maximum size of 128, which is the maximum number of calls to cache. Once this limit is reached, older results are discarded to make space for new ones.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Fibonacci sequence is a great example to illustrate the concept of caching because it depicts a recursive function, where calculating a Fibonacci sequence recalculates the same values multiple times.&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;functools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;lru_cache&lt;/span&gt;

&lt;span class="nd"&gt;@lru_cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;120&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;fibonacci&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&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;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;n&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&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;result&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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;demo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;55&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Notes📝
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;We use the &lt;strong&gt;lru_cache&lt;/strong&gt; decorator from &lt;strong&gt;functools&lt;/strong&gt;. When we call &lt;strong&gt;fibonacci(10)&lt;/strong&gt;, it recursively calls &lt;strong&gt;fibonacci(9)&lt;/strong&gt;, &lt;strong&gt;fibonacci(8)&lt;/strong&gt;, &lt;strong&gt;fibonacci(7)&lt;/strong&gt;, and so on until it reaches 1 or 0, ultimately outputting &lt;strong&gt;55&lt;/strong&gt; to the screen. If n is less than 1, it returns n; otherwise, it returns the sum of the function called with &lt;strong&gt;n-1&lt;/strong&gt; and &lt;strong&gt;n-2&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When we call &lt;strong&gt;fibonacci(30)&lt;/strong&gt; for the first time, it stops calling the Fibonacci function when it reaches &lt;strong&gt;10&lt;/strong&gt;, since we’ve previously run &lt;strong&gt;fibonacci(10)&lt;/strong&gt;. Similarly, when we run &lt;strong&gt;fibonacci(60)&lt;/strong&gt; for the first time, it stops calling the Fibonacci function at &lt;strong&gt;30&lt;/strong&gt; since we’ve previously run &lt;strong&gt;fibonacci(30)&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Therefore, a cached &lt;strong&gt;fibonacci()&lt;/strong&gt; function will execute faster compared to one that isn’t cached. We can write a script to demonstrate the time difference between a cached function and one that isn't cached.&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;functools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;lru_cache&lt;/span&gt;

&lt;span class="c1"&gt;# Fibonacci function without caching
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fibonacci_no_cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&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;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;n&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fibonacci_no_cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;fibonacci_no_cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Fibonacci function with caching
&lt;/span&gt;&lt;span class="nd"&gt;@lru_cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Use LRU cache with unlimited size
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fibonacci_with_cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&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;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;n&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fibonacci_with_cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;fibonacci_with_cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Calculate Fibonacci(30) without caching and measure the time
&lt;/span&gt;&lt;span class="n"&gt;start_time&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;fibonacci_no_cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;no_cache_time&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="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start_time&lt;/span&gt;

&lt;span class="c1"&gt;# Calculate Fibonacci(30) with caching and measure the time
&lt;/span&gt;&lt;span class="n"&gt;start_time&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;fibonacci_with_cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;with_cache_time&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="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start_time&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 without cache: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;no_cache_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;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 with cache: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;with_cache_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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;Time&lt;/span&gt; &lt;span class="n"&gt;without&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;3.886222839355469e-05&lt;/span&gt;
&lt;span class="n"&gt;Time&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;2.2172927856445312e-05&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Notes📝
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;We see the differences in time it takes to run a cached function and one that isn't: &lt;strong&gt;cached 0.0000221729&lt;/strong&gt;, &lt;strong&gt;not cached 0.0000388622&lt;/strong&gt;. You can see we reduce the time by almost half.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Caching is particularly effective for recursive functions like Fibonacci, where the same inputs are used repeatedly. It saves time by avoiding redundant calculations, especially for large or frequently accessed values.&lt;/p&gt;

&lt;p&gt;Now that we've explored some use cases where knowledge of decorators in Python can be very handy, let's further look at some of the built-in decorators that come with Python.&lt;/p&gt;

&lt;h4&gt;
  
  
  Python Decorators
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Properties
&lt;/h5&gt;

&lt;p&gt;Properties are built-in Python functions for managing methods of a class. They allow you to define methods that get and set the values of attributes, providing a way to enforce rules and validation when accessing or modifying these attributes. Properties are typically used to encapsulate private attributes and control access to them.&lt;/p&gt;

&lt;p&gt;Let's see an example of how properties work in a class method:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Circle&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;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;diameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;radius&lt;/span&gt;

&lt;span class="n"&gt;circle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&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;circle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;diameter&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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can access the diameter method as an attribute, instead of calling the function with circle.diameter(), thanks to the @property decorator.&lt;/p&gt;

&lt;p&gt;The beauty of having property decorators is how they make our code more concise. We can choose to make our diameter method stricter by ensuring the radius doesn’t take numbers less than or equal to zero, like this:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Circle&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;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;diameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Only positive numbers&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="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;radius&lt;/span&gt;

&lt;span class="n"&gt;circle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&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;circle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;diameter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;when we run the code, a value error is raised as shown below&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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Only positive numbers&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Only&lt;/span&gt; &lt;span class="n"&gt;positive&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Setters and Getters
&lt;/h5&gt;

&lt;p&gt;A getter method is responsible for retrieving the current value of a property, decorated with the @property decorator, while a setter method is responsible for setting the value of a property. The setter method is called when the property is assigned a new value.&lt;/p&gt;

&lt;p&gt;One major flaw in how we've implemented validation above is that if we have other methods that rely on the radius being positive, this current approach might not handle invalid values properly. This can lead to subtle bugs or crashes. For example, consider a circumference method:&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="nd"&gt;@property&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;circumference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;3.14159&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;radius&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The circumference property does not currently validate whether the radius is a positive number or not. It would be redundant to validate the radius within the circumference method. Instead, we can introduce setter and getter properties for our radius.&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Circle&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;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_radius&lt;/span&gt;


    &lt;span class="nd"&gt;@radius.setter&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&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;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Positive numbers only&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;


    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;diameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;radius&lt;/span&gt;


    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;circumference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;3.14159&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;radius&lt;/span&gt;


&lt;span class="n"&gt;circle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Diameter: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;diameter&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="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;Circumference: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;circumference&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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;Diameter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="n"&gt;Circumference&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;62.8318&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Notes📝
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;Our getter method retrieves the current value of the radius and returns it, while our setter method decorator checks the validity of the value. If the value is valid, it is assigned to the radius &lt;strong&gt;self._radius&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Notice that in our getter and setter methods, we use &lt;strong&gt;_radius&lt;/strong&gt; to avoid the function calling itself repeatedly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
  Deleters
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;The deleter function in a Python property decorator is used to define the behavior when an attribute is deleted using the &lt;strong&gt;del&lt;/strong&gt; statement. Like the getter and setter functions, it allows you to control access to an attribute, but specifically handles what happens when you delete the attribute.&lt;/p&gt;

&lt;p&gt;Returning to our circle class, let’s include a deleter property that defines how the class should behave when a radius in a circle object is deleted.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Circle&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;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_radius&lt;/span&gt;


    &lt;span class="nd"&gt;@radius.setter&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&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;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Positive numbers only&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_radius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;


    &lt;span class="nd"&gt;@radius.deleter&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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;Radius deleted&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_radius&lt;/span&gt;


    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;diameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;radius&lt;/span&gt;


    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;circumference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;3.14159&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;radius&lt;/span&gt;


&lt;span class="n"&gt;circle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Diameter: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;diameter&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="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;Circumference: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;circumference&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;del&lt;/span&gt; &lt;span class="n"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;radius&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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;Diameter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="n"&gt;Circumference&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;62.8318&lt;/span&gt;
&lt;span class="n"&gt;Radius&lt;/span&gt; &lt;span class="n"&gt;deleted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Class method (@classmethod)
&lt;/h4&gt;

&lt;p&gt;A class method is a method that is bound to the class rather than the instance of the class. It takes the class itself as its first argument (cls) instead of the instance (self). This allows the method to access and modify class state that applies across all instances of the class. A class method can be called by both the class and its instances.&lt;/p&gt;

&lt;p&gt;Let's see how to use a class method in a class by modeling a Person:&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;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&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;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;

    &lt;span class="nd"&gt;@classmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;birth_year&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&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="n"&gt;year&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;cls&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="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;year&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;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&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;Name: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, Year: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;birth_year&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Doe&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;34&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;person&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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Doe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1990&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Notes📝
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;Notice that we can call the &lt;strong&gt;birth_year()&lt;/strong&gt; method directly on the class without creating a Person instance, e.g., &lt;strong&gt;person = Person('Doe', 34)&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's take a look at another example that explains the use of &lt;strong&gt;@classmethod&lt;/strong&gt; in a code block.&lt;/p&gt;

&lt;p&gt;Assuming we have an employee record, we can use a class method to retrieve individual employee records based on the PRIMARY KEY passed.&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;sqlite3&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Employee&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;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&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="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;

    &lt;span class="nd"&gt;@classmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;from_database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

        &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;employees.db&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SELECT name, salary FROM employees WHERE id=?&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;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,))&lt;/span&gt;
        &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&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;row&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="n"&gt;salary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&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="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Employees not found&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;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="n"&gt;employee_1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_database&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;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employee_1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But before we run this code, let's create a &lt;strong&gt;database.py&lt;/strong&gt; file that will set up our database of employees.&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;sqlite3&lt;/span&gt;

&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;employees.db&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'''&lt;/span&gt;&lt;span class="s"&gt;CREATE TABLE IF NOT EXISTS employees
               (id INTEGER PRIMARY KEY, name TEXT, salary REAL)&lt;/span&gt;&lt;span class="sh"&gt;'''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INSERT INTO employees (id, name, salary) VALUES (1, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Ohemaa&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, 10000)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INSERT INTO employees (id, name, salary) VALUES (2, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Nana&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, 3000)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INSERT INTO employees (id, name, salary) VALUES (3, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Kofi&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, 15000)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM employees&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchall&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;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&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;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we run &lt;strong&gt;database.py&lt;/strong&gt; for the first time it creates an &lt;code&gt;employee.db&lt;/code&gt; file as shown below&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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Ohemaa&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;10000.0&lt;/span&gt;&lt;span class="p"&gt;)&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Nana&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3000.0&lt;/span&gt;&lt;span class="p"&gt;)&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;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Kofi&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;15000.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when we run our &lt;code&gt;main.py&lt;/code&gt; file we can get the individual associated to the PRIMARY_KEY passed&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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="n"&gt;Kofi&lt;/span&gt; &lt;span class="mf"&gt;15000.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Notes📝
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;In the classmethod in our &lt;strong&gt;main.py&lt;/strong&gt; file,&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;   &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;employees.db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT name, salary FROM employees WHERE id=?&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;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,))&lt;/span&gt;
       &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;We establish and close the connection with our &lt;strong&gt;employees.db&lt;/strong&gt; and then unpack the values of the &lt;strong&gt;row&lt;/strong&gt; into &lt;strong&gt;name&lt;/strong&gt; and &lt;strong&gt;salary&lt;/strong&gt;. This allows us to use a classmethod without creating an employee instance to access an employee record. If we were to implement this using an instance method, it would require us to create an empty employee object first, like &lt;strong&gt;employee = Employee(0, '', '')&lt;/strong&gt;, before fetching the record, which might seem a bit too complex.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Static method (@staticmethod)
&lt;/h4&gt;

&lt;p&gt;In a static method, you don’t need to pass an explicit first argument like &lt;strong&gt;cls&lt;/strong&gt; in a classmethod or &lt;strong&gt;self&lt;/strong&gt; in an instance method. A static method is also bound to a class and somewhat behaves like a class method. The major differences are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A static method doesn’t take an instance of the class as its first argument, unlike a classmethod or instance method.&lt;/li&gt;
&lt;li&gt;A static method cannot modify the state of the class.&lt;/li&gt;
&lt;li&gt;It is primarily used as a utility function that does not depend on the state of the class or its instances.&lt;/li&gt;
&lt;li&gt;A static method is defined using the &lt;strong&gt;@staticmethod&lt;/strong&gt; decorator.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A staticmethod is most suitable in scenarios where you need to perform a function on a class without keeping a record of the instances of the class, as shown below:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nd"&gt;@staticmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&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;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

    &lt;span class="nd"&gt;@staticmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&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;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&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;Addition: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&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="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;Multiply: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# you can also create a calculator instance
&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Calculator&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Addition: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;)&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="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;Multiply: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;Addition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;
&lt;span class="n"&gt;Multiply&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;270&lt;/span&gt;

&lt;span class="n"&gt;Addition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;34&lt;/span&gt;
&lt;span class="n"&gt;Multiply&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You notice we do not need to rely on a class instance to use a static method.&lt;/p&gt;

&lt;p&gt;Let's take a look at another example that calculates the average salary of employees in a company.&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Company&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="nd"&gt;@staticmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;average_salary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employees&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;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;data&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;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bob&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Charlie&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;70000&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Average salary: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Company&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;average_salary&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="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="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;Average&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You see that the staticmethod doesn’t need to know or modify anything in the class other than having access to the class name.&lt;/p&gt;

&lt;p&gt;In summary, static methods are within a class and do not need access to the class (no self or cls keyword). They cannot change or look at any object attributes or call other methods within the class. Static methods are mostly suitable as helper or utility functions that are relevant to the class but do not need to access or modify class or instance data.&lt;/p&gt;

&lt;h4&gt;
  
  
  Abstract method (@abstractmethod)
&lt;/h4&gt;

&lt;p&gt;Lastly, let’s take a look at abstractmethod in Python.&lt;/p&gt;

&lt;p&gt;An abstract class acts as an interface for other subclasses, serving as a blueprint and forcing all subclasses to implement all of its abstract methods. An abstract base class cannot be instantiated directly.&lt;/p&gt;

&lt;p&gt;Python does not provide abstract classes natively, but rather comes with a module that provides the base for defining Abstract Base Classes (ABC).&lt;/p&gt;

&lt;p&gt;You use an @abstractmethod when all children of a subclass are required to have the same method as the inherited abstract class. Like the example below&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;abc&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;abstractmethod&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_salary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FullTimeEmployee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Employee&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;calculate_salary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Calculating salary for full-time employee&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PartTimeEmployee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Employee&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;calculate_salary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Calculating salary for part-time employee&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContractEmployee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Employee&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;calculate_salary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Calculating salary for contract employee&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Notes📝
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;Employee(ABC) defines an abstract class, which cannot be instantiated. If a class inherits from an abstract class, it must implement all the abstract methods defined in the parent abstract class. Otherwise, it will also be considered an abstract class and cannot be instantiated.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
  Abstract property
&lt;/h5&gt;

&lt;p&gt;Just like with abstractmethod, an abstract property must also be implemented in any subclass. This allows you to specify that a subclass must include a property with a getter (and optionally a setter) method.&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;abc&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;abstractmethod&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Employee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;The salary property must be implemented by all subclasses&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FullTimeEmployee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Employee&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;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base_salary&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;base_salary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base_salary&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;base_salary&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PartTimeEmployee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Employee&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;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hourly_rate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hours_worked&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hourly_rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hourly_rate&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hours_worked&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hours_worked&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hourly_rate&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hours_worked&lt;/span&gt;

&lt;span class="c1"&gt;# Example usage
&lt;/span&gt;&lt;span class="n"&gt;full_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FullTimeEmployee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;part_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PartTimeEmployee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Full_time Salary: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;full_time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;salary&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="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;Part_time Salary: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;part_time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;salary&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;h5&gt;
  
  
  Notes📝
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;Every child class (FullTimeEmployee and PartTimeEmployee) has the salary property, although with different implementations. One takes in one argument and the other takes two. When we run the code, we get the following output:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;john&lt;/span&gt;&lt;span class="nd"&gt;@doe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;python3&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;span class="n"&gt;Full_time&lt;/span&gt; &lt;span class="n"&gt;Salary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50000&lt;/span&gt;
&lt;span class="n"&gt;Part_time&lt;/span&gt; &lt;span class="n"&gt;Salary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;FullTimeEmployee and PartTimeEmployee are concrete subclasses that provide specific implementations for the salary property. The salary methods in both subclasses are concrete methods. Concrete methods are methods that have a complete implementation within a class. They contain actual code that defines what the method does, as opposed to abstract methods, which only declare the method's signature without providing an implementation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;An understanding of decorators can help you write cleaner, more maintainable, and reusable code. Decorators are a flexible and readable way to modify the behavior of functions and methods. They are useful for a variety of tasks such as logging, authorization, and caching.&lt;/p&gt;

</description>
      <category>python</category>
      <category>backend</category>
      <category>webdev</category>
      <category>learning</category>
    </item>
    <item>
      <title>Regex pattern in Python: A beginners guide</title>
      <dc:creator>Osahenru</dc:creator>
      <pubDate>Fri, 26 Apr 2024 13:26:34 +0000</pubDate>
      <link>https://forem.com/osahenru/regex-pattern-in-python-a-beginners-guide-lmb</link>
      <guid>https://forem.com/osahenru/regex-pattern-in-python-a-beginners-guide-lmb</guid>
      <description>&lt;p&gt;Regular expression (regex) is a sequence of characters that define a search pattern, usually used for text search, text manipulation, and input validation&lt;/p&gt;

&lt;p&gt;In this tutorial we are going to see  how to validate, clean and extract users data, using code examples to explain the concepts of regular expressions in Python.&lt;/p&gt;

&lt;p&gt;At the end of this tutorial, I hope you'll be more confident in using regex in your next project or have a better understanding when you encounter it in a codebase.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^[a-zA-Z0-9.!#$%&amp;amp;'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Insight💡: The regex pattern above is used to validate an email address. I know it looks really cryptic, but as we look at examples, you will begin to have a more in-depth understanding.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's start by updating our vocabulary with some common metacharacters used in regex.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.   any character except a new line
*   0 or more repetitions
+   1 or more repetitions
?   0 or 1 repetition
{m} m repetitions
{m,n} m-n repetitions
^   matches the start of the string
$   matches the end of the string or just before the newline at the end of the string
\ Used to drop the special meaning of character following it
| Means OR (A|B) A or B
(...)   a group
(?:...) non-capturing version
[]    set of characters
[^]   complementing the set
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's write some code to better understand the regex syntax above, as we will be revisiting this code block frequently.&lt;/p&gt;

&lt;h2&gt;
  
  
  VALIDATING USERS DATA
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Example 1: IP address validator:
&lt;/h3&gt;

&lt;p&gt;Ideally, an IP address should consist of four sets of numbers separated by periods, with each set ranging from 0 to 255 and typically represented with at most three digits (e.g., 192.168.1.1). Each set is called an octet, represented in decimal form. That said, let's see how we can pattern a user's IPv4 address.&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;re&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&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="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;IPv4 Address: &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;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^(\d{1,3}\.){3}\d{1,3}$&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&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="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s break down this pattern to understand what each syntax does&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^ -matches the beginning of the string
\d -numbers only, i.e a letter will return False
{1, 3} -do something either once or 3 times i.e the number can be one - three digits, i.e 0 - 999
\. -a literal dot(.), if we do not use the backslash the re.search function will interpret . as any character except a new line
(\d{1,3}\.) -a group of pattern
{3} -do something 3 times, so we want to do whatever is in the group parenthesis (\d{1,3}\.) 3 times which will match something like this 192.168.1.
\d -digits
{1, 3} -do something either once or 3 times
$ -matches the end of the string or just before the newline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our code above checks if a user's IP address has four sets of octet numbers. However, it does not check if each octet number is between 0 and 255. Therefore, an IP address like 1.300.600.5 will return True instead of False. To fix this, we can include some extra logic. Modify the code as follows&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 2: IP address validator:
&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;re&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&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="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;IPv4 Address: &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;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^(\d{1,3}\.){3}\d{1,3}$&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

    &lt;span class="n"&gt;ip_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&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="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&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="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&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;for&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ip_list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&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="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s update our regex vocabulary to see how we can improve our existing code base&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\d    decimal digit
\D    not a decimal digit
\s    whitespace characters
\S    not a whitespace character
\w    word character, as well as numbers and the underscore
\W    not a word character
\b word bound, matches if a word matches the beginning and end of a word
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's see how we might be able to use regex to extract data from a user's input&lt;/p&gt;

&lt;h2&gt;
  
  
  EXTRACTING DATA
&lt;/h2&gt;

&lt;p&gt;Assuming we have a Facebook URL &lt;code&gt;https://www.facebook.com/johndoe&lt;/code&gt; and we want to extract just the username, how might we go about this using our bank of rich regex vocabulary? We can think of various ways to implement this. One straightforward approach is to introduce the use of the &lt;code&gt;re.sub()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;re.sub()&lt;/code&gt; function in Python is used for replacing substrings that match a specified pattern with a replacement string. It takes three main arguments: &lt;code&gt;re.sub(pattern, replacement, string)&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 3: Username extractor:
&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;re&lt;/span&gt;


&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://www.facebook.com/johndoe&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://www.facebook.com/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&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;text&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;matches&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: This code assumes that every Facebook URL begins with &lt;code&gt;https://www.&lt;/code&gt;, but you can take it up as a challenge to pattern URLs that begin with &lt;code&gt;http://www.&lt;/code&gt; or just &lt;code&gt;www.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I hope at this point it's all beginning to make sense. If not, let's cover some more examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  CLEANING DATA
&lt;/h2&gt;

&lt;p&gt;Sometimes, phone books append special characters and whitespaces to a phone number. How about we write a pattern to clean the data of a user’s phone number? Let's revisit our rich metacharacter vocabulary.&lt;/p&gt;

&lt;p&gt;Assuming we want to get rid of the &lt;code&gt;(+233)&lt;/code&gt; and replace it with a &lt;code&gt;0&lt;/code&gt;, how might we go about it? Well, let's take a look at the example below&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 4: Phone number book:
&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;re&lt;/span&gt;


&lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;(+233) 546 07890&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;\(\+233\)&lt;/span&gt;&lt;span class="sh"&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;0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone_number&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;matches&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;546&lt;/span&gt; &lt;span class="mi"&gt;07890&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can further improve this code by removing the whitespaces, again, by using the &lt;code&gt;re.sub()&lt;/code&gt; function&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 5: Phone number book
&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;re&lt;/span&gt;

&lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;(+233) 546 07890&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;\(\+233\)&lt;/span&gt;&lt;span class="sh"&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;0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;rematched_pattern&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&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;matches&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;rematched_pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;054607890&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  MORE REGEX FUNCTION
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;re.fullmatch()&lt;/code&gt; function in regex checks whether the entire string satisfies the pattern. It returns a match object if there is a match and &lt;code&gt;None&lt;/code&gt; otherwise. This means that you have to pattern the entire string for the &lt;code&gt;re.fullmatch()&lt;/code&gt; function to return a match object; otherwise, it returns &lt;code&gt;None&lt;/code&gt;. This is unlike the &lt;code&gt;re.search()&lt;/code&gt; function, which looks for the pattern anywhere in the string. Consider the example below:&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 6 with fullmatch:
&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;re&lt;/span&gt;
&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;123abcd&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; 
&lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fullmatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;\d+&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&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;matches&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run this program, you'll notice that the &lt;code&gt;re.fullmatch()&lt;/code&gt; function returns &lt;code&gt;None&lt;/code&gt; because we only tried to match the digits part of the string with &lt;code&gt;r'\d+'&lt;/code&gt;. Now, let's write the same pattern, but using the &lt;code&gt;re.search()&lt;/code&gt; function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 7 with search():
&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;re&lt;/span&gt;

&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;123abcd&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; 
&lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;\d+&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&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;matches&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Match&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&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;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;123&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While the &lt;code&gt;re.fullmatch()&lt;/code&gt; function returns &lt;code&gt;None&lt;/code&gt;, the &lt;code&gt;re.search()&lt;/code&gt; function returns a match object. This illustrates that using the &lt;code&gt;re.fullmatch()&lt;/code&gt; function would have been a simpler approach for our IP address example above, as we are mapping an entire string of data.&lt;/p&gt;

&lt;h3&gt;
  
  
  re.fullmatch() vs. re.match()
&lt;/h3&gt;

&lt;p&gt;The main difference is that &lt;code&gt;re.fullmatch()&lt;/code&gt; searches the entire string (from beginning to end) for a pattern, whereas &lt;code&gt;re.match()&lt;/code&gt; only searches the beginning for a match. It returns a match object if a match is found, otherwise &lt;code&gt;None&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Use fullmatch(), match(), or search()
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;re.fullmatch()&lt;/code&gt;: Use when you want to ensure the entire string matches a pattern. For example, to validate a string against a specific format, such as checking if a string is a valid date or a sequence of digits.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;re.match()&lt;/code&gt;: Use when you want to find a match only at the beginning of a string. For example, to validate user input, such as checking if a string starts with a specific prefix.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;re.search()&lt;/code&gt;: Use when you want to find a match anywhere in a string. For example, to check if a string contains a specific pattern, such as a certain word or sequence of characters.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In general, if you are unsure which function to use, &lt;code&gt;re.search()&lt;/code&gt; is often a good choice because it is more flexible and can be used to find patterns anywhere in the string. On a surface level, one could argue that &lt;code&gt;re.match()&lt;/code&gt; and &lt;code&gt;re.fullmatch()&lt;/code&gt; are just shortcuts, as &lt;code&gt;re.search()&lt;/code&gt; can perform the functions of both &lt;code&gt;re.match()&lt;/code&gt; and &lt;code&gt;re.fullmatch()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  COMMON FLAGS
&lt;/h2&gt;

&lt;p&gt;To optimize the functionality of a regex function, you can include flags. We will discuss three common flags used in regex.&lt;/p&gt;

&lt;h3&gt;
  
  
  re.IGNORECASE(re.I)
&lt;/h3&gt;

&lt;p&gt;This flag ignores case sensitivity in a pattern, allowing uppercase and lowercase letters to be matched interchangeably.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 8: without the re.IGNORECASE flag:
&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;re&lt;/span&gt;

&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;123ABCDabcd&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;[A-Z]+&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&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;matches&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code prints out a match object &lt;code&gt;&amp;lt;re.Match object; span=(3, 7), match='ABCD'&amp;gt;&lt;/code&gt;, omitting lowercase characters. Let's consider another version of the same code where we use the &lt;code&gt;re.IGNORECASE&lt;/code&gt; flag and observe the output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 9: with the re.IGNORECASE flag:
&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;re&lt;/span&gt;

&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;123ABCDabcd&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="n"&gt;matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;[A-Z]+&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IGNORECASE&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;matches&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that with the &lt;code&gt;re.IGNORECASE&lt;/code&gt; flag, we have a different printout &lt;code&gt;&amp;lt;re.Match object; span=(3, 11), match='ABCDabcd'&amp;gt;&lt;/code&gt;, which includes all characters (due to case-insensitivity).&lt;/p&gt;

&lt;h3&gt;
  
  
  re.MULTILINE (re.M)
&lt;/h3&gt;

&lt;p&gt;This flag allows &lt;code&gt;^&lt;/code&gt; (caret) and &lt;code&gt;$&lt;/code&gt; (dollar) to match the pattern at the beginning of the string and at the beginning of each newline (&lt;code&gt;\n&lt;/code&gt;). It also allows them to match the pattern at the end of the string and at the end of each newline (&lt;code&gt;\n&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 10 without the re.MULTILINE flag:
&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;re&lt;/span&gt;

&lt;span class="n"&gt;target_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Joy lucky number is 75&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Tom lucky number is 25&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^\w{3}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target_str&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;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&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;Joy&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;The code above ignores every third word after a newline (&lt;code&gt;\n&lt;/code&gt;). With a modified version like this...&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 11 with the re.MULTILINE flag:
&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;re&lt;/span&gt;

&lt;span class="n"&gt;target_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Joy lucky number is 75&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Tom lucky number is 25&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^\w{3}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target_str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MULTILINE&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;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&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;Joy&lt;/span&gt;&lt;span class="sh"&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;Tom&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;we can ignore the new line character and print out every 3 word.&lt;/p&gt;

&lt;h3&gt;
  
  
  re.DOTALL (re.S)
&lt;/h3&gt;

&lt;p&gt;By default, the &lt;code&gt;.&lt;/code&gt; inside a regular expression pattern represents any character (a letter, digit, symbol, or punctuation mark), except the newline character (&lt;code&gt;\n&lt;/code&gt;). However, this behavior can be altered using the &lt;code&gt;re.DOTALL&lt;/code&gt; flag.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 12 without the re.DOTALL flags:
&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;re&lt;/span&gt;

&lt;span class="n"&gt;target_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;ML 
and AI&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&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;target_str&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;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Match&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&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;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ML &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 13 with the re.DOTALL flag:
&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;re&lt;/span&gt;

&lt;span class="n"&gt;target_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;ML 
and AI&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&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;target_str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DOTALL&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;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Match&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&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;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ML &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;and AI&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can see it included the nextline character to the match object&lt;/p&gt;

&lt;h2&gt;
  
  
  CONCLUSION
&lt;/h2&gt;

&lt;p&gt;The key to writing a good regex pattern is to visually model the pattern based on the data given and tweak it as you progress, rather than relying solely on memory. Remember to test your pattern against a variety of inputs to ensure it behaves as expected. Please leave a comment below if any questions or for further clarifications. Happy coding!&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>regex</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Getting Started with Python's map() Function: A Beginner's Guide</title>
      <dc:creator>Osahenru</dc:creator>
      <pubDate>Tue, 26 Mar 2024 00:31:26 +0000</pubDate>
      <link>https://forem.com/osahenru/getting-started-with-pythons-map-function-a-beginners-guide-l8c</link>
      <guid>https://forem.com/osahenru/getting-started-with-pythons-map-function-a-beginners-guide-l8c</guid>
      <description>&lt;p&gt;In Python, &lt;code&gt;a map()&lt;/code&gt; refers to the process of applying a function to each item in an iterable (like a list, tuple, or dictionary) and returning a new iterable with the results. &lt;code&gt;map()&lt;/code&gt; function takes two arguments: a function and an iterable. The function is applied to each item in the iterable, and the results are returned as a new iterable. These terminologies might sound a bit unfamiliar so let’s explain with some examples&lt;/p&gt;

&lt;p&gt;&lt;code&gt;syntax:&lt;/code&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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;iterables&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming we have a string &lt;code&gt;“1/2"&lt;/code&gt; from a user’s input and we want to perform an arithmetic operation on this string, how might we go about that, well lets list out the steps&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional approach&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Step 1&lt;/strong&gt;&lt;br&gt;
Split the fraction, using the &lt;code&gt;split()&lt;/code&gt; method and &lt;code&gt;“/”&lt;/code&gt; as it’s delimiter&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="err"&gt;“&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.split(“/”)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;br&gt;
The split function returns a list of two values(strings) which we can assign to an unpacked variable &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&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="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.split(“/”)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;&lt;br&gt;
Convert a and b to an int&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="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;&lt;br&gt;
Finally we perform our arithmetic operation with&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="n"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&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;answer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Putting everything together we have 5 lines of code&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="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1/2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&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;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fraction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&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;fraction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Output: 0.5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using map() function&lt;/strong&gt;&lt;br&gt;
Now, lets see how we can use the map function to achieve same result but with fewer lines of code&lt;br&gt;
&lt;strong&gt;Step 1&lt;/strong&gt;&lt;br&gt;
Split the fraction, using the &lt;code&gt;split()&lt;/code&gt; method &lt;code&gt;“/”&lt;/code&gt; as it’s delimiter&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="err"&gt;“&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.split(“/”)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;br&gt;
The split function returns a list of two values(strings) which we can assign to an unpack value&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="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.split(“/”)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;&lt;br&gt;
Use the &lt;code&gt;map()&lt;/code&gt; function to convert the return values of the &lt;code&gt;split()&lt;/code&gt; to an int&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="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;map&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="err"&gt;“&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.split(“/”))
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;&lt;br&gt;
Finally we perform our arithmetic operation with&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="n"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Putting all together we have 3 lines of code as to 5 lines of code from the traditional method&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="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;map&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1/2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&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;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&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;answer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Output:0.5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note that the &lt;code&gt;split()&lt;/code&gt; function returns a list of strings &lt;code&gt;[“1”, “2”]&lt;/code&gt; and key word &lt;code&gt;int&lt;/code&gt; is a python function which is applied to each item in the list and these values are unpacked and assigned to the variable &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Map() and Lambda, What is a Lambda function ?&lt;/strong&gt;&lt;br&gt;
A lambda function is an anonymous function defined using the lambda keyword. It is a small, inline function that can have any number of arguments but can only have one expression.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Syntax:&lt;/code&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="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;br&gt;
Assuming we need a function that adds two numbers together, let us see how we can achieve this using both the traditional way and the lambda function &lt;br&gt;
&lt;strong&gt;Traditional way&lt;/strong&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and to call this function in the main function will be like this&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&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;&lt;code&gt;Output:7&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Using a lambda function&lt;/strong&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="n"&gt;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and we call the function in the main function, same way&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Output: 15&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As seen from the example above a lambda function can take any number of arguments&lt;/p&gt;

&lt;p&gt;Now lets see an example as to how we can use both a &lt;code&gt;map()&lt;/code&gt; and &lt;code&gt;lambda&lt;/code&gt; function&lt;/p&gt;

&lt;p&gt;assuming we want a function that returns a list but the first character of each word of this list is being capitalized, say we want to convert a list like this &lt;code&gt;[“serah”, “hakim”, “adam”, “kwame”]&lt;/code&gt; to this &lt;code&gt;[“Serah”, “Hakim”, “Adam”, “Kwame”]&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional approach&lt;/strong&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;title_each_word&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word_list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="n"&gt;new_word&lt;/span&gt; &lt;span class="o"&gt;=&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;word&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;word_list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
       &lt;span class="n"&gt;new_word&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&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;new_word&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;title_each_word&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;serah&lt;/span&gt;&lt;span class="sh"&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;simi&lt;/span&gt;&lt;span class="sh"&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;nana&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;code&gt;Output: [“Serah”, “Hakim”, “Adam”, “Kwame”]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using lambda and map() function&lt;/strong&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="n"&gt;word&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;serah&lt;/span&gt;&lt;span class="sh"&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;hakim&lt;/span&gt;&lt;span class="sh"&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;adam&lt;/span&gt;&lt;span class="sh"&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;kwame&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;new_word&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;word&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="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_word&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Output: [“Serah”, “Hakim”, “Adam”, “Kwame”]&lt;/code&gt;&lt;br&gt;
You can see how concise the map and lambda function have made our code look like, now when does one use a lambda function or a map function&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;map()&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;lambda&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;It is used when you want to apply a single transformation function to all the iterable elements and return an iterator&lt;/td&gt;
&lt;td&gt;A quick function you can just use and throw away without a name or sort&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Just like any concepts, with regular practice these Python features will become second nature if you keep at it as familiarizing yourself with them will ensure you adhere strictly to the DRY principles &lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>beginners</category>
      <category>developer</category>
    </item>
    <item>
      <title>Devin: A Tool, Not a Substitute for Your Job</title>
      <dc:creator>Osahenru</dc:creator>
      <pubDate>Mon, 18 Mar 2024 11:28:58 +0000</pubDate>
      <link>https://forem.com/osahenru/devin-a-tool-not-a-substitute-for-your-job-46ib</link>
      <guid>https://forem.com/osahenru/devin-a-tool-not-a-substitute-for-your-job-46ib</guid>
      <description>&lt;p&gt;In the past couple of weeks, there's been a lot of talk about AI replacing software engineers as speculated from known figures. While I find these statements laughable, it's also important to address these concerns here just as I did via email to a thriving community of aspiring Python developers who are worried about the future. Since this platform remains a haven for aspiring tech enthusiasts, I believe it's also important to drop my 2 cents here.&lt;/p&gt;

&lt;p&gt;While a lot of work and resources are being put into programs that ensure the tech industry is more inclusive in offering more accessible pathways to becoming a software engineers, I find it distasteful that the marketing campaign strategy of an emerging company is in the dismissal of an entire industry, goes to tell a lot about the company. Well, in plain and simple text AI is in no way replacing software engineers anytime, AI tools like Devin are nothing but tools, the choice to use it or not to rely solely on several decisions.&lt;/p&gt;

&lt;p&gt;AI is still arguably a decade away from having anything revolutionary, folks like Jensen Huang who hasn’t written a single line of code in recent years sometimes use these buzzwords to either attract more investments or maybe truly some actually do lack the understanding of how these tools operate, anyone who has built anything substantial knows that feeding an AI tool like Devin with vital information about your application is a call for disaster.&lt;/p&gt;

&lt;p&gt;While I think Devin is a fantastic tool and if built correctly will impact the way software engineers work, I find their marketing mantra quite sh!tty, Devin like every other software tool is to optimize the performance of developers just like Xcode or Pycharm, Copilot...; I can choose to build an app using notepad ++ (a dumb idea tho 😂 ) instead of VS code, the emphasis is that these are just merely tools which developers can familiarize with when you have solidified an understanding on the fundamentals of your desired tech stack.&lt;/p&gt;

&lt;p&gt;A simple search about Devin reveals two important things: One, Devin is built on GPT4, If you frequently use these tools you would have noticed that even the best of them hallucinate, these companies just show the working demos when in reality it’s a war dealing with these hallucinations from these tools. Two, Isn’t it quite ironic that Devin is in their recruitment for the positions of software engineer which is laughable, I mean if you’ve built a tool to replace software engineers why are there still openings for those job roles?&lt;/p&gt;

&lt;p&gt;Lastly, while I think AI tools are the new cool and here to stay and not to replace the job of a software engineer, if there’s going to be any replacement it'll be the boring and mundane things of being a software engineer and not your job, again learn the very fundamental and basics of your tech stack and then proceed to learning these tools, block out all the noise and focus on building your career.&lt;/p&gt;

&lt;p&gt;SO to everyone building something worthwhile making humanity better through inclusivity.  And to every aspiring tech enthusiast, keep learning and building! ❤️&lt;/p&gt;

&lt;p&gt;Photo credit: &lt;a href="https://www.freepik.com/free-photo/ai-background-business-technology-digital-transformation_17850432.htm#fromView=search&amp;amp;page=1&amp;amp;position=39&amp;amp;uuid=6f9e6f8b-47d1-444a-a132-556db7eac427"&gt;rawpixel on freepik&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwaredevelopment</category>
      <category>beginners</category>
      <category>devin</category>
    </item>
    <item>
      <title>Building a basic Python todo app and pushing on GitHub</title>
      <dc:creator>Osahenru</dc:creator>
      <pubDate>Sun, 21 May 2023 21:54:35 +0000</pubDate>
      <link>https://forem.com/osahenru/building-a-basic-python-todo-app-and-pushing-on-github-5ged</link>
      <guid>https://forem.com/osahenru/building-a-basic-python-todo-app-and-pushing-on-github-5ged</guid>
      <description>&lt;p&gt;Hello guys, &lt;br&gt;
to conclude what we have been on for a couple of days now, here is a blog post I have prepared for you that you can always reflect back on, you can check out the whole code on github &lt;a href="https://github.com/TimOsahenru/pyclub-mentees-projects"&gt;[here]&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In this article we will:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Complete the todo app we started by adding a users class to it and then push to GitHub&lt;/li&gt;
&lt;li&gt;Go through basic git commands&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;here is a snippet of the previous code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Task():
    def __init__(self, title):
        self.name = title
        self.description = ""
        self.is_completed = False
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to extend the code to accommodate a user, we will create a User class and initialize with a name for each instance of the User object&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User():
    def __init__(self, name):
        self.name = name
        self.tasks = []
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we want to also add more functionality to the app by allowing a user to be able to &lt;strong&gt;add tasks&lt;/strong&gt;, &lt;strong&gt;delete tasks&lt;/strong&gt; and &lt;strong&gt;view task&lt;/strong&gt;&lt;br&gt;
so an updated &lt;strong&gt;main.py&lt;/strong&gt; file will look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User():
    def __init__(self, name):
        self.name = name
        self.tasks = []


    def add_task(self, task):
        self.tasks.append(task)


    def delete_task(self, task):
        if task in self.tasks:
            self.tasks.remove(task)


    def display_tasks(self):
        print("Username: ", self.name)
        for task in self.tasks:
            print("Title", task.title)
            print("Description", task.description)
            print("Completed", task.is_completed)
            print()



class Task():
    def __init__(self, title):
        self.name = title
        self.description = ""
        self.is_completed = False
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  PUSHING TO GITHUB
&lt;/h2&gt;

&lt;p&gt;It is expected the project has been cloned with &lt;code&gt;git clone&lt;/code&gt; and is resting on your local machine, here is a link to repo to clone &lt;a href="https://github.com/TimOsahenru/pyclub-mentees-projects"&gt;from&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;after copying the contents of &lt;strong&gt;main.py&lt;/strong&gt; with &lt;code&gt;git status&lt;/code&gt; you can see the current status of your repo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YolZnGEG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yj5e5u7nbib51ttw6ggh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YolZnGEG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yj5e5u7nbib51ttw6ggh.png" alt="screenshot of the terminal" width="732" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we add out implementation to git with the command &lt;code&gt;git add main.py&lt;/code&gt; and to commit the changes you have made run the command&lt;br&gt;
&lt;code&gt;git commit -m “created a user model for each task object”&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;run git status again to be sure you changes were added and committed&lt;/p&gt;

&lt;p&gt;and to finally push to github we run the command&lt;br&gt;
&lt;code&gt;git push&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;viola an updated project should be sitting on the repo from which you cloned from.&lt;/p&gt;

&lt;p&gt;for questions and comments you can contact me via mail &lt;a href="mailto:timosahenru@gmail.com"&gt;timosahenru@gmail.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
    </item>
    <item>
      <title>Building globally with Django internalization</title>
      <dc:creator>Osahenru</dc:creator>
      <pubDate>Fri, 03 Mar 2023 17:24:29 +0000</pubDate>
      <link>https://forem.com/osahenru/building-globally-with-django-internalization-471a</link>
      <guid>https://forem.com/osahenru/building-globally-with-django-internalization-471a</guid>
      <description>&lt;p&gt;The world as a global village is comprising of different languages, ethnicity and gender. In this article I will introduce to you the concept of internalization with Django.&lt;/p&gt;

&lt;p&gt;You will understand how an application can be built to reach a global audience using Django’s internalization by either.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Manually changing the language code of your application&lt;/li&gt;
&lt;li&gt;Or using an extension to change language sessions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;For getting the best out of this article, a basic understanding of Django is needed;

&lt;ul&gt;
&lt;li&gt;How to setup a Django project and run an application&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Have &lt;strong&gt;gettext&lt;/strong&gt; running on your machine, for linux run this command
&lt;code&gt;sudo apt-get install gettext&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Install language switch, a firefox extension &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/languageswitch/"&gt;language switcher&lt;/a&gt;.
If you have checked these prerequisites then lets proceed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So I have successfully created a project &lt;strong&gt;config&lt;/strong&gt; and an application &lt;strong&gt;app&lt;/strong&gt; as shown in this file tree.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2qC1MK7K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k2fn0tzn9rgw7rh19phd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2qC1MK7K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k2fn0tzn9rgw7rh19phd.png" alt="Image description" width="289" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;to run and compile your message create a folder called locale inside your &lt;strong&gt;app&lt;/strong&gt; directory with &lt;code&gt;mkdir app/locale&lt;/code&gt; the &lt;code&gt;locale/&lt;/code&gt; directory we just created is where the magic happens, where our messages will be compiled.&lt;/p&gt;

&lt;p&gt;If you have &lt;code&gt;gettext&lt;/code&gt; installed on your machine then import it with the following line of code &lt;code&gt;from django.utils.translation import gettext as _&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We can translate text either from the backend view (views.py) or from the frontend templating engine.&lt;/p&gt;

&lt;h4&gt;
  
  
  Translating from views
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3VRYR0wA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fvut5bkehmxl01o1bv5r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3VRYR0wA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fvut5bkehmxl01o1bv5r.png" alt="Image description" width="458" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Translating from your template
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x3BcNjvw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c93da4f2h13mxu0agogi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x3BcNjvw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c93da4f2h13mxu0agogi.png" alt="Image description" width="679" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We proceed further to generate a translated text file with &lt;code&gt;django-admin makemessages -l es&lt;/code&gt; if you open the locale folder, you'll see a &lt;code&gt;django.po&lt;/code&gt; file where the translation process takes place.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4nTgjR0c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t2q5dp6fkd5ga9yeg72w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4nTgjR0c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t2q5dp6fkd5ga9yeg72w.png" alt="Image description" width="282" height="145"&gt;&lt;/a&gt;&lt;br&gt;
Make the following changes by changing your default language code in your &lt;code&gt;settings.py&lt;/code&gt; file from English to Spanish &lt;code&gt;LANGUAGE_CODE = 'es'&lt;/code&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--crKRRZrM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pkhv3fv9wejnyqd3b87g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--crKRRZrM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pkhv3fv9wejnyqd3b87g.png" alt="Image description" width="282" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and when you're done run application with the compile command&lt;br&gt;
&lt;code&gt;django-admin compilemessages&lt;/code&gt; load your tags from the template with &lt;code&gt;{% load i18n %}&lt;/code&gt;  as shown above.&lt;/p&gt;

&lt;h4&gt;
  
  
  To manually change the language from your &lt;code&gt;settings.py&lt;/code&gt; file
&lt;/h4&gt;

&lt;p&gt;all you need to do is just change the language code from English to Spanish as previously shown above.&lt;/p&gt;

&lt;h4&gt;
  
  
  To change the language using an extension
&lt;/h4&gt;

&lt;p&gt;If you have installed the language switcher extension, then include this line of code to  your middleware  in your &lt;code&gt;settings.py&lt;/code&gt; &lt;code&gt;django.middleware.locale.LocalMiddleware&lt;/code&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NoPrQwzf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jzqox36modf2wrsx9y3z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NoPrQwzf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jzqox36modf2wrsx9y3z.png" alt="Image description" width="593" height="198"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please ensure to include this file after the &lt;strong&gt;sesion middleware&lt;/strong&gt; precisely after&lt;br&gt;
the &lt;strong&gt;common middleware&lt;/strong&gt; as shown above.&lt;/p&gt;

&lt;p&gt;If that is done, then toggle between language on your browser&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tDGEzp8n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhcz01w6tg1ig806w0dv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tDGEzp8n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhcz01w6tg1ig806w0dv.png" alt="Image description" width="211" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope this was helpful, please give a follow if you found this helpful.&lt;/p&gt;

</description>
      <category>djanog</category>
      <category>python</category>
      <category>community</category>
    </item>
    <item>
      <title>Beginner to hired in 12 months (a step-by-step approach on getting hired as a Dev)</title>
      <dc:creator>Osahenru</dc:creator>
      <pubDate>Thu, 26 Jan 2023 22:20:55 +0000</pubDate>
      <link>https://forem.com/osahenru/beginner-to-hired-in-12-months-a-step-by-step-approach-on-getting-hired-as-a-dev-2ffa</link>
      <guid>https://forem.com/osahenru/beginner-to-hired-in-12-months-a-step-by-step-approach-on-getting-hired-as-a-dev-2ffa</guid>
      <description>&lt;p&gt;In the late quarter of 2022, I received a mail asking for my application for an internship position(paid in dollars), I wasn’t surprised because I expected it, I felt it even took too long 😄 😄, this sense of confidence came because I knew I had put in the work needed, so why some might interpret my fate as mere luck, although it is true, luck did contribute to my success, but also, I was prepared and in search of her(luck) by being deliberate about what I wanted and also by taken some actionable steps.&lt;/p&gt;

&lt;p&gt;These deliberate steps to getting you your first job are what I will be sharing in this guide, I’m not promising you a similar outcome as mine, cos I believe yours might even be a better position as to how I started, but what I am assuring you of is, if you put in these steps to good use, you’ll see the results within a year, and this brings me to my first tip;&lt;/p&gt;

&lt;p&gt;NB: Although the Python language and the Django framework are used as a case study for this article, the lessons learned and tips shared here can also be used across any other language, framework or technology concepts as a beginner.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NB: Although the Python language and the Django framework is used as a case study for this article, the lessons learnt and tips shared here can also be used across any other language, framework or technology concepts as a beginner&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip1: Being intentional:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Intentional living is the art of making your own choices before other choices make you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I had to be intentional about what part of tech I wanted to start building a career in and for me it was as a backend engineer, a backend engineer is usually bothered about the flow of logic of an application.&lt;/p&gt;

&lt;p&gt;I had researched some of the best languages to learn as of 2021 as a backend engineer and Python was top on that list, it still is as of 2023 according to &lt;a href="https://www.hostinger.com/tutorials/best-programming-languages-to-learn"&gt;hostinger&lt;/a&gt;, it takes about 6 months or more to understand the concepts of Python.&lt;/p&gt;

&lt;p&gt;When I was sure I understood what it’ll cost me to be proficient in Python as a backend engineer, I committed myself to it, which brings me to our next tip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip2: Commit yourself:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unless commitment is made, there are only promises and hopes; but no plans. ― Peter F. Drucker.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Commitment is the decision to show up every day regardless of the amount of work put in, commitment is in the little steps you take each day towards your plan or goal, commitment is in knowing that consistency beats intensity any day or time, not focusing too much on the result of perfection but on the process of the journey.&lt;/p&gt;

&lt;p&gt;So, on November 8, 2022, I decided to be committed to my intention about becoming a software engineer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/_osahenru/status/1457799159600193542?s=20&amp;amp;t=NdhiugcZd1TNTzbu8UPPLA"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LU7aeM8O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oj3cd7vx07a92ohi0nuv.png%2520align%3D%2522center%2522" alt="Twitter image" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You know, when the universe knows about your plan it finds a way it guides you unto completion, especially if you’re determined to see it through, the old book of wisdom says&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;...Write the vision And make it plain on tablets, That he may run who reads it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This was what I did by making that tweet, making a tweet wasn’t the last bus stop, I had to also put in the work needed.&lt;/p&gt;

&lt;p&gt;I signed up for a beginners course in &lt;a href="https://pll.harvard.edu/course/cs50-introduction-computer-science?delta=0"&gt;computer&lt;/a&gt; science I learned programming with scratch for a couple of weeks (say about 4 weeks) on their platform&lt;/p&gt;

&lt;p&gt;While many are meant to believe that tech is hard, the lack of a proper road map can even make it harder.&lt;/p&gt;

&lt;p&gt;I proceeded to c++ still under the same &lt;a href="https://pll.harvard.edu/course/cs50-introduction-computer-science?delta=0"&gt;curriculum(cs50)&lt;/a&gt;, not sure how long this took but to follow a plan let's say two months because by February of the following year(2022) I had already narrowed my learning to just Python.&lt;/p&gt;

&lt;p&gt;Once I understood the fundamentals of computer programming I narrowed my skill to learning Python with &lt;a href="https://www.youtube.com/watch?v=_uQrJ0TkZlc"&gt;Mosh Hamedani&lt;/a&gt;, as my first encounter with the programming language called Python, Mosh’s teaching style is top-notch and very beginners friendly.&lt;/p&gt;

&lt;p&gt;After understanding the core concepts of Python; variables, functions, classes, OOP, etc, I was still in search of a beginners guide to learning Python, which brings me to my next tips.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip4: Document your journey&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Accomplishments will prove to be a journey, not a destination - Dwight D. Eisenhower&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Documentation is the love language that you write to your future self, it is very important to document your journey as a software engineer, you will always be impressed by how much you have improved when you go back to visit your documentation.&lt;/p&gt;

&lt;p&gt;Documenting your tech journey helps you better understand the concepts you are learning and also gives you room to improve on your skill sets as it exposes you to a community of both expert engineers and learners who will benefit from your experience, I’m still shocked at the number of engagement I get on my &lt;a href="http://dev.to"&gt;dev.to&lt;/a&gt; interesting to see that people benefit from my sharing of my little wealth of knowledge.&lt;/p&gt;

&lt;p&gt;I use my &lt;a href="https://github.com/TimOsahenru"&gt;GitHub account&lt;/a&gt; not just as a version control system but also to document my projects, which is why I always take out time to write out a proper README file for all my projects(public or private), my &lt;a href="http://dev.to"&gt;dev.to&lt;/a&gt; account and &lt;a href="https://osahenru.hashnode.dev/"&gt;hashnode&lt;/a&gt; accounts are used to write on whatever concepts I'm learning.&lt;/p&gt;

&lt;p&gt;You don’t need to pay for a blog domain as a beginner; these resources are freely available for use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip5: Effectively belong to a community&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Alone, we can do so little; together, we can do so much – Helen Keller&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In May 2022, I searched for some Python handles to follow on Twitter and I stumbled on &lt;a href="https://twitter.com/PyGhana?t=Vtgu0UPxcsP9ep-CA03svA&amp;amp;s=09"&gt;PyGhana&lt;/a&gt;, coincidentally they made a retweet about the PyConGhana 22, so I gave a follow on Twitter to find out more about them when I was convinced about understanding the concept of a Py conference &lt;a href="https://twitter.com/PyconGhana?t=uoTtNZr6u3uPyKasUrfO2A&amp;amp;s=09"&gt;PyConGhana&lt;/a&gt;, I promised myself to give a talk at the conference, submitted my first ever CFP and thankfully it was approved.&lt;/p&gt;

&lt;p&gt;I understand not everyone enjoys socializing, scary but, somehow being a software developer will force you to socialize in ways that might not suit your personality, just see it as the prize you need to pay.&lt;/p&gt;

&lt;p&gt;The decision to give my first talk at a tech conference was very crucial to my journey in landing a job, I met recruiters foreign and local, and had a couple of sincere interactions with developers who were present at the event I could see the gap in knowledge from my end and it challenged me that I can be better and also in the same light I could also see how far I had come as a self-taught developer seeing how much people also benefited from my little knowledge shared.&lt;/p&gt;

&lt;p&gt;Well, if you’re reading this I sincerely urge you to become a member of a community regardless of your level of competence.&lt;/p&gt;

&lt;p&gt;When you pick a language, search out for the community close to you, the Python community, for example, is very broad and diverse, having branches in almost every continent, most countries and major cities and if there are none this is a call to create one.&lt;/p&gt;

&lt;p&gt;Being an active person in your community means you are contributing to the community from; financial contributions to resources and material, to contributing with your skills and expertise, no matter how small let your presence and impact be felt, and engage their social media handles by commenting and retweeting whenever a post is made.&lt;/p&gt;

&lt;p&gt;In the long run, when there’s a job opening, it is most times first circulated within the community before it is made public and sometimes it is easier for people to recommend you for a position when you’re an active member of a mutual community.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip6: Market yourself:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The price you will offer yourself to the world is how much they will buy you. ― Lailah Gifty Akita&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What makes a story compelling, is how it is being told, to be hired for a position you want to be able to tell a story with your journey on your Twitter, Github or Linkedin profile in a way that is captivating and shows an amazing personality.&lt;/p&gt;

&lt;p&gt;How you tell your story on these platforms is more important than your story itself, especially as one with no work experience, you should learn how to constantly share what you’re currently doing/learning, the challenges you faced and how you have overcome those challenges but, be careful not to make another boring writeup, add some personality while you market yourself.&lt;/p&gt;

&lt;p&gt;From your display picture to your bio, be very intentional about what you post from now on, see social media as a podium and Twitter(or any other platform) as the mic, what you say and HOW you say it will determine if people should listen to you.&lt;/p&gt;

&lt;p&gt;A story gives room for engagement, for example, two developers sharing their story on how they got a job can differ based on how they share their stories.&lt;/p&gt;

&lt;p&gt;Why this tip might not seem as portraying the importance of selling yourself as a software engineer, the message I want you to pick is to be very deliberate on how you market yourself by telling your story.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip7: Contribute to an open-source project&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your engagement with open is the surest referral to getting your first job.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An open source project is a project in which its source code has been made public and can be modified, the Django framework is a good example of an open source project, &lt;a href="https://github.com/TimOsahenru/OpenCiviWiki"&gt;my first open source&lt;/a&gt; project in 2022 exposed me to what a large code base looks like, as a developer it is one thing to read through your code and debug, and yet another to read and try to understand the code of others.&lt;/p&gt;

&lt;p&gt;Contributing to an open source project will strengthen your skill in whatever language you're learning as you will be able to see thinking pieces of what makes up the code base to which you are contributing.&lt;/p&gt;

&lt;p&gt;Also, another benefit of contributing to open source as a beginner is how it exposes you to the working wonders of a version control system.&lt;/p&gt;

&lt;p&gt;For how to get started with open source as a beginner, I prepared this &lt;a href="https://dev.to/osahenru/getting-started-with-your-first-open-source-project-5d6m"&gt;detailed guide&lt;/a&gt;, please check it out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip 8: Start applying&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The best time to plant a tree was 20 years ago. The second best time is now.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The biggest injustice you can do to yourself is to sit on the sidelines and wait for the perfect time to arrive, the right time for you to start doing what it is you want to do and create what it is you want to create is NOW!&lt;/p&gt;

&lt;p&gt;You don't have to be great to start, but you have to start to be great; you don’t need to become a great “developer” before you start applying, ironically you need to start applying to become a great developer in the long run.&lt;/p&gt;

&lt;p&gt;Polish your &lt;a href="https://www.linkedin.com/in/tim-osahenru-1a8a9b122/"&gt;Linkedin&lt;/a&gt; profile, and prepare your resume and a cover letter.&lt;/p&gt;

&lt;p&gt;You can start applying on &lt;a href="https://www.linkedin.com/jobs/"&gt;Linkedin&lt;/a&gt; jobs or any job portals, two of the surest positions for a beginner are an internship position or a junior position, and you can get these offers on Linkedin jobs depending on how you have tweaked your Linkedin page.&lt;/p&gt;

&lt;p&gt;Besides Linkedin, another platform where you can get jobs is the websites of the companies who are sponsoring some of these tech events, especially those who sponsor the language or framework you’re working with.&lt;/p&gt;

&lt;p&gt;So, as a Python/Django developer search for companies sponsoring any PyCon or DjangoCon event close to you or where you would love to work, visit the company's career pages on their website and apply to them, this process is way easier as you’re sure of some of the requirements for working for the company as they are sponsors of your choice language/framework.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip 9: Believe&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To accomplish great things, we must not only act, but also dream; not only plan, but also believe. - Anatole France&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Belief is a practical instrument you need to shape reality, now you have done all the tips earlier highlighted, you must believe it can happen for you and watch it happen.&lt;/p&gt;

&lt;p&gt;Move without fear or doubt believing it will work for you, provided you are willing to put in the work as highlighted in this article then believe it will most certainly work for you.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What the mind of man can conceive and believe, the mind of man can achieve - Napoleon Hill.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thankfully November 2022 I got my offer that birthed this article&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MfzzpeE7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6j5zak6k728z4nejcrbf.jpg%2520align%3D%2522left%2522" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MfzzpeE7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6j5zak6k728z4nejcrbf.jpg%2520align%3D%2522left%2522" alt="Image description" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I will end with a very beautiful quote from four-time grand slam singles champion, Naomi Osaka&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I don't think there's a perfectly correct path to take in life but I always felt that if you move forward with good intentions you'll find your way eventually.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I know it might seem draining on some days but please don’t be discouraged, it worked for me and also it can work for you.&lt;/p&gt;

&lt;p&gt;May the odds forever be in your favor.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to deploy a sphinx styled documentation</title>
      <dc:creator>Osahenru</dc:creator>
      <pubDate>Wed, 21 Dec 2022 12:48:28 +0000</pubDate>
      <link>https://forem.com/osahenru/how-to-deploy-a-sphinx-styled-documentation-4fdc</link>
      <guid>https://forem.com/osahenru/how-to-deploy-a-sphinx-styled-documentation-4fdc</guid>
      <description>&lt;p&gt;In this tutorial guide I will show you how to create a documentation for your project using the Sphinx style.&lt;/p&gt;

&lt;p&gt;Sphinx is a documentation generator written and used by the Python community and environments.&lt;/p&gt;

&lt;p&gt;Sphinx uses the &lt;strong&gt;reStrcuturedText&lt;/strong&gt; markup language by default and can also be tweaked to using &lt;strong&gt;markdown.md&lt;/strong&gt; as a third party package&lt;/p&gt;

&lt;p&gt;In this tutorial guide I’ll show you how to&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install sphinx on your project&lt;/li&gt;
&lt;li&gt;Setup Sphinx on your project&lt;/li&gt;
&lt;li&gt;Run Sphinx with some basic commands&lt;/li&gt;
&lt;li&gt;Install a different theme&lt;/li&gt;
&lt;li&gt;Deploy your documentation on &lt;a href="https://readthedocs.org/"&gt;reathedocs&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;First create a project on GitHub and clone it on your local machine or alternatively clone this blank &lt;a href="https://github.com/TimOsahenru/demo-sphinx-tutorial"&gt;project&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd&lt;/code&gt; into the directory of the repo you just cloned with &lt;br&gt;
&lt;code&gt;cd demo-sphinx-tutorial&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a virtual environment with&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;python3 -m venv venv&lt;/code&gt; if you’re on a linux server like I am or &lt;code&gt;python -m venv venv&lt;/code&gt; on a windows&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Activate your virtual environment with&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;source venv/bin/activate&lt;/code&gt; on a linux server &lt;code&gt;venv\Scripts\activate&lt;/code&gt; on a windows and open your project in your choice editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install Sphinx&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;pip install sphinx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup Sphinx&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;sphinx-quickstart docs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now what this is going to do is to run you through a bunch of questions, whenever you want to accept the default value just go ahead and &lt;code&gt;press enter&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Separate source and build directories (y/n) [n]: 
press y

The project name will occur in several places in the built documentation.
&amp;gt; Project name: demo-sphinx-tutorial
&amp;gt; Author name(s): Tim Osahenru
&amp;gt; Project release []: 1.0

&amp;gt; Project language [en]: 
press enter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run Sphinx&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd&lt;/code&gt; into source folder and make a directory called images  with &lt;code&gt;mkdir&lt;/code&gt; images where our images will be stored&lt;br&gt;
your file tree should look like this&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y2DhZUea--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/252trvwk6ndx76yfaglm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y2DhZUea--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/252trvwk6ndx76yfaglm.png" alt="Project file tree" width="197" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;open the &lt;code&gt;index.rst&lt;/code&gt; file this is where the magic takes place, you want to leave this section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I2Gyx2Ld--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8t1qqn1adkrwjzca4qh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I2Gyx2Ld--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8t1qqn1adkrwjzca4qh.png" alt="Toctree content" width="364" height="214"&gt;&lt;/a&gt;&lt;br&gt;
the toctree tells  sphinx the hierarchical order of your file, you can either push to the bottom of the page of leave it ontop &lt;strong&gt;DO NOT DELETE THIS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;next I’m going to copy and paste some dummy data into the &lt;code&gt;index.rst&lt;/code&gt; file&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SBCgOHuS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lwt1b63elrj39y75hh3k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SBCgOHuS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lwt1b63elrj39y75hh3k.png" alt="Dummy data in index.rst" width="699" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;now we build our documentation with this commands &lt;code&gt;sphinx-build -b html docs/source/ docs/build/html&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To view your built work open the build folder and load &lt;code&gt;index.html&lt;/code&gt; on your browser&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NB:
whenever you make a change inside the index.rst
file always make sure you build with 
sphinx-build -b html docs/source/ docs/build/html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Install theme&lt;/strong&gt;&lt;br&gt;
To pick a theme &lt;a href="https://sphinx-themes.org/"&gt;visit&lt;/a&gt; for this tutorial this &lt;a href="https://sphinx-themes.org/sample-sites/sphinx-rtd-theme/"&gt;theme&lt;/a&gt; was used&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;install the theme with&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;pip install sphinx-rtd-theme&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;locate this session in your &lt;code&gt;conf.py&lt;/code&gt; file and change &lt;code&gt;html_theme = 'alabaster'&lt;/code&gt; to &lt;code&gt;html_theme = 'sphinx_rtd_theme'&lt;/code&gt; and build again with &lt;code&gt;sphinx-build -b html docs/source/ docs/build/html&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  PART II
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Deploying to readthedocs&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;cd&lt;/code&gt; into you &lt;code&gt;docs&lt;/code&gt; folder and create a requirements file with &lt;code&gt;pip freeze &amp;gt; requirements.txt&lt;/code&gt; for readthedocs to know the dependencies used on this project&lt;/p&gt;

&lt;p&gt;Perform these git commands to push to GitHub where we will be deploying our project from&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git status
git add .
Git commit -m ‘first commit’
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create an account on &lt;a href="https://readthedocs.org/"&gt;readthedocs&lt;/a&gt; navigate to your profile image button and click the drop down menu &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NHroOEc7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a09wfb07efo4114ty4xd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NHroOEc7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a09wfb07efo4114ty4xd.png" alt="drop-down menu" width="211" height="202"&gt;&lt;/a&gt; click on &lt;code&gt;My Projects&lt;/code&gt; &amp;gt; &lt;code&gt;Import a Project&lt;/code&gt; select the project you wish to deploy and click on &lt;code&gt;Build Project&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once the build is successful you should get an indication and have a project like &lt;a href="https://osahenru-sphinx-tutorial.readthedocs.io/en/latest/"&gt;this&lt;/a&gt;.&lt;br&gt;
Congratulations!&lt;/p&gt;

</description>
      <category>technicalwriting</category>
      <category>documentation</category>
      <category>sphinx</category>
      <category>readthedocs</category>
    </item>
    <item>
      <title>Getting started with your first open source project</title>
      <dc:creator>Osahenru</dc:creator>
      <pubDate>Wed, 26 Oct 2022 18:56:21 +0000</pubDate>
      <link>https://forem.com/osahenru/getting-started-with-your-first-open-source-project-5d6m</link>
      <guid>https://forem.com/osahenru/getting-started-with-your-first-open-source-project-5d6m</guid>
      <description>&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;p&gt;I expect the reader of this article to have an existing GitHub account and is fairly familiar with GitHub and a few command like &lt;code&gt;git status&lt;/code&gt;, &lt;code&gt;git commit&lt;/code&gt;, &lt;code&gt;git add .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;However if you're not familiar with GitHub checkout this &lt;a href="https://docs.github.com/en/get-started/quickstart" rel="noopener noreferrer"&gt;beginners guide&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is open source
&lt;/h2&gt;

&lt;p&gt;I can relate to how the term ‘open source’ sounds like a term used only by those who are perceived as the top dog by other developers well, I fairly understand, open source just merely means project which are open for contributions and this is intentionally done by the creators of these projects.&lt;/p&gt;

&lt;p&gt;As a contributor you can contribute to an existing issue or create one yourself (although as a beginner I recommend you stick with the former of contributing to an existing issue), for the purpose of this article an issue can be said to be a list of improvements required for the project to function optimally either as fixing a bug or requesting additional functions to the project&lt;/p&gt;

&lt;p&gt;A good issue is one which has a tag, has a simple title, has been opened for at least a year (as a beginner you don’t want to contribute to an issue that has been left unattended to with zero to few interactions).&lt;/p&gt;

&lt;p&gt;So, now, you have spotted an issue you feel comfortable contributing to, you need to notify the maintainer of that project by sending a comment to assign the issue to you.&lt;/p&gt;

&lt;p&gt;Please give time before you get feedback from the maintainer as most times the feedback might not be instance as most have other project they are maintaining or have a busy work life.&lt;/p&gt;

&lt;p&gt;If you’re not sure of where to find open source project easily, sign up to &lt;a href="https://hacktoberfest.com/" rel="noopener noreferrer"&gt;hacktoberfest&lt;/a&gt; and browse through their list of sites where you can find good open source projects, alternatively below are some sites you can easily check out too&lt;br&gt;
&lt;a href="https://up-for-grabs.net" rel="noopener noreferrer"&gt;Ups for grabs&lt;/a&gt;&lt;br&gt;
&lt;a href="https://goodfirstissues.com/" rel="noopener noreferrer"&gt;Good first issues&lt;/a&gt;&lt;br&gt;
&lt;a href="https://goodfirstissue.dev/" rel="noopener noreferrer"&gt;Good first issues dotdev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While you’re waiting for a response from the maintainer you can familiarize yourself with the project's code base for this sole reason is why I strongly encourage beginners to contribute to open source projects because you’ll be exposed to the code base of the project where you can familiarize yourself on the industry way of writing clean and maintainable codes and the exposure to collaboration too is very rewarding when you’re in search of a job.&lt;/p&gt;
&lt;h2&gt;
  
  
  Forking a project
&lt;/h2&gt;

&lt;p&gt;Once an issue has been assigned to you, next, you need to &lt;strong&gt;FORK&lt;/strong&gt; the repository of that project to your GitHub repository&lt;/p&gt;

&lt;p&gt;To fork a repo according to &lt;a href="https://www.freecodecamp.org/news/how-to-make-your-first-pull-request-on-github-3/" rel="noopener noreferrer"&gt;Thanoshan MV&lt;/a&gt; means &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When we love someone’s repository and would like to have it in our GitHub account, we fork it so that we can work with it separately. When we fork a repository, we get an instance of that entire repository with its whole history. After forking, we can do whatever we want to do without affecting the original version&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;unrelated but I find this definition really hilarious more so that the pronunciation of the word has other meanings, makes me wonder what the engineers at GitHub were thinking about while coming up with their naming conventions… 😂😂😂&lt;/p&gt;

&lt;p&gt;You might fork a project to propose changes to the &lt;br&gt;
upstream(original repository).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F0078mxlluchyosrhnl6q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F0078mxlluchyosrhnl6q.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select an owner(which in most case is you) scroll down and &lt;strong&gt;CLICK&lt;/strong&gt; &lt;code&gt;create fork&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Cloning a forked repo
&lt;/h2&gt;

&lt;p&gt;So you have successfully forked the project you want to work on but you need to clone it to make it available on your local machine so you can work on it, to do this navigate to your newly forked project which usually has this naming convention &lt;code&gt;[YourName/Name-of-forked-project]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Above the list of files &lt;strong&gt;CLICK&lt;/strong&gt; &lt;code&gt;code&lt;/code&gt; copy the URL  using HTTPS&lt;/p&gt;

&lt;p&gt;Now to clone this project to your machine open your terminal, change directory to where you want your project cloned and type &lt;code&gt;git clone&lt;/code&gt; followed by the URL you just copied and press &lt;strong&gt;ENTER&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Syncing your forked project with the original repo
&lt;/h2&gt;

&lt;p&gt;In an open source project you’ll always have different contributors working on different issues so to keep with the latest commit or changes we need to sync our forked project with the upstream.&lt;/p&gt;

&lt;p&gt;On your GitHub account navigate to the repo of the original project where you forked from.&lt;/p&gt;

&lt;p&gt;Above the list of files &lt;strong&gt;CLICK&lt;/strong&gt; &lt;code&gt;code&lt;/code&gt;just close to the Add file icon, copy the URL  using HTTPS.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd&lt;/code&gt; into the directory of the earlier forked clone type &lt;code&gt;git remote -v&lt;/code&gt; press &lt;strong&gt;ENTER&lt;/strong&gt; to see the remote name of the repo you just forked.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;your output should look something like this&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;origin  https://github.com/YourName/OriginalNameofYourFork.git (fetch)
origin  https://github.com/YourName/OriginalNameofYourFork.git (push)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type &lt;code&gt;git remote add upstream&lt;/code&gt; and then paste the URL you last copied followed by &lt;strong&gt;ENTER&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;your command should look something like this&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git remote add upstream https://github.com/YourName/OriginalOwner/OriginalNameofProject.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to be sure of the upstream of your fork, type &lt;code&gt;git remote -v&lt;/code&gt; again, you should see the URL for your fork as origin and the URL for the original repo as upstream&lt;/p&gt;

&lt;p&gt;&lt;em&gt;your output should look something like this&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;origin  https://github.com/YourName/NameofYourFork.git (fetch)
origin  https://github.com/YourName/NameofYourFork.git (push)
upstream  https://github.com/YourName/RepoNameOriginalofOriginalOwner.git (fetch)
upstream  https://github.com/YourName/RepoNameofOriginalOwner.git (push)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, your forked project will be synced with the upstream repo, it is good practice to always sync your fork with the upstream repository after cloning to your local machine.&lt;/p&gt;

&lt;p&gt;So, you have successfully spotted an issue in an open source project, the issue has been assigned to you, you’ve forked and cloned it to your local machine also, but before you start working on it, it is very important to create a branch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a branch
&lt;/h2&gt;

&lt;p&gt;Few git branch commands and their functions to have at your finger tips.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git branch&lt;/code&gt;&lt;br&gt;
current branch you’re working on&lt;br&gt;
&lt;code&gt;git branch -r&lt;/code&gt;&lt;br&gt;
all remote branches&lt;br&gt;
&lt;code&gt;git branch -a&lt;/code&gt;&lt;br&gt;
all remote branches local and remote&lt;br&gt;
&lt;code&gt;git checkout&lt;/code&gt;&lt;br&gt;
shows a record of all the commit in your current branch.&lt;/p&gt;

&lt;p&gt;Now, we create a new branch using the git checkout command.&lt;br&gt;
&lt;code&gt;git checkout -b [branch name]&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Making changes
&lt;/h2&gt;

&lt;p&gt;After you’ve successfully resolved the issue, git takes a record of every change made in that repo to see the changes that has been made we use the &lt;code&gt;git status&lt;/code&gt;command on a windows environment these changes will be highlighted in red.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commit changes
&lt;/h2&gt;

&lt;p&gt;Once you're sure that the changes made solve the issues raised, next, you need to add these changes to the repo with &lt;code&gt;git add .&lt;/code&gt; and commit these changes with &lt;br&gt;
&lt;code&gt;git commit -m ‘a commit message summarizing what you did’&lt;/code&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  Pushing changes
&lt;/h2&gt;

&lt;p&gt;Now we need to make our changes visible remotely by pushing these changes using &lt;code&gt;git push&lt;/code&gt; but before we do that we need to be sure of the name of the remote, some repo use &lt;code&gt;main&lt;/code&gt; others &lt;code&gt;master&lt;/code&gt; or &lt;code&gt;origin&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;by using the command &lt;code&gt;git remote&lt;/code&gt; you’ll see the remote name used for the project&lt;br&gt;
&lt;a href="https://media.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%2Fzk1uc9ot2ftsha474vcd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fzk1uc9ot2ftsha474vcd.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;once you’ve successfully identified the remote name, you can now successfully push with &lt;code&gt;git push [repo name] [branch name]&lt;/code&gt; for the case of this article, the remote name used in demoing this article is &lt;code&gt;origin&lt;/code&gt; and the branch name is &lt;code&gt;register-models&lt;/code&gt; so your git command will be something like &lt;br&gt;
&lt;code&gt;git push origin register-models&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Making a pull request
&lt;/h2&gt;

&lt;p&gt;Once you’ve successfully pushed your code, the next and final step will be to make a pull request, that is alerting the maintainer of the project that a change has been made and a merge is needed&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;CLICK *&lt;/em&gt; on the compare &amp;amp; request icon&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fuehexxriufuv9iopqwh9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fuehexxriufuv9iopqwh9.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fill up the fields with the necessary information and click &lt;code&gt;create pull request&lt;/code&gt;, Congratulations you have successfully made your first contribution to an open source project, if your PR is accepted you’ll receive a mail.&lt;/p&gt;

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

&lt;p&gt;It is okay to google the solutions to an issue no one will penalize you for doing that, what is important to contributing to an open source project is solving the issue, and also very important to note is that your PR might not be merge do not take it personal or feel less skilled to keep contributing to more projects, it might be that your approach to tackling the issue isn’t a maintainable or clean approach, you can always seek help from contributors on how best to contribute if your PR isn’t merged. &lt;/p&gt;

</description>
      <category>opensource</category>
      <category>github</category>
      <category>git</category>
      <category>hacktoberfest</category>
    </item>
    <item>
      <title>Using Django's hitcount for unregistered users in your application</title>
      <dc:creator>Osahenru</dc:creator>
      <pubDate>Mon, 12 Sep 2022 15:17:18 +0000</pubDate>
      <link>https://forem.com/osahenru/using-djangos-hitcount-for-unregistered-users-in-your-application-2o36</link>
      <guid>https://forem.com/osahenru/using-djangos-hitcount-for-unregistered-users-in-your-application-2o36</guid>
      <description>&lt;p&gt;Django &lt;code&gt;hitcount&lt;/code&gt; is a python library that allows you track the number of hits/views on a particular objects by detecting the IP address of each click to prevent unreal views this ensures views aren't counted twice.&lt;/p&gt;

&lt;p&gt;This library was built using the Django’s class based views which provides a wrapper for Django’s generic &lt;code&gt;DetailView&lt;/code&gt; and allows you to process the Hit as the view is loaded.&lt;/p&gt;

&lt;p&gt;To begin with this library you must have Python and Django running on your system, next we install the &lt;code&gt;django-hitcount&lt;/code&gt; using &lt;code&gt;pip install django-hitcount&lt;/code&gt;, after installation we add the hitcount library to our installed applications in &lt;code&gt;settings.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fvjp2jqxk4urucg3tt57f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fvjp2jqxk4urucg3tt57f.png" alt="settings file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we modify our &lt;code&gt;models.py&lt;/code&gt; file by importing the following line of code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from hitcount.models import HitCountMixin, HitCount
from django.contrib.contenttypes.fields import GenericRelation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;this library was built using Django's class based views so for beginners who might have already began using function based view in their application should have no worry as you can use both function based views and a class based view in one application view.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So, now lets move to our &lt;code&gt;views.py&lt;/code&gt; and tweak it a little, but before we do that, we need to import our hitcount into our &lt;code&gt;views.py&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from hitcount.views import HitCountDetailView
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.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%2Ftrpc5xjwiximtqjcqu9i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ftrpc5xjwiximtqjcqu9i.png" alt="Detail views"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;HitCountDetailView&lt;/code&gt; can be used to do the business-logic of counting the hits by setting &lt;code&gt;count_hit=True&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Almost there, now we move to our HTML template and load our hitcount tags, just right above your html DOCTYPE load the hitcount tags&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{% load hitcount_tags %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we add styling to our application with this line of code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;span class="ion-ios-eye"&amp;gt;&amp;lt;/span&amp;gt; {% get_hit_count for project %} views
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;VOILA!!! You've successfully integrated Django's hitcount to your application&lt;/p&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
