<?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: Alireza Shabani</title>
    <description>The latest articles on Forem by Alireza Shabani (@revisto).</description>
    <link>https://forem.com/revisto</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%2F367132%2Fb9edd43d-448e-4590-a7af-8dcfe9531369.jpg</url>
      <title>Forem: Alireza Shabani</title>
      <link>https://forem.com/revisto</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/revisto"/>
    <language>en</language>
    <item>
      <title>Why GNOME’s Translation Platform Is Called "Damned Lies"</title>
      <dc:creator>Alireza Shabani</dc:creator>
      <pubDate>Wed, 11 Jun 2025 13:39:01 +0000</pubDate>
      <link>https://forem.com/revisto/why-gnomes-translation-platform-is-called-damned-lies-4nj5</link>
      <guid>https://forem.com/revisto/why-gnomes-translation-platform-is-called-damned-lies-4nj5</guid>
      <description>&lt;p&gt;&lt;em&gt;Damned Lies&lt;/em&gt; is the name of &lt;a href="https://l10n.gnome.org/" rel="noopener noreferrer"&gt;GNOME’s web application for managing localization (l10n)&lt;/a&gt; across its projects. But why is it named like this?&lt;/p&gt;

&lt;h3&gt;
  
  
  Damned Lies about GNOME
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5nnz1v4x134hdds8mxfj.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%2F5nnz1v4x134hdds8mxfj.png" alt="Screenshot of Gnome Damned Lies from Google search with the title: Damned Lies about GNOME" width="762" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the &lt;a href="https://l10n.gnome.org/about/" rel="noopener noreferrer"&gt;About page of GNOME’s localization site&lt;/a&gt;, the only explanation given for the name &lt;em&gt;Damned Lies&lt;/em&gt; is a link to a Wikipedia article called "&lt;a href="https://en.wikipedia.org/wiki/Lies,_damned_lies,_and_statistics" rel="noopener noreferrer"&gt;Lies, damned lies, and statistics&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;"Damned Lies" comes from the saying &lt;strong&gt;"Lies, damned lies, and statistics"&lt;/strong&gt; which is a 19th-century phrase used to describe the persuasive power of &lt;a href="https://en.wikipedia.org/wiki/Statistics" rel="noopener noreferrer"&gt;statistics&lt;/a&gt; to bolster weak arguments, As described on &lt;a href="https://en.wikipedia.org/wiki/Lies,_damned_lies,_and_statistics" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;. One of its earliest known uses appeared in an 1891 letter to the &lt;em&gt;National Observer&lt;/em&gt;, which categorized lies into three types:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Sir, —It has been wittily remarked that there are three kinds of falsehood: &lt;strong&gt;the first is a 'fib,' the second is a downright lie, and the third and most aggravated is statistics.&lt;/strong&gt; It is on statistics and on the absence of statistics that the advocate of national pensions relies ..."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To find out more, I asked in GNOME’s &lt;a href="https://matrix.to/#/#i18n:gnome.org" rel="noopener noreferrer"&gt;i18n Matrix room&lt;/a&gt;, and &lt;a href="https://alexandrefranke.com/" rel="noopener noreferrer"&gt;Alexandre Franke&lt;/a&gt; helped a lot, he said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Stats are indeed lies, in many ways.&lt;/p&gt;

&lt;p&gt;Like if GNOME 48 gets 100% translated in your language on Damned Lies, it doesn’t mean the version of GNOME 48 you have installed on your system is 100% translated, because the former is a real time stat for the branch and the latter is a snapshot (tarball) at a specific time.&lt;/p&gt;

&lt;p&gt;So 48.1 gets released while the translation is at 99%, and then the translators complete the work, but you won’t get the missing translations until 48.2 gets released.&lt;/p&gt;

&lt;p&gt;Works the other way around: the translation is at 100% at the time of the release, but then there’s a freeze exception and the stats go 99% while the released version is at 100%.&lt;/p&gt;

&lt;p&gt;Or you are looking at an old version of GNOME for which there won’t be any new release, which wasn’t fully translated by the time of the latest release, but then a translator decided that they wanted to see 100% because the incomplete translation was not looking as nice as they’d like, and you end up with Damned Lies telling you that version of GNOME was fully translated when it never was and never will be.&lt;/p&gt;

&lt;p&gt;All that to say that translators need to learn to work smart, at the right time, on the right modules, and not focus on the stats.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So there you have it: &lt;em&gt;Damned Lies&lt;/em&gt; is a name that reminds us that numbers and statistics can be misleading even on GNOME's I10n Web application.&lt;/p&gt;

</description>
      <category>gnome</category>
      <category>i18n</category>
      <category>i10n</category>
      <category>localisation</category>
    </item>
    <item>
      <title>Journey to GNOME Circle: Community, App Ideas, and Getting Started</title>
      <dc:creator>Alireza Shabani</dc:creator>
      <pubDate>Sun, 13 Apr 2025 17:58:14 +0000</pubDate>
      <link>https://forem.com/revisto/journey-to-gnome-circle-community-app-ideas-and-getting-started-4k2</link>
      <guid>https://forem.com/revisto/journey-to-gnome-circle-community-app-ideas-and-getting-started-4k2</guid>
      <description>&lt;p&gt;&lt;strong&gt;Hello, chat! I'm Revisto, and I want to share my journey to GNOME Circle and how I became a GNOME Foundation member.&lt;/strong&gt; I'll discuss my experiences and the development path of &lt;a href="https://apps.gnome.org/DrumMachine/" rel="noopener noreferrer"&gt;Drum Machine&lt;/a&gt;. This is the first part of the "Journey to GNOME Circle" series.&lt;/p&gt;

&lt;p&gt;I love Free and Open Source communities, especially GNOME and GNOME Circle. I find contributing to open source communities far more rewarding than contributing to projects maintained by a single individual. If you find the right community, there are many experienced, generous, and &lt;strong&gt;humble&lt;/strong&gt; people you can learn from. You can explore various projects maintained by the community, experience consistent quality, be surrounded by an amazing community, and even enjoy some perks!&lt;/p&gt;

&lt;p&gt;I found the GNOME community to be one of the best in the FOSS industry. Why?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are &lt;strong&gt;lots&lt;/strong&gt; of apps and projects you can contribute to, from GTK to Terminal to GNOME Shell itself.&lt;/li&gt;
&lt;li&gt;It has a welcoming community full of experienced people.&lt;/li&gt;
&lt;li&gt;GNOME looks fantastic, thanks to &lt;a href="https://jimmac.eu/" rel="noopener noreferrer"&gt;Jakub Steiner&lt;/a&gt;. The GNOME design is stunning. It has great &lt;a href="https://developer.gnome.org/hig/" rel="noopener noreferrer"&gt;documentation and handbooks&lt;/a&gt; for beginners, making it super beginner-friendly.&lt;/li&gt;
&lt;li&gt;Different ways to &lt;a href="https://welcome.gnome.org/#where-to-contribute" rel="noopener noreferrer"&gt;contribute&lt;/a&gt;, you can help with documentation, programming, design, translation, create new apps, and more.&lt;/li&gt;
&lt;li&gt;Membership perks.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h3&gt;
  
  
  GNOME Foundation Membership?!
&lt;/h3&gt;

&lt;p&gt;The GNOME Foundation offers membership to its active contributors. Whether you're an active translator, help with documentation, enhance GNOME's appearance, or generally &lt;strong&gt;MAKE GNOME BETTER&lt;/strong&gt;, you can apply for membership. Additionally, if your app gets into GNOME Circle, you qualify for membership.&lt;/p&gt;

&lt;h4&gt;
  
  
  What are the perks?
&lt;/h4&gt;

&lt;p&gt;Here are some of the perks in summary. You can find complete information &lt;a href="https://handbook.gnome.org/foundation/membership-benefits.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Email Alias (&lt;code&gt;nickname@gnome.org&lt;/code&gt;):&lt;/strong&gt; gnome.org email addresses are provided for all Foundation members. This address is an alias which can be used as a relay for sending and receiving emails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your own blog at &lt;code&gt;blogs.gnome.org&lt;/code&gt;:&lt;/strong&gt; Foundation members are eligible to host their blog on &lt;a href="https://blogs.gnome.org/" rel="noopener noreferrer"&gt;blogs.gnome.org&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Listing on &lt;a href="https://planet.gnome.org/" rel="noopener noreferrer"&gt;Planet GNOME&lt;/a&gt;:&lt;/strong&gt; Foundation members who have blogs can have them included on &lt;a href="https://planet.gnome.org/" rel="noopener noreferrer"&gt;planet.gnome.org&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Travel sponsorship for events:&lt;/strong&gt; Foundation members are eligible for travel sponsorship to GNOME conferences and events.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nextcloud (&lt;code&gt;cloud.gnome.org&lt;/code&gt;):&lt;/strong&gt; GNOME hosts a Nextcloud instance at &lt;a href="https://cloud.gnome.org/" rel="noopener noreferrer"&gt;cloud.gnome.org&lt;/a&gt;. This provides a range of services, including file hosting, calendaring, and contact management.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are useful and beneficial for your reputation and branding. I use my email alias for GNOME-related work at &lt;code&gt;AlirezaSh@gnome.org&lt;/code&gt;, have my blog at &lt;code&gt;alirezash.gnome.org&lt;/code&gt;, and sync my &lt;a href="https://obsidian.md/" rel="noopener noreferrer"&gt;Obsidian&lt;/a&gt; notes with Nextcloud on GNOME infrastructure. Unfortunately, I couldn't get my travel sponsorship as a speaker at events because I'm from Iran, and due to OFAC regulations which is so unfair.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  What's GNOME Circle?
&lt;/h2&gt;

&lt;p&gt;I've always had the idea of creating beautiful, useful apps for Linux. There were many apps I needed but couldn't find a good version for Linux, and some apps I wished had better GUIs.&lt;/p&gt;

&lt;p&gt;GNOME Circle is a collection of applications and libraries that extend the GNOME ecosystem.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"GNOME Circle champions the great software that is available for the GNOME platform. Not only do we showcase the best apps and libraries for GNOME, but we also support independent developers who are using GNOME technologies."&lt;br&gt;&lt;br&gt;
— &lt;a href="https://circle.gnome.org/" rel="noopener noreferrer"&gt;GNOME Circle&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In GNOME, we have core apps like Terminal, GNOME Shell, Text Editor, etc., and we have GNOME Circle apps. These are apps that independent developers have created using GNOME technologies (GTK and Libadwaita), following the &lt;a href="https://developer.gnome.org/hig/" rel="noopener noreferrer"&gt;GNOME Human Interface Guidelines&lt;/a&gt;, and meeting the app criteria. Once accepted, these apps become part of GNOME Circle.&lt;/p&gt;

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

&lt;p&gt;GNOME Circle has lots of really cool apps that you should check out. It includes &lt;a href="https://apps.gnome.org/Curtail/" rel="noopener noreferrer"&gt;Curtail&lt;/a&gt;, an application to compress your images; &lt;a href="https://apps.gnome.org/EarTag/" rel="noopener noreferrer"&gt;Ear Tag&lt;/a&gt;, an audio file tags editor; &lt;a href="https://apps.gnome.org/Chessclock/" rel="noopener noreferrer"&gt;Chess Clock&lt;/a&gt;, which provides time control for over-the-board chess games.&lt;/p&gt;

&lt;p&gt;GNOME Circle is really cool, full of beautiful apps and creative developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  App Idea?
&lt;/h2&gt;

&lt;p&gt;If GNOME Circle sounds interesting to you, or you like GNOME Foundation membership perks, or you appreciate the open-source community, or you want to create an app that fulfills your own needs, you should have an idea. What app do you want to develop? I believe we all have ideas. Personally, I really want a good VPN client for Linux (because of censorship in Iran, it's vital), or a good-looking, user-friendly download manager, among other apps.&lt;/p&gt;

&lt;p&gt;I highly recommend you check out other applications on &lt;a href="https://circle.gnome.org/" rel="noopener noreferrer"&gt;GNOME Circle&lt;/a&gt;. There are lots of creative projects there that can inspire you. Some of my favorites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://apps.gnome.org/Wike/" rel="noopener noreferrer"&gt;Wike&lt;/a&gt;: Search and read Wikipedia articles.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://apps.gnome.org/Komikku/" rel="noopener noreferrer"&gt;Komikku&lt;/a&gt;: Discover and read manga &amp;amp; comics.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://apps.gnome.org/Fretboard/" rel="noopener noreferrer"&gt;Fretboard&lt;/a&gt;: Look up guitar chords.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://apps.gnome.org/EarTag/" rel="noopener noreferrer"&gt;Ear Tag&lt;/a&gt;: Edit audio file tags.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think it's a good idea to check if your idea has already been implemented. You can check the apps in GNOME Circle and also check the apps that are being reviewed by the GNOME Circle Committee to become part of the circle soon: &lt;a href="https://gitlab.gnome.org/Teams/Circle/-/issues" rel="noopener noreferrer"&gt;GNOME Circle Issues&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Although you can submit a new app with a similar idea to an existing app, I believe it would be better to bring new ideas to the circle or even contribute to existing circle apps that align with your idea.&lt;/p&gt;

&lt;p&gt;On a side note, I really enjoy reading other people's app requests and discussions &lt;a href="https://gitlab.gnome.org/Teams/Circle/-/issues/?sort=updated_desc&amp;amp;state=closed&amp;amp;label_name%5B%5D=Rejected&amp;amp;first_page_size=20" rel="noopener noreferrer"&gt;here&lt;/a&gt;. I've been reading them to familiarize myself with the application acceptance process and understand the possible reasons an app might get rejected.&lt;/p&gt;

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

&lt;p&gt;Since I'm a music producer (listen to my work &lt;a href="https://www.youtube.com/@therevisto" rel="noopener noreferrer"&gt;here&lt;/a&gt;), I really like the idea of making music production in Linux easier. I had music-related ideas for my first app in the Circle: synthesizers, drum machines, and eventually a DAW (Digital Audio Workstation). I started simple and went with Drum Machine. I looked at different online drum machines such as &lt;a href="https://drumbit.app/" rel="noopener noreferrer"&gt;drumbit.app&lt;/a&gt; and &lt;a href="https://www.onemotion.com/drum-machine/" rel="noopener noreferrer"&gt;onemotion.com/drum-machine&lt;/a&gt;, then I started thinking about how I wanted my own drum machine to look like and I drew this (I know it doesn't look good; I'm bad at drawing &amp;gt;-&amp;lt;).&lt;/p&gt;

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

&lt;p&gt;Now I had motivation, an idea, and wanted to actually start making.&lt;br&gt;
I'll detail the development process and evolution of Drum Machine in the next post, so stay tuned!&lt;/p&gt;

&lt;p&gt;You can find me here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mastodon&lt;/strong&gt;: &lt;a href="https://mastodon.social/@revisto" rel="noopener noreferrer"&gt;@revisto@mastodon.social&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blog&lt;/strong&gt;: &lt;a href="https://blogs.gnome.org/AlirezaSh" rel="noopener noreferrer"&gt;blogs.gnome.org/AlirezaSh&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/revisto" rel="noopener noreferrer"&gt;github.com/revisto&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a href="https://linkedin.com/in/revisto" rel="noopener noreferrer"&gt;linkedin.com/in/revisto&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Youtube&lt;/strong&gt;: &lt;a href="https://youtube.com/@theRevisto" rel="noopener noreferrer"&gt;youtube.com/@theRevisto&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Telegram (Personal)&lt;/strong&gt;: &lt;a href="https://t.me/revisto" rel="noopener noreferrer"&gt;t.me/revisto&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Telegram (Tech Channel in Farsi)&lt;/strong&gt;: &lt;a href="https://t.me/revistoTech" rel="noopener noreferrer"&gt;t.me/revistoTech&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>gnome</category>
      <category>opensource</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>SOLID Design Principles: Learn the Dependency Inversion Principle</title>
      <dc:creator>Alireza Shabani</dc:creator>
      <pubDate>Mon, 04 Dec 2023 09:31:49 +0000</pubDate>
      <link>https://forem.com/revisto/solid-design-principles-learn-the-dependency-inversion-principle-5hdm</link>
      <guid>https://forem.com/revisto/solid-design-principles-learn-the-dependency-inversion-principle-5hdm</guid>
      <description>&lt;p&gt;👋 Hey there, fellow software enthusiasts!&lt;/p&gt;

&lt;p&gt;I'm Revisto, a passionate software engineer 👨‍💻, and I want to dive into the exciting world of SOLID principles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SOLID&lt;/strong&gt; is a set of rules and principles that help us create maintainable, reusable, and flexible software designs. These principles guide us in building software that can adapt and grow as our projects evolve. Today, we will focus on the third principle of SOLID.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S: &lt;a href="https://dev.to/revisto/solid-design-principles-learn-the-single-responsibility-principle-3cb1"&gt;Single Responsibility Principle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;O: &lt;a href="https://dev.to/revisto/solid-design-principles-learn-the-open-closed-principle-2o8o"&gt;Open-Closed Principle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;L: &lt;a href="https://dev.to/revisto/solid-design-principles-learn-the-liskov-substitution-principle-2em9"&gt;Liskov Substitution Principle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;I: &lt;a href="https://dev.to/revisto/solid-design-principles-learn-the-interface-segregation-principle-j8c"&gt;Interface Segregation Principle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;D: Dependency Inversion Principle&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Dependency Inversion Principle (DIP):
&lt;/h2&gt;

&lt;p&gt;✨ Now, let's shine a light on the Dependency Inversion Principle (DIP). This principle focuses on managing dependencies between classes, aiming to create software systems that are flexible, maintainable, and extensible.&lt;/p&gt;

&lt;p&gt;💡 The core idea of the DIP can be summarized as &lt;strong&gt;"depend on abstractions, not on concretions."&lt;/strong&gt; In other words, classes should rely on interfaces or abstract classes rather than concrete implementations. By doing so, we invert the traditional dependency flow.&lt;/p&gt;

&lt;p&gt;Robert C. Martin, one of the proponents of SOLID principles, defines the Dependency Inversion Principle in two parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High-level modules should not depend on low-level modules. Both should depend on abstractions.&lt;/strong&gt; This means that the modules at a higher level of abstraction should not rely on the lower-level details. Instead, they should depend on abstract interfaces or classes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Abstractions should not depend on details. Details should depend on abstractions.&lt;/strong&gt; This emphasizes that the abstract interface or class should not be influenced by the specific implementation details. It should provide a contract that the concrete implementations adhere to.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📔 Common Example:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Understanding the Scenario:&lt;/strong&gt;&lt;br&gt;
Imagine we have a Logger class that is responsible for writing log messages to a file. We also have a Calculator class that performs arithmetic operations and uses the Logger class to log information about those operations.&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;Logger&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;log&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;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;log.txt&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;a&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&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="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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Logger&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;add&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;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&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;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&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;Added &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; and &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, result = &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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;❌ In the original implementation, the Calculator class directly creates an instance of the Logger class within its constructor. This creates a strong dependency between the two classes, making it difficult to modify or replace the Logger implementation in the future.&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;LoggerInterface&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;log&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;message&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;Logger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LoggerInterface&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;log&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;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;log.txt&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;a&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&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="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;logger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;LoggerInterface&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;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&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;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&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;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&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;Added &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; and &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, result = &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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To adhere to the Dependency Inversion Principle, we can introduce an interface, LoggerInterface, which defines the log method. The Logger class then implements this interface, ensuring it adheres to the contract defined by the interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr1pk30glhu5dzmj9nnx0.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%2Fr1pk30glhu5dzmj9nnx0.png" alt="Image description" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By adhering to the Dependency Inversion Principle, we achieve loose coupling between classes, making our software more flexible and easier to maintain. It also enhances code reusability and allows for more straightforward testing and future modifications.&lt;/p&gt;

&lt;p&gt;🚀 Stay tuned for more articles where we'll explore other exciting programming topics and delve into the exciting world of software engineering.&lt;/p&gt;

&lt;p&gt;Thanks for reading. Feel free to comment your thoughts😊. Hope this post was helpful. You can hit me up on &lt;a href="https://www.linkedin.com/in/revisto/" rel="noopener noreferrer"&gt;Linked In&lt;/a&gt; and &lt;a href="https://www.github.com/revisto/" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>python</category>
      <category>solidprinciples</category>
      <category>cleancode</category>
      <category>programming</category>
    </item>
    <item>
      <title>SOLID Design Principles: Learn the Interface-Segregation Principle</title>
      <dc:creator>Alireza Shabani</dc:creator>
      <pubDate>Mon, 27 Nov 2023 15:16:09 +0000</pubDate>
      <link>https://forem.com/revisto/solid-design-principles-learn-the-interface-segregation-principle-j8c</link>
      <guid>https://forem.com/revisto/solid-design-principles-learn-the-interface-segregation-principle-j8c</guid>
      <description>&lt;p&gt;👋 Hey there, fellow software enthusiasts!&lt;/p&gt;

&lt;p&gt;I'm Revisto, a passionate software engineer 👨‍💻, and I want to dive into the exciting world of SOLID principles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SOLID&lt;/strong&gt; is a set of rules and principles that help us create maintainable, reusable, and flexible software designs. These principles guide us in building software that can adapt and grow as our projects evolve. Today, we will focus on the third principle of SOLID.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S: &lt;a href="https://dev.to/revisto/solid-design-principles-learn-the-single-responsibility-principle-3cb1"&gt;Single Responsibility Principle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;O: &lt;a href="https://dev.to/revisto/solid-design-principles-learn-the-open-closed-principle-2o8o"&gt;Open-Closed Principle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;L: &lt;a href="https://dev.to/revisto/solid-design-principles-learn-the-liskov-substitution-principle-2em9"&gt;Liskov Substitution Principle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;I: Interface Segregation Principle&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;D: Dependency Inversion Principle&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding the Interface Segregation Principle:
&lt;/h2&gt;

&lt;p&gt;✨ In object-oriented programming, &lt;strong&gt;an interface represents a set of behaviors that an object can perform&lt;/strong&gt;. It serves as a contract that defines the methods an object must have. The purpose of interfaces is to &lt;strong&gt;enable clients to interact with objects through a common interface&lt;/strong&gt;, without needing to know the intricate details of how those methods are implemented.&lt;/p&gt;

&lt;p&gt;The core idea behind the Interface Segregation Principle can be summarized as follows: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Clients should not be forced to depend upon methods that they do not use. Interfaces belong to clients, not to hierarchies🤩.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In Python, abstract classes are commonly used as interfaces, aligning with the philosophy of duck typing. The duck typing principle states that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If it walks like a duck and quacks like a duck, it must be a duck🦆.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;📔 Common Example:&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;Printer&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;print&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;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&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;fax&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;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&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;scan&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;document&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;OldPrinter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Printer&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;print&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;document&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;Printing &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; in black and white...&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;fax&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;document&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;NotImplementedError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Fax functionality not supported&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;scan&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;document&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;NotImplementedError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Scan functionality not supported&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 ISP suggests that interfaces should be designed in a way that clients are not forced to depend on methods they don't need.&lt;/p&gt;

&lt;p&gt;❌ The OldPrinter class implements the print method to print documents in black and white. However, it raises &lt;strong&gt;NotImplementedError&lt;/strong&gt; for the &lt;strong&gt;fax&lt;/strong&gt; and &lt;strong&gt;scan&lt;/strong&gt; methods, indicating that these functionalities are not supported by this particular printer.&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;Printer&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;print&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;document&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;Fax&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;fax&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;document&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;Scanner&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;scan&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;document&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;OldPrinter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Printer&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;print&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;document&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;Printing &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; in black and white...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewPrinter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Printer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Scanner&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;print&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;document&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;Printing &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; in color...&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;fax&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;document&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;Faxing &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="si"&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;def&lt;/span&gt; &lt;span class="nf"&gt;scan&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;document&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;Scanning &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="si"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More examples at &lt;a href="https://github.com/Revisto/SOLID/tree/master/interface-segregation" rel="noopener noreferrer"&gt;my GitHub&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;By adhering to the Interface Segregation Principle, we can craft &lt;strong&gt;interfaces that are meaningful and concise, tailored specifically to the needs of clients.&lt;/strong&gt; This principle empowers us to create software systems that are adaptable, maintainable, and efficient. Remember, SOLID principles serve as valuable guidelines for building software that stands the test of time.&lt;/p&gt;

&lt;p&gt;🚀 Stay tuned for more articles where we'll explore the other SOLID principles and delve into the exciting world of software engineering.&lt;/p&gt;

&lt;p&gt;Thanks for reading. Feel free to comment your thoughts😊. Hope this post was helpful. You can hit me up on &lt;a href="https://www.linkedin.com/in/revisto/" rel="noopener noreferrer"&gt;Linked In&lt;/a&gt; and &lt;a href="https://www.github.com/revisto/" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>python</category>
      <category>cleancode</category>
      <category>programming</category>
      <category>solidprinciples</category>
    </item>
    <item>
      <title>SOLID Design Principles: Learn the Liskov-Substitution Principle</title>
      <dc:creator>Alireza Shabani</dc:creator>
      <pubDate>Sat, 25 Nov 2023 11:01:54 +0000</pubDate>
      <link>https://forem.com/revisto/solid-design-principles-learn-the-liskov-substitution-principle-2em9</link>
      <guid>https://forem.com/revisto/solid-design-principles-learn-the-liskov-substitution-principle-2em9</guid>
      <description>&lt;p&gt;👋 Hey there, fellow software enthusiasts!&lt;/p&gt;

&lt;p&gt;I'm Revisto, a passionate software engineer 👨‍💻, and I want to dive into the exciting world of SOLID principles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SOLID&lt;/strong&gt; is a set of rules and principles that help us create maintainable, reusable, and flexible software designs. These principles guide us in building software that can adapt and grow as our projects evolve. Today, we will focus on the third principle of SOLID.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S: &lt;a href="https://dev.to/revisto/solid-design-principles-learn-the-single-responsibility-principle-3cb1"&gt;Single Responsibility Principle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;O: &lt;a href="https://dev.to/revisto/solid-design-principles-learn-the-open-closed-principle-2o8o"&gt;Open-Closed Principle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;L: Liskov Substitution Principle&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;I: Interface Segregation Principle&lt;/li&gt;
&lt;li&gt;D: Dependency Inversion Principle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✨ The Liskov Substitution Principle is named after the brilliant &lt;a href="https://en.wikipedia.org/wiki/Barbara_Liskov" rel="noopener noreferrer"&gt;Barbara Liskov&lt;/a&gt;. Simply put, it states that &lt;strong&gt;a child class should be able to replace its parent class seamlessly&lt;/strong&gt;. This means that objects of the child class should be able to substitute objects of the parent class without causing any issues or breaking the application's integrity.&lt;/p&gt;

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

&lt;p&gt;In other words, any piece of code that interacts with objects of a specific type should continue to function correctly even when those objects are replaced with instances of a subtype.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Subtypes must be substitutable for their base types.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(A subtype can be either a class extending another class or a class implementing an interface.)&lt;/p&gt;

&lt;p&gt;Let's consider an example to better grasp the concept. Imagine we have a Teleportation class in our codebase. According to the Liskov Substitution Principle, we should be able to substitute the Teleportation class with any of its subclasses, such as Car, Bike or Cycle, without causing any issues or breaking the existing code🤩.&lt;/p&gt;

&lt;h2&gt;
  
  
  📔 Example
&lt;/h2&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;TransporationDevice&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;start_engine&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;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TransporationDevice&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;start_engine&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;Starting Engine...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bike&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TransporationDevice&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;start_engine&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;Starting Engine...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cycle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TransporationDevice&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;start_engine&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="c1"&gt;# Bicyles don't have engines
&lt;/span&gt;          &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;NotImplementedError&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;❌ The &lt;code&gt;TransporationDevice&lt;/code&gt; class doesn't adhere to the Liskov Substitution Principle. When we think about scaling, there is a problem because not all the devices have engines and then there would be a problem.&lt;br&gt;
When that happens, the TransporationDevice class needs to change to support all devices and use other classes for all teleportation kinds. Thus, the current design violates OCP.&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;TransporationDevice&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;start&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;Steps to start the vehicle&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;TransporationDeviceWithoutEngine&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="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TransporationDeviceWithEngine&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;start_engine&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;Process to start the engine&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;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TransporationDeviceWithEngine&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;start&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="c1"&gt;# First start engine
&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;start_engine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="c1"&gt;# Do other steps here
&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start_engine&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;Starting Engine...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bike&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TransporationDeviceWithEngine&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;start&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="c1"&gt;# First start the engine
&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;start_engine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="c1"&gt;# Do other steps here
&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start_engine&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;Starting Engine...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cycle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TransporationDeviceWithoutEngine&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;start&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;Hit pedals....&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;More examples at &lt;a href="https://github.com/Revisto/SOLID/tree/master/liskov-substitution" rel="noopener noreferrer"&gt;my GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Applying LSP:
&lt;/h2&gt;

&lt;p&gt;By adhering to the Liskov Substitution Principle, we can ensure that our code remains &lt;strong&gt;flexible and robust&lt;/strong&gt;. It &lt;strong&gt;reduces the chances of introducing bugs or errors when extending our codebase&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;🚀 Stay tuned for more articles where we'll explore the other SOLID principles and delve into the exciting world of software engineering.&lt;/p&gt;

&lt;p&gt;Thanks for reading. Feel free to comment your thoughts😊. Hope this post was helpful. You can hit me up on &lt;a href="https://www.linkedin.com/in/revisto/" rel="noopener noreferrer"&gt;Linked In&lt;/a&gt; and &lt;a href="https://www.github.com/revisto/" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>python</category>
      <category>solidprinciples</category>
      <category>cleancode</category>
      <category>programming</category>
    </item>
    <item>
      <title>SOLID Design Principles: Learn the Open-Closed Principle</title>
      <dc:creator>Alireza Shabani</dc:creator>
      <pubDate>Sun, 19 Nov 2023 14:13:25 +0000</pubDate>
      <link>https://forem.com/revisto/solid-design-principles-learn-the-open-closed-principle-2o8o</link>
      <guid>https://forem.com/revisto/solid-design-principles-learn-the-open-closed-principle-2o8o</guid>
      <description>&lt;p&gt;👋 Hey there, fellow software enthusiasts! &lt;br&gt;
I'm Revisto, a passionate software engineer, and I want to dive into the exciting world of SOLID principles. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SOLID&lt;/strong&gt; is a set of rules and principles that can help us create maintainable, reusable, and flexible software designs. Essentially, it provides guidelines for building software that can help our projects grow easily.&lt;/p&gt;

&lt;p&gt;So, what does SOLID stand for? Let's break it down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S: &lt;a href="https://dev.to/revisto/solid-design-principles-learn-the-single-responsibility-principle-3cb1"&gt;Single Responsibility Principle&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;O: Open-Closed Principle&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;L: Liskov Substitution Principle&lt;/li&gt;
&lt;li&gt;I: Interface Segregation Principle&lt;/li&gt;
&lt;li&gt;D: Dependency Inversion Principle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9f32dnl5irxax39nd7q3.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%2F9f32dnl5irxax39nd7q3.png" alt="Image description" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✨ One of the fundamental principles of SOLID is the Open-Closed Principle (OCP). It states that &lt;strong&gt;a class, method, or function should be open for extension but closed for modification&lt;/strong&gt;. In other words, w*&lt;em&gt;e should be able to easily extend the functionality of a software component without having to modify its existing code.&lt;/em&gt;*&lt;/p&gt;

&lt;p&gt;So, what does it mean for a component to be open for extension? It means that we can add new features or behaviors to the component without modification. This can be achieved through techniques like &lt;strong&gt;inheritance&lt;/strong&gt;, where we can create new classes or functions that build upon the existing ones.&lt;/p&gt;

&lt;p&gt;By adhering to the Open-Closed Principle, we create software components that are &lt;strong&gt;flexible and adaptable🤩&lt;/strong&gt;. When new requirements or features arise, we can simply extend the existing codebase rather than modify it. This reduces the risk of introducing bugs and makes our software more maintainable in the long run.&lt;/p&gt;

&lt;p&gt;Let's take a look at a couple of examples to illustrate the Open-Closed Principle in action:&lt;/p&gt;
&lt;h2&gt;
  
  
  👨‍💻 Example: Inheritance
&lt;/h2&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;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;income&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deduction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# tax_amount variable is defined
&lt;/span&gt;    &lt;span class="c1"&gt;# in each calculation
&lt;/span&gt;    &lt;span class="n"&gt;tax_amount&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;taxable_income&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;income&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;deduction&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;India&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# calculation here
&lt;/span&gt;        &lt;span class="k"&gt;pass&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;US&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# calculation here
&lt;/span&gt;        &lt;span class="k"&gt;pass&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UK&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# calculation here
&lt;/span&gt;        &lt;span class="k"&gt;pass&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tax_amount&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;❌ The &lt;code&gt;calculate&lt;/code&gt; function doesn't adhere to the Open-Closed Principle. When we think about scaling and users from several countries start using the app, then there would be a problem.&lt;br&gt;
When that happens, the TaxCalculator class needs to change to support the new countries and their rules. Thus, the current design violates OCP.&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;CountryTaxCalculator&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_tax_amount&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;TaxCalculatorForUS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CountryTaxCalculator&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;total_income&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total_deduction&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;total_income&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total_income&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;total_deduction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total_deduction&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_tax_amount&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;taxable_income&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;total_income&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;total_deduction&lt;/span&gt;
        &lt;span class="c1"&gt;# calculation here 
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;taxable_income&lt;/span&gt; 


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TaxCalculatorForUK&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CountryTaxCalculator&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;total_income&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total_deduction&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;total_income&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total_income&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;total_deduction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total_deduction&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_tax_amount&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;taxable_income&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;total_income&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;total_deduction&lt;/span&gt;
        &lt;span class="c1"&gt;# calculation here 
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;taxable_income&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More examples at &lt;a href="https://github.com/Revisto/SOLID/tree/master/open-closed" rel="noopener noreferrer"&gt;my GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9n7mu7r9rnlj7bho62md.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%2F9n7mu7r9rnlj7bho62md.png" alt="Image description" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adhering to the single responsibility principle is crucial. Make sure that each class or module has a clear and distinct responsibility. If a class becomes responsible for multiple tasks, it's a sign that it should be broken down into smaller, more focused units.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open-Closed Principle VS Single-Responsibility Principle
&lt;/h2&gt;

&lt;p&gt;Here I quote from this &lt;a href="https://stackoverflow.com/questions/31018554/open-closed-vs-single-responsibility" rel="noopener noreferrer"&gt;post&lt;/a&gt; from &lt;a href="https://stackoverflow.com/users/4989498/sanderarts" rel="noopener noreferrer"&gt;sanderarts&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Single Responsibility Principle deals with the fact that if a class has multiple responsibilities, these responsibilities will be tightly coupled if they're in a single class. So if an interface or algorithm changes for one responsibility it will likely also affect the other responsibility, an undesired effect.&lt;br&gt;
In the Open/Closed Principle a class should be able to extend its behavior without the need to modify the class itself. The only need to modify the class should be because it has a bug/error in it, not because you would like to change or add functionality.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By embracing the Open-Closed Principle, we create software that is more flexible, maintainable, and extensible. We can easily add new features without modifying existing code, promoting code reuse and reducing the risk of introducing bugs. So, let's strive to keep our software open for extension but closed for modification!&lt;/p&gt;

&lt;p&gt;🚀 Stay tuned for more articles where we'll explore the other SOLID principles and delve into the exciting world of software engineering.&lt;/p&gt;

&lt;p&gt;Thanks for reading. Feel free to comment your thoughts😊. Hope this post was helpful. You can hit me up on &lt;a href="https://www.linkedin.com/in/revisto/" rel="noopener noreferrer"&gt;Linked In&lt;/a&gt; and &lt;a href="https://www.github.com/revisto/" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>solidprinciples</category>
      <category>python</category>
      <category>cleancode</category>
      <category>programming</category>
    </item>
    <item>
      <title>SOLID Design Principles: Learn the Single-Responsibility Principle</title>
      <dc:creator>Alireza Shabani</dc:creator>
      <pubDate>Sun, 19 Nov 2023 11:06:07 +0000</pubDate>
      <link>https://forem.com/revisto/solid-design-principles-learn-the-single-responsibility-principle-3cb1</link>
      <guid>https://forem.com/revisto/solid-design-principles-learn-the-single-responsibility-principle-3cb1</guid>
      <description>&lt;p&gt;👋 Hey there, fellow software enthusiasts! &lt;br&gt;
I'm Revisto, a passionate software engineer, and I want to dive into the exciting world of SOLID principles. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SOLID&lt;/strong&gt; is a set of rules and principles that can help us create maintainable, reusable, and flexible software designs. Essentially, it provides guidelines for building software that can help our projects grow easily.&lt;/p&gt;

&lt;p&gt;So, what does SOLID stand for? Let's break it down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S: Single Responsibility Principle&lt;/li&gt;
&lt;li&gt;O: Open-Closed Principle&lt;/li&gt;
&lt;li&gt;L: Liskov Substitution Principle&lt;/li&gt;
&lt;li&gt;I: Interface Segregation Principle&lt;/li&gt;
&lt;li&gt;D: Dependency Inversion Principle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffr7q0aeo4sbuo4g6a8zv.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%2Ffr7q0aeo4sbuo4g6a8zv.png" alt="Image description" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, we'll take a closer look at each of these principles, starting with the first one: the Single Responsibility Principle.&lt;/p&gt;

&lt;p&gt;The Single Responsibility Principle (SRP) states that every &lt;strong&gt;entity&lt;/strong&gt; in your software should have one and &lt;strong&gt;only one responsibility&lt;/strong&gt;. In simpler terms, it means that a class or function should have a single job to do.&lt;/p&gt;

&lt;p&gt;Robert C. Martin states:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A class should have only one reason to change.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think about it this way: if you have a class that's responsible for multiple tasks or purposes, you'll find yourself needing to modify the entire class whenever any of those tasks change. This can quickly become a nightmare, as it increases the risk of breaking other parts of the class or function unintentionally.&lt;/p&gt;

&lt;p&gt;To adhere to the Single Responsibility Principle, it's important to identify the distinct responsibilities within your software and &lt;strong&gt;separate them into different classes or functions&lt;/strong&gt;. By doing so, you ensure that each entity has a clear purpose and is focused on a specific task.&lt;/p&gt;

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

&lt;p&gt;Now, let's take a look at some Python examples to illustrate the Single Responsibility Principle in action:&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;Customer&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;email&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;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_email&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;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# sending an email to the customer
&lt;/span&gt;        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;place_order&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;order&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# placing an order
&lt;/span&gt;        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_invoice&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;invoice&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# generating an invoice
&lt;/span&gt;        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_feedback&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;feedback&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# add feedback
&lt;/span&gt;        &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a Customer class, it's responsible for sending emails to the customer, placing an order, generating invoices, and adding feedback. &lt;br&gt;
&lt;strong&gt;Are all these functions related to the Customer class?&lt;/strong&gt;&lt;br&gt;
❌ The short answer is NO.&lt;br&gt;
The customer class must be responsible for tasks and jobs only related to the customer. &lt;code&gt;send_email&lt;/code&gt; is another task related to the Notification system. &lt;code&gt;place_order&lt;/code&gt;  should be handled by another class related to orders etc.&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;Customer&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;email&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;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailService&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;send_email&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;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Sending an email to the customer
&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;OrderService&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;place_order&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;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Placing an order
&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;InvoiceService&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;generate_invoice&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;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;invoice&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Generating an invoice
&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;FeedbackService&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;add_feedback&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;customer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;feedback&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# add customer feedback
&lt;/span&gt;        &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More examples at &lt;br&gt;
&lt;a href="https://github.com/Revisto/SOLID/tree/master/single-responsibility" rel="noopener noreferrer"&gt;my GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens if we adhere to the single responsibility principle?
&lt;/h2&gt;

&lt;p&gt;By adhering to the Single Responsibility Principle, we can achieve code that is easier to understand, maintain, and test. Changes in one responsibility won't affect other unrelated parts of the codebase, reducing the risk of introducing bugs and improving overall code quality.&lt;/p&gt;

&lt;p&gt;In the next articles, we'll explore the other SOLID principles, so stay tuned for more exciting insights into building better software. &lt;/p&gt;

&lt;p&gt;Thanks for reading. Feel free to comment your thoughts😊. Hope this post was helpful. You can hit me up on &lt;a href="https://www.linkedin.com/in/revisto/" rel="noopener noreferrer"&gt;Linked In&lt;/a&gt; and &lt;a href="https://www.github.com/revisto/" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>solidprinciples</category>
      <category>cleancode</category>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>Generate All Possible Images!</title>
      <dc:creator>Alireza Shabani</dc:creator>
      <pubDate>Sun, 12 Jul 2020 00:19:02 +0000</pubDate>
      <link>https://forem.com/revisto/generate-all-possible-images-a-great-idea-f23</link>
      <guid>https://forem.com/revisto/generate-all-possible-images-a-great-idea-f23</guid>
      <description>&lt;p&gt;Let's discuss a &lt;strong&gt;HUGE&lt;/strong&gt; project but so useful one!&lt;br&gt;
The main idea is to generate all possible pictures with a specific resolution such as 1080×1920.&lt;/p&gt;


&lt;h1&gt;
  
  
  Why:
&lt;/h1&gt;

&lt;p&gt;Your first question might be, &lt;strong&gt;why the hell should this happen?&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cause it is literally EVERYTHING!!! Everything has happened, Everything that will happen, it can be a huge resource of inspiration, it can be leaked photos, it can be any media that will be released tomorrow, it can be exactly the &lt;strong&gt;future&lt;/strong&gt;. This is "Why".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we want to generate all 1080p pictures, it will be around&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt; 1080*1920*255*255*255 = 3.47892351×10¹³ &amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
, it is noticeable we are facing two different issues:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Time&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Size&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Therefore i though as the first step , i should use a lower resolution to generate , so i did some research:&lt;/p&gt;

&lt;p&gt;○ 352 x 240 (240p)&lt;br&gt;
○ 480 x 360 (360p)&lt;br&gt;
○ 858 x 480 (480p)&lt;br&gt;
○ 1280 x 720 (720p) &lt;br&gt;
○ 1920 x 1080 (1080p)&lt;br&gt;
○ 3860 x 2160 (2160p)&lt;/p&gt;

&lt;p&gt;The best choice is 240p. it will be something like:&lt;br&gt;
  &lt;/p&gt;

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

&lt;p&gt;Alright, Let's check a number of possibilities:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;240×352×256×256×256 = 1.417339208×10¹²&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;it is still a lot but with a huge difference in size.&lt;br&gt;
so I had another idea, limiting the range of red/green/blue:&lt;/p&gt;
&lt;h1&gt;
  
  
  2 Different Ways
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Option 1
&lt;/h2&gt;

&lt;p&gt;instead of having &lt;strong&gt;(256³)=16777216&lt;/strong&gt; options for each pixel , have &lt;strong&gt;((256/8)³)=32768&lt;/strong&gt; =&amp;gt; we saved &lt;strong&gt;16777216/32768=512&lt;/strong&gt; , in other words &lt;strong&gt;(240×352×32*32*32)=2768240640&lt;/strong&gt; possibilities&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How About analysing size and time:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;
  
  
  Size:
&lt;/h1&gt;

&lt;p&gt;Each .Jpg format 240p : 51KB (maximum)&lt;br&gt;
Each .Png format 240p : 254KB (maximum)&lt;br&gt;
It is clear we have to use .jpg format.&lt;br&gt;
All possible pictures size will be :&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(240×352×32*32*32)*51KB = 141180272640KB or 137871360MB or 134640GB or 131TB&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  Time:
&lt;/h1&gt;

&lt;p&gt;Each pixel (in a loop not random) takes 0.000000166&lt;/p&gt;

&lt;p&gt;Each 240p picture generate takes&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;(0.000000166*(352*240))+0.08 = 0.09402368&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Then for all Possible pictures, it takes&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;0.01*2768240640= 27682406.4 sec or 461373.4 min or 7689.5 hour or 320.3 days&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;










&lt;h2&gt;
  
  
  Option 2
&lt;/h2&gt;

&lt;p&gt;instead of having &lt;strong&gt;(256³)=16777216&lt;/strong&gt; options for each pixel , have &lt;strong&gt;((256/32)³)=512&lt;/strong&gt; =&amp;gt; we saved &lt;strong&gt;16777216/512=32768&lt;/strong&gt; , in other words &lt;strong&gt;(240×352×8*8*8)=43253760&lt;/strong&gt; possibilities&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How About analysing size and time:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Size:
&lt;/h1&gt;

&lt;p&gt;Each .Jpg format 240p : 51KB (maximum)&lt;br&gt;
Each .Png format 240p : 254KB (maximum)&lt;br&gt;
It is clear we have to use .jpg format.&lt;br&gt;
All possible pictures size will be :&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(240×352×8*8*8)*51KB = 2205941760KB or 2154240MB or 2103.7GB or 2.05TB&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  Time:
&lt;/h1&gt;

&lt;p&gt;Each pixel (in a loop not random) takes 0.000000166&lt;/p&gt;

&lt;p&gt;Each 240p picture generate takes&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;(0.000000166*(352*240))+0.08 = 0.09402368&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Then for all Possible pictures, it takes&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;0.01*43253760= 432537.6 sec or 7208.9 min or 120.1 hour or 5 days&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;










&lt;p&gt;Thanks for your attention, hope you like the idea and I really love to see your ideas to optimize!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Revisto/" rel="noopener noreferrer"&gt;Revisto&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>picture</category>
      <category>idea</category>
      <category>image</category>
    </item>
    <item>
      <title>Customize Your Ubuntu a bit !</title>
      <dc:creator>Alireza Shabani</dc:creator>
      <pubDate>Thu, 09 Jul 2020 20:34:14 +0000</pubDate>
      <link>https://forem.com/revisto/customize-your-ubuntu-5ga0</link>
      <guid>https://forem.com/revisto/customize-your-ubuntu-5ga0</guid>
      <description>&lt;p&gt;I have installed Ubuntu and I had been trying a lot and testing everything to make my system as beautiful as possible.&lt;br&gt;
so let's Customize (▀̿Ĺ̯▀̿ ̿)&lt;br&gt;
          &lt;/p&gt;



&lt;blockquote&gt;
&lt;h1&gt;
  
  
  Tweaks :
&lt;/h1&gt;

&lt;p&gt;The first step is to make sure that we have the universe repository enabled on our Ubuntu system:&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo add-apt-repository universe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now install Tweak Tool on your Ubuntu system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install gnome-tweak-tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h2&gt;
  
  
  SHELL   Config
&lt;/h2&gt;

&lt;p&gt;shell is locked by default in Ubuntu, Here is how to unlock it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install gnome-shell-extensions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart your system&lt;br&gt;
then,&lt;br&gt;
 &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%2F285j8et6q70qnuz5y5wy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F285j8et6q70qnuz5y5wy.jpg" width="800" height="446"&gt;&lt;/a&gt;&lt;br&gt;
Open GNOME Extensions app&lt;br&gt;
      &lt;br&gt;
  &lt;br&gt;
    &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%2F390hpt3xm3a7lmgw7g2f.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%2F390hpt3xm3a7lmgw7g2f.jpeg" width="750" height="419"&gt;&lt;/a&gt;&lt;br&gt;
Turn On 'User Themes'&lt;/p&gt;

&lt;p&gt;After These :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Then you need to log out and back into your session OR manually restart GNOME Shell (Alt + F2, type r, hit enter)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2F149366088.v2.pressablecdn.com%2Fwp-content%2Fuploads%2F2020%2F04%2Fselect-yaru-dark-theme-750x419.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%2F149366088.v2.pressablecdn.com%2Fwp-content%2Fuploads%2F2020%2F04%2Fselect-yaru-dark-theme-750x419.jpeg" width="750" height="419"&gt;&lt;/a&gt;&lt;br&gt;
Turn On 'User Themes'&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Select ‘Appearance’ in the sidebar&lt;br&gt;
Locate the Shell section&lt;br&gt;
Select THE SHELL THEME that you want from the menu&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;My Recommendation can make your system, A &lt;strong&gt;GodDamn&lt;/strong&gt; Awesome Ubuntu:&lt;br&gt;
  &lt;br&gt;
▷    Applications: Orchis&lt;br&gt;
▷    Cursor: Yaru&lt;br&gt;
▷    Icons: Numix-Circle&lt;br&gt;
▷    Shell: Orchis-Dark&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn1.bbcode0.com%2Fuploads%2F2020%2F7%2F9%2F3c76a303e032140edfce343db6c8786b-full.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%2Fcdn1.bbcode0.com%2Fuploads%2F2020%2F7%2F9%2F3c76a303e032140edfce343db6c8786b-full.png" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  How To Install Them?
&lt;/h2&gt;

&lt;p&gt;Orchis and Orchis-Dark:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/vinceliuice/Orchis-theme
cd Orchis-theme
./install.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Numix-Circle :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo add-apt-repository ppa:numix/ppa
sudo apt update
sudo apt install numix-icon-theme-circle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;blockquote&gt;
&lt;h1&gt;
  
  
  WallPaper (^̮^):
&lt;/h1&gt;
&lt;/blockquote&gt;

&lt;p&gt;I highly recommend you to find your &lt;strong&gt;Wallpaper&lt;/strong&gt; from &lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;br&gt;
Why:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Perfect Pictures&lt;br&gt;
High-Quality Pictures&lt;br&gt;
Over 1.5 million photos&lt;/p&gt;
&lt;/blockquote&gt;










&lt;p&gt;Thanks for your attention, hope you make the most beautiful Ubuntu and &lt;em&gt;eNJOY!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Revisto&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>linux</category>
      <category>tweaks</category>
      <category>customize</category>
    </item>
  </channel>
</rss>
