<?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>DEV Community: Dollar Dhingra</title>
    <description>The latest articles on DEV Community by Dollar Dhingra (@dollardhingra).</description>
    <link>https://dev.to/dollardhingra</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%2F593617%2Fc94ad14b-7a9b-4879-acfd-45de545af0f6.jpeg</url>
      <title>DEV Community: Dollar Dhingra</title>
      <link>https://dev.to/dollardhingra</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dollardhingra"/>
    <language>en</language>
    <item>
      <title>Benchmarking Python JSON serializers - json vs ujson vs orjson</title>
      <dc:creator>Dollar Dhingra</dc:creator>
      <pubDate>Wed, 25 May 2022 17:12:15 +0000</pubDate>
      <link>https://dev.to/dollardhingra/benchmarking-python-json-serializers-json-vs-ujson-vs-orjson-1o16</link>
      <guid>https://dev.to/dollardhingra/benchmarking-python-json-serializers-json-vs-ujson-vs-orjson-1o16</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you work with a large datasets in json inside your python code, then you might want to try using 3rd party libraries like &lt;a href="https://github.com/ultrajson/ultrajson"&gt;ujson&lt;/a&gt;and &lt;a href="https://github.com/ijl/orjson"&gt;orjson&lt;/a&gt; which are replacements to python’s json library.&lt;/p&gt;

&lt;p&gt;As per their documentation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ultrajson/ultrajson"&gt;ujson&lt;/a&gt; (UltraJSON) is an ultra fast JSON encoder and decoder written in pure C with bindings for Python 3.7+.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ijl/orjson"&gt;orjson&lt;/a&gt; is a fast, correct JSON library for Python. It is the fastest python library for json encoding &amp;amp; decoding. It serializes dataclass, datetime, numpy, and UUID instances natively.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Benchmarking
&lt;/h2&gt;

&lt;p&gt;I did a basic benchmark comparing json, ujson and orjson. The benchmarking results were interesting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;orjson&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;ujson&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;benchmark&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;dumps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000000&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;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;print&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;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;" __main__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1556283673.1523004&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"task_uuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"0ed1a1c3-050c-4fb9-9426-a7e72d0acfc7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"task_level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s"&gt;"action_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"started"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"action_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"another_key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"and_another"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;benchmark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;benchmark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ujson"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ujson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ujson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# orjson only outputs bytes, but often we need unicode:
&lt;/span&gt;    &lt;span class="n"&gt;benchmark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"orjson"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orjson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;orjson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# OUTPUT:
# Python 12.502133846282959
# ujson 4.428200960159302
# orjson 2.3136467933654785
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/ultrajson/ultrajson"&gt;ujson&lt;/a&gt; is 3 times faster than the standard json library&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ijl/orjson"&gt;orjson&lt;/a&gt; is over 6 times faster than the standard json library&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;For most cases, you would want to go with python’s standard json library which removes dependencies on other libraries. On other hand you could try out &lt;a href="https://github.com/ultrajson/ultrajson"&gt;ujson&lt;/a&gt;which is simple replacement for python’s json library. If you want more speed and also want dataclass, datetime, numpy, and UUID instances and you are ready to deal with more complex code, then you can try your hands on &lt;a href="https://github.com/ijl/orjson"&gt;orjson&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>json</category>
    </item>
    <item>
      <title>As a lead engineer/manager, what steps can you take for your team to provide better estimations for their tasks?</title>
      <dc:creator>Dollar Dhingra</dc:creator>
      <pubDate>Thu, 21 Apr 2022 15:38:53 +0000</pubDate>
      <link>https://dev.to/dollardhingra/how-to-enable-team-to-give-better-estimations-for-their-tasks-56e7</link>
      <guid>https://dev.to/dollardhingra/how-to-enable-team-to-give-better-estimations-for-their-tasks-56e7</guid>
      <description>&lt;p&gt;As a lead engineer/manager, what steps can you take for your team to provide better  estimations for their JIRA stories or tasks before starting the development work?&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>productivity</category>
      <category>management</category>
    </item>
    <item>
      <title>2021 year in review</title>
      <dc:creator>Dollar Dhingra</dc:creator>
      <pubDate>Sun, 20 Mar 2022 11:36:53 +0000</pubDate>
      <link>https://dev.to/dollardhingra/2021-year-in-review-5434</link>
      <guid>https://dev.to/dollardhingra/2021-year-in-review-5434</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Yes I know, I am late at publishing this. Somehow I missed it in my drafts. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Looking back at your achievements at the end of every year is a great way to boost your confidence and tackle the imposter syndrome :) So, here we go!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1st prize at Remote Hackathon&lt;/strong&gt; - Participated in the company’s internal remote hackathon with 6 other team members. Checkout more details &lt;a href="https://www.linkedin.com/posts/tothenew_geekcombat-hackathon-activity-6775326843689025536-WWY1?utm_source=linkedin_share&amp;amp;utm_medium=member_desktop_web"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Started writing technical blogs on topics related to python programming and software engineering. I also self-hosted the blog &lt;a href="https://dollardhingra.com"&gt;here&lt;/a&gt; with my first ever &lt;a href="https://dev.to/dollardhingra/beginners-guide-to-abstract-base-class-in-python-476i-temp-slug-1599916"&gt;article&lt;/a&gt;. Since then I try to write at least 1 blog article each month. &lt;strong&gt;This year itself my posts had 20k views&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Delivered talks&lt;/strong&gt; on following topics at my workplace &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introduction to ELasticsearch&lt;/li&gt;
&lt;li&gt;Clean Code&lt;/li&gt;
&lt;li&gt;Data Structures in Python&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created an open source telegram bot for covid : &lt;a href="https://dollardhingra.com/projects/#covid19-india-resources---telegram-bot"&gt;covid19-india-resources&lt;/a&gt;, &lt;a href="https://github.com/dollardhingra/cowinquick"&gt;repo link&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created a &lt;a href="https://dollardhingra.com/cowinquick/"&gt;panel&lt;/a&gt; for checking vaccine booking slots. Booked 30+ slots for family and friends using this panel, &lt;a href="https://github.com/dollardhingra/covid19indiaresources"&gt;Repo link&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Read the following books: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.amazon.in/System-Design-Interview-insiders-Second/dp/B08CMF2CQF"&gt;System Design Interview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.in/Using-Asyncio-Python-Understanding-Asynchronous/dp/9352139674/ref=sr_1_1?crid=2OHIII2QZBKME&amp;amp;keywords=understanding+asyncio&amp;amp;qid=1647712919&amp;amp;s=books&amp;amp;sprefix=underdtanding+asyncio%2Cstripbooks%2C349&amp;amp;sr=1-1"&gt;Understanding Asyncio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.in/No-Drama-Discipline-Whole-Brain-Nurture-Developing/dp/0345548043/ref=sr_1_1?keywords=no+drama+discipline+book&amp;amp;qid=1647713084&amp;amp;s=books&amp;amp;sprefix=no+dra%2Cstripbooks%2C187&amp;amp;sr=1-1"&gt;No Drama Discipline&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Awesome movies that I watched: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.imdb.com/title/tt0268978/"&gt;A beautiful mind&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.imdb.com/title/tt6751668/"&gt;Parasite&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accepted a job offer from &lt;a href="https://www.1mg.com/"&gt;Tata 1mg&lt;/a&gt; as SDE-3. We are hiring at &lt;a href="https://www.1mg.com/"&gt;Tata 1mg&lt;/a&gt;. Checkout the &lt;a href="https://1mg.darwinbox.in/ms/candidate/careers"&gt;jobs&lt;/a&gt; and let me know if you are interested to work at India’s leading healthcare brand.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>watercooler</category>
      <category>yearinreview</category>
      <category>career</category>
    </item>
    <item>
      <title>Bus Factor in Software Engineering</title>
      <dc:creator>Dollar Dhingra</dc:creator>
      <pubDate>Tue, 25 Jan 2022 16:41:35 +0000</pubDate>
      <link>https://dev.to/dollardhingra/bus-factor-in-software-engineering-42gh</link>
      <guid>https://dev.to/dollardhingra/bus-factor-in-software-engineering-42gh</guid>
      <description>&lt;h1&gt;
  
  
  1. Introduction
&lt;/h1&gt;

&lt;p&gt;Imagine that John Doe works on a project along with 7-10 folks. John started working on this project from the beginning and therefore knows a lot more than everyone else in the project.&lt;/p&gt;

&lt;p&gt;These leads to some problems such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;John is the go-to person for each detail that the team needs. John has a lot of responsibility and workload on his shoulders, making his progress sometimes slow.&lt;/li&gt;
&lt;li&gt;Whenever John falls sick and goes on unplanned leave, he is bugged by his team to keep things moving forward in the project.&lt;/li&gt;
&lt;li&gt;The organisation finds it hard to replace John and has therefore retained him twice in the past year by raising his compensation twice.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;In short, the project has a single point of failure -&amp;gt; John Doe&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  2. What is Bus Factor?
&lt;/h1&gt;

&lt;p&gt;As per Wikipedia, The bus factor is a measurement of the risk resulting from information and capabilities not being shared among team members, derived from the phrase “in case they get hit by a bus”. It is also known as the bread truck scenario, bus problem, beer truck scenario, lottery factor, truck factor, bus/truck number, or lorry factor.&lt;/p&gt;

&lt;p&gt;In simple words, what is the probability of the project failing if John Doe gets hit by a bus and is not able to return to work?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Higher the bus factor higher the risk of failure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  3. Reducing/Preventing the Bus Factor in Software Development
&lt;/h1&gt;

&lt;h2&gt;
  
  
  3.1 Documenting
&lt;/h2&gt;

&lt;p&gt;Creating and maintaining documentation can take a good amount of effort from all the stakeholders. But in the long run, it is worth documenting. Documenting includes Product Requirement Documents(PRDs), High &amp;amp; Low-level design documents, changelogs, READMEs, complete ticket descriptions on ticketing tools, Root Cause Analysis documents in case of production fires, etc&lt;/p&gt;

&lt;h2&gt;
  
  
  3.2 Code Reviews
&lt;/h2&gt;

&lt;p&gt;If done effectively, code reviews can act as an excellent tool to reduce the bus factor, given that everyone in the team gets a chance to review the code. The Engineering manager/team lead should make sure that there are relative code review guidelines set up as per the team so that it is effective enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.3 Meetings
&lt;/h2&gt;

&lt;p&gt;Yes, I know meetings sometimes slow us down and hinder our productivity. Also, some meetings can just be replaced by an email. But, meetings (especially if you are working remotely) can actively reduce the bus factor if done correctly. Meetings like standup, sprint planning/grooming, design discussions, sprint retros etc bring everyone together as a team. Imagine you reading a minute of meeting document vs actually brainstorming in the meeting. &lt;strong&gt;Meetings do not replace the documentation. Instead, the documentation complements the meeting process.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3.4 Team Process
&lt;/h2&gt;

&lt;p&gt;More team processes can improve the knowledge distribution in the team like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pair programming&lt;/li&gt;
&lt;li&gt;Office hours&lt;/li&gt;
&lt;li&gt;On-call rotations&lt;/li&gt;
&lt;li&gt;Engineering demos&lt;/li&gt;
&lt;li&gt;Knowledge sharing sessions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3.5 Positive Work culture
&lt;/h2&gt;

&lt;p&gt;A positive culture means employees are happy in the organisation and a better work environment is created. Following techniques can be applied to improve the work culture and reduce the bus factor:&lt;/p&gt;

&lt;h3&gt;
  
  
  3.5.1 Mandatory Paid Annual Vacation
&lt;/h3&gt;

&lt;p&gt;Most of the organisations provide paid leave to their employees. The organisations should also encourage people to use these leaves and go on a vacation(for a week at least). This will enable other employees to take care of work in the absence of an employee.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.5.2 Short Notice/Termination Period
&lt;/h3&gt;

&lt;p&gt;A short notice period means, the organisation making sure that there is less dependency on an employee.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;The first step is to talk about Bus factor in your team, even if you are a junior member in the team. Maybe, some of the above methods like meetings, code reviews, documenting etc. are already being used in your organisation for sharing knowledge. You can consider optimising those methods to reduce/prevent the bus factor in your team. For eg, you can consider including the junior members of your team in meetings and code reviews. The members with a centralized knowledge can work on spreading their knowledge in the team so that they can spend their time and energy on something new for the team. &lt;/p&gt;

&lt;p&gt;What do you think of Bus factor in your team? Do you have more methods to prevent high bus factor? Feel free to give your feedback!&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>discuss</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to install older Ruby versions(2.x) on Mac M1 without using arch x86_64</title>
      <dc:creator>Dollar Dhingra</dc:creator>
      <pubDate>Thu, 20 Jan 2022 16:53:20 +0000</pubDate>
      <link>https://dev.to/dollardhingra/how-to-install-older-ruby-versions2x-on-mac-m1-without-using-arch-x8664-58ie</link>
      <guid>https://dev.to/dollardhingra/how-to-install-older-ruby-versions2x-on-mac-m1-without-using-arch-x8664-58ie</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;After spending hours of searching different solutions on the internet for &lt;strong&gt;installing older version of ruby (2.5.x, 2.6.x etc ) on Mac M1&lt;/strong&gt;, I finally figured out the solution and decided to document it by writing a blog.&lt;/p&gt;

&lt;h1&gt;
  
  
  Pre-Requirements
&lt;/h1&gt;

&lt;p&gt;Make sure you have following installed on your Mac M1&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update your Mac OS&lt;/li&gt;
&lt;li&gt;Homebrew
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;rbenv (Should work for rvm also)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install rbenv

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Make sure that you have latest xcode command line tools
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xcode-select --install

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

&lt;/div&gt;



&lt;p&gt;if the above fails, then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo rm -rf /Library/Developer/CommandLineTools
xcode-select --install

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

&lt;/div&gt;



&lt;h1&gt;
  
  
  Steps to Reproduce The Problem
&lt;/h1&gt;

&lt;p&gt;The problem occurs if you try to install an older version with Ruby.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rbenv install 2.6.2

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

&lt;/div&gt;



&lt;p&gt;Error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- BUILD FAILED (macOS 12.1 using ruby-build 20210707)
- Inspect or clean up the working tree at `/var/folders/.....`

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

&lt;/div&gt;



&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;p&gt;Try installing the ruby version with this variable &lt;code&gt;RUBY_CFLAGS="-Wno-error=implicit-function-declaration"&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUBY_CFLAGS="-Wno-error=implicit-function-declaration" rbenv install 2.6.2

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

&lt;/div&gt;



&lt;p&gt;This should work fine!&lt;/p&gt;

&lt;h1&gt;
  
  
  Other Installations
&lt;/h1&gt;

&lt;p&gt;After this, install other dependencies normally using brew. For eg: postgresql I installed postgresql@10 which was required for the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install postgresql@10

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

&lt;/div&gt;



&lt;p&gt;The end of success clearly states that you have to do some entries in your bash/zsh file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If you need to have postgresql@10 first in your PATH, run:
  echo 'export PATH="/opt/homebrew/opt/postgresql@10/bin:$PATH"' &amp;gt;&amp;gt; ~/.zshrc

For compilers to find postgresql@10 you may need to set:
  export LDFLAGS="-L/opt/homebrew/opt/postgresql@10/lib"
  export CPPFLAGS="-I/opt/homebrew/opt/postgresql@10/include"

For pkg-config to find postgresql@10 you may need to set:
  export PKG_CONFIG_PATH="/opt/homebrew/opt/postgresql@10/lib/pkgconfig"

To restart postgresql@10 after an upgrade:
  brew services restart postgresql@10
Or, if you don't want/need a background service you can just run:
  /opt/homebrew/opt/postgresql@10/bin/postgres -D /opt/homebrew/var/postgresql@10

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

&lt;/div&gt;



&lt;p&gt;Do these changes and then go to your project and set the ruby version for the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rbenv local 2.6.2

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

&lt;/div&gt;



&lt;p&gt;Check if the ruby version is correct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ruby -v # should output whatever version you had set in the previous step.

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

&lt;/div&gt;



&lt;p&gt;The next step is to install the bundle&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bundle install

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

&lt;/div&gt;



&lt;p&gt;During the installation, I got an error while installing http-parser. The error message looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Caused by:
LoadError: cannot load such file -- 2.6/ffi_c

Caused by:
LoadError: cannot load such file -- ffi-compiler/compile_task

(See full trace by running task with --trace)

rake failed, exit code 1

Gem files will remain installed in /Users/Dollar/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/http-parser-1.2.3 for inspection.
Results logged to /Users/Dollar/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/extensions/-darwin-21/2.6.0/http-parser-1.2.3/gem_make.out

An error occurred while installing http-parser (1.2.3), and Bundler cannot continue.
Make sure that `gem install http-parser -v '1.2.3' --source 'https://rubygems.org/'` succeeds before bundling.

In Gemfile:
  elastic-apm was resolved to 3.15.1, which depends on
    http was resolved to 4.4.1, which depends on
      http-parser

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

&lt;/div&gt;



&lt;p&gt;The error message clearly states that the reason&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LoadError: cannot load such file -- ffi-compiler/compile_task

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

&lt;/div&gt;



&lt;p&gt;I rectified the problem through installing ffi compiler for ruby platform using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gem install ffi --platform=ruby

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

&lt;/div&gt;



&lt;p&gt;Now, try running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bundle install

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

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Things should work now! Feel free to drop a suggestion or any feedback if this process can be further improved.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Best Practices For Writing Clean Pythonic Code</title>
      <dc:creator>Dollar Dhingra</dc:creator>
      <pubDate>Sat, 11 Dec 2021 09:24:32 +0000</pubDate>
      <link>https://dev.to/dollardhingra/python-code-best-practices-4k96</link>
      <guid>https://dev.to/dollardhingra/python-code-best-practices-4k96</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This article is a collection of best practices for more idiomatic python code especially if you are new to python. &lt;/p&gt;

&lt;h2&gt;
  
  
  Contribute
&lt;/h2&gt;

&lt;p&gt;Feel free to &lt;a href="https://github.com/dollardhingra/dollardhingra.github.io/edit/master/_posts/2021-12-05-python-code-best-practices.md"&gt;contribute&lt;/a&gt; to this list, and I will thank you by including a link to your profile with the snippet!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Catching Exceptions
&lt;/h2&gt;

&lt;p&gt;This is a sure-shot way to get your code into trouble&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# very bad practice
&lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# A slightly better way(included logging), but still a bad practice:
&lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# although, logging is a good practice
&lt;/span&gt;
&lt;span class="c1"&gt;# When we don't use `Exception` we will also be catching events like system exit. 
# So, using Exception means that we are only catching Exceptions.
&lt;/span&gt;
&lt;span class="c1"&gt;# A better way:
&lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;do_something&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;# some code to handle your exception gracefully if required
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have used a specific type of Exception i.e. &lt;code&gt;ValueError&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Name Casing
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="c1"&gt;# using camelCase is not a convention in python
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sampleArr&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="c1"&gt;# instead use snake_case in python
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample_arr&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In python, &lt;code&gt;snake_case&lt;/code&gt; is preferred for variables, functions and method names. However, for classes, &lt;code&gt;PascalCase&lt;/code&gt; is used.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Chained comparison operators
&lt;/h2&gt;

&lt;p&gt;There are multiple ways of comparing in Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Don't do this:
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'x is greater than 0 but less than 10'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# Instead, do this:
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'x is greater than 0 but less than 10'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Mutable default arguments
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="c1"&gt;# wrong way!
# a sure shot way to get some unintended bugs in your code
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_fruit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt;
    &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&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;box&lt;/span&gt;


&lt;span class="c1"&gt;# correct way!
# recommended way for handling mutable default arguments:
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_fruit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&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;box&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read more about mutable default arguments &lt;a href="https://dev.to/dollardhingra/1-anti-pattern-mutable-default-arguments-3bp5"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. String Formatting
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="c1"&gt;# Avoid using it
# %-formatting
&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"James Bond"&lt;/span&gt;
&lt;span class="n"&gt;profession&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Secret Agent"&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, %s. You are a %s."&lt;/span&gt; &lt;span class="o"&gt;%&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;profession&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# slightly better
# str.format()
&lt;/span&gt;&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, {}. You are a {}."&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;format&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;profession&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# Short, crisp and faster!
# f-strings
&lt;/span&gt;&lt;span class="k"&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="s"&gt;"Hello, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. You are a &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;profession&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&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 f in f-strings may as well stand for "fast." f-strings are faster than both %-formatting and str.format(). &lt;a href="https://www.python.org/dev/peps/pep-0498/#abstract"&gt;(Source)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Top-level script environment
&lt;/h2&gt;

&lt;p&gt;Executes only if it is run as a script and not as a module&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Filename: run.py
&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'__main__'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Hello from script!'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ python run.py
$ Hello from script!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Hello from script!&lt;/code&gt; will &lt;strong&gt;not&lt;/strong&gt; be printed if the module is imported into any other module.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Conditional expressions
&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;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can be reduced to this one:&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;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Iterating over an iterator
&lt;/h2&gt;

&lt;p&gt;You don’t necessarily need to iterate over the indices of the elements in an iterator if you don’t need them. You can iterate directly over the elements.&lt;br&gt;
This makes your code more pythonic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;list_of_fruits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"pear"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"orange"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# bad practice
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list_of_fruits&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
    &lt;span class="n"&gt;fruit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list_of_fruits&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;process_fruit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# good practice
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fruit&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;list_of_fruits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;process_fruit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  9. Indexing/Counting during iteration
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Don't do this:
&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;


&lt;span class="c1"&gt;# Nor this:
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
    &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Definitely don't do this:
&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# Instead, use `enumerate()`
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  10. Using context managers
&lt;/h2&gt;

&lt;p&gt;Python provides context managers that manage the overhead of initializing and clearing up the resources and let&lt;br&gt;
you focus on the implementation. For example in the case of reading a file, you don't need to be concerned &lt;br&gt;
to close the file manually.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# bad practice 
&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./data.csv"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"wb"&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="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"some data"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# KeyError
# f.close() never executes which leads to memory issues
&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;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# good practice
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./data.csv"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"wb"&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="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"some data"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# python still executes f.close() even if the KeyError exception occurs
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  11. Using set for searching instead of a list
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s"&gt;'s'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'m'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'s'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'p'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'m'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# ok for small no. of elements
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lookup_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;'s'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="c1"&gt;# O(n)
&lt;/span&gt;

&lt;span class="c1"&gt;# better for large no. of elements
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lookup_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;'s'&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="c1"&gt;# O(1)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sets are implemented using hash in python, which makes searching of element faster(O(1)) as compared to searching in a &lt;br&gt;
list(O(n)). &lt;/p&gt;
&lt;h2&gt;
  
  
  12. using * while importing a module
&lt;/h2&gt;

&lt;p&gt;Imports should always be specific. Importing * from a module is a very bad practice that pollutes the namespace.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# bad practice 
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;math&lt;/span&gt; &lt;span class="kn"&gt;import&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;ceil&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="c1"&gt;# good practice 
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;math&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ceil&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;ceil&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="c1"&gt;# we know where ceil comes from
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  13. using items() for iterating a dictionary
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Aarya"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
     &lt;span class="s"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Dont do this
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&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="s"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Instead do this
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&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="s"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://realpython.com/python-f-strings/"&gt;RealPython f-strings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://realpython.com/the-most-diabolical-python-antipattern/"&gt;RealPython the most diabolic anti pattern&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arielortiz.info/s201911/pycon2019/docs/design_patterns.html"&gt;Python Idiom Patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://towardsdatascience.com/18-common-python-anti-patterns-i-wish-i-had-known-before-44d983805f0f"&gt;18 Common Python Anti-Patterns I Wish I Had Known Before&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  More Articles You May Like
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/dollardhingra/1-anti-pattern-mutable-default-arguments-3bp5"&gt;#1 Anti-Pattern - Mutable Default Arguments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/dollardhingra/code-quality-tools-in-python-4k2a"&gt;Code Quality Tools in Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/dollardhingra/understanding-the-abstract-base-class-in-python-k7h"&gt;Beginner's guide to abstract base class in Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>productivity</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Anti Pattern - Mutable Default Arguments</title>
      <dc:creator>Dollar Dhingra</dc:creator>
      <pubDate>Sun, 31 Oct 2021 17:34:56 +0000</pubDate>
      <link>https://dev.to/dollardhingra/1-anti-pattern-mutable-default-arguments-3bp5</link>
      <guid>https://dev.to/dollardhingra/1-anti-pattern-mutable-default-arguments-3bp5</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this article, you will understand what mutable default arguments are, why you should avoid using them and the workaround.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Example With A Mutable Default Argument
&lt;/h2&gt;

&lt;p&gt;Consider the following code example below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_fruit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt;
    &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&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;box&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Let's understand step by step what is happening:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We are creating a function to add fruits(str) in a box(list)&lt;/li&gt;
&lt;li&gt;There is a &lt;code&gt;add_fruit&lt;/code&gt; function which is responsible for adding the &lt;code&gt;fruit&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;This function takes 2 arguments: &lt;code&gt;fruit&lt;/code&gt; and &lt;code&gt;box&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attention!&lt;/strong&gt; : The second argument here is a mutable default argument.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  So, what is mutable default argument?
&lt;/h2&gt;

&lt;p&gt;An argument in a function with default value as mutable. &lt;/p&gt;

&lt;p&gt;In short, Python has both mutable and immutable types. The difference is: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mutables can be modified&lt;/li&gt;
&lt;li&gt;immutables can't be modified.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For eg: Tuple is an immutable type. If we define a tuple like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;weekends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'saturday'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'sunday'&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt;

&lt;span class="n"&gt;weekends&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'Monday'&lt;/span&gt; &lt;span class="c1"&gt;# TypeError: 'tuple' object does not support item assignment
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An immutable type canot be modified.&lt;/p&gt;

&lt;h2&gt;
  
  
  You Might Expect
&lt;/h2&gt;

&lt;p&gt;let's modify our code and create a couple of boxes, i.e. red box and yellow box&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_fruit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt;
    &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&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;box&lt;/span&gt;

&lt;span class="n"&gt;red_box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;add_fruit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&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="s"&gt;"red box: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;red_box&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;yellow_box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;add_fruit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mango"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&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="s"&gt;"yellow box: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;yellow_box&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Expected Output
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;red box: ["apple"]

yellow box: ["mango"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Actually Output
&lt;/h3&gt;

&lt;p&gt;Actually, you get the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;red box: ["apple"]

yellow box: ["apple", "mango"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait? What? We never added apple in the yellow box. &lt;/p&gt;

&lt;h2&gt;
  
  
  What Exactly Happened?
&lt;/h2&gt;

&lt;p&gt;A new list is created once when the function is defined, and the same list is used in each successive call. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Python’s default arguments are evaluated once when the function is defined. This means that if you use a mutable default argument and mutate it, you will and have mutated that object for all future calls to the function as well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We will get the same result for other mutable types also(For eg: &lt;code&gt;dict&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  What Should Be Done?
&lt;/h2&gt;

&lt;p&gt;If your function needs to have a default argument for a mutable type, then default it with None and also add a check for the same.&lt;br&gt;
Let's modify our &lt;code&gt;add_fruit&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_fruit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fruit&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;box&lt;/span&gt;

&lt;span class="n"&gt;red_box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;add_fruit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&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="s"&gt;"red box: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;red_box&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;yellow_box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;add_fruit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mango"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&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="s"&gt;"yellow box: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;yellow_box&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This extra check can saves hours of debugging!&lt;/p&gt;

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

&lt;p&gt;It's always a best practice to not use mutable default arguments. Instead, try adding an extra comparison check with &lt;br&gt;
&lt;code&gt;None&lt;/code&gt; to handle the default arguments which are mutable.&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Code Quality Tools in Python</title>
      <dc:creator>Dollar Dhingra</dc:creator>
      <pubDate>Sat, 09 Oct 2021 16:04:52 +0000</pubDate>
      <link>https://dev.to/dollardhingra/code-quality-tools-in-python-4k2a</link>
      <guid>https://dev.to/dollardhingra/code-quality-tools-in-python-4k2a</guid>
      <description>&lt;h2&gt;
  
  
  What is code quality?
&lt;/h2&gt;

&lt;p&gt;Before we talk about code quality tools, let's see what code quality is. We can agree that code is of high quality if&lt;/p&gt;

&lt;h3&gt;
  
  
  It does what it is supposed to do
&lt;/h3&gt;

&lt;p&gt;If the code written is not doing what is supposed to do, then it doesn't meet the very basic requirements, and we can say that the code quality is low.&lt;/p&gt;

&lt;h3&gt;
  
  
  It does not contain defects or problems
&lt;/h3&gt;

&lt;p&gt;Let's say that your code does what it is supposed to do, but struggles to perform well on edge cases. Let's take an example of a mobile app that you start using for communicating with friends and family. You can send &amp;amp; receive messages easily from your friends through this app. One fine day, you want to share a photo with a group and your app crashes. Certainly, there is some issue with the code that has not been tested properly. &lt;/p&gt;

&lt;h3&gt;
  
  
  It is easy to read, maintain, and extend
&lt;/h3&gt;

&lt;p&gt;Finally, let's consider that a code does what it is supposed to do, and it does not contain any defects or problems. But, the code is not easy to read, maintain and extend. &lt;/p&gt;

&lt;p&gt;Robert C. Martin in his book &lt;a href="https://www.oreilly.com/library/view/clean-code-a/9780136083238/"&gt;Clean Code&lt;/a&gt; says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as&lt;br&gt;
part of the effort to write new code. Because this ratio is so high, we want the reading of the code to be easy, even if it makes the writing harder.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Therefore, code readability is a very important factor in code quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Style guide: following the conventions
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Great codebases look like they were written by an individual, when they were worked on by a team.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Consistency code is easier to read &amp;amp; therefore maintain by a team. &lt;br&gt;
&lt;strong&gt;A style guide serves the purpose of defining a consistent way to write your code.&lt;/strong&gt; &lt;br&gt;
The style guide contains conventions to be followed for writing a code. &lt;a href="https://pep8.org/"&gt;PEP8&lt;/a&gt; is the official style guide for Python that is recommended to use for writing any python code. Let's consider a small example. In the python code below, the operators tend to get scattered across different columns on the screen, and each operator has moved away from its operand and onto the previous line. Here, the eye has to do extra work to tell which items are added and which are subtracted:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not Recommended:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;## No: operators sit far away from their operands
&lt;/span&gt;&lt;span class="n"&gt;income&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gross_wages&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
          &lt;span class="n"&gt;taxable_interest&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dividends&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;qualified_dividends&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;
          &lt;span class="n"&gt;ira_deduction&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;
          &lt;span class="n"&gt;student_loan_interest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To solve this readability problem, mathematicians and their publishers follow the opposite convention which is more &lt;br&gt;
readable&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;## Yes: easy to match operators with operands
&lt;/span&gt;&lt;span class="n"&gt;income&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gross_wages&lt;/span&gt;
          &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;taxable_interest&lt;/span&gt;
          &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dividends&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;qualified_dividends&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;ira_deduction&lt;/span&gt;
          &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;student_loan_interest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another official recommendation from Python is &lt;a href="https://www.python.org/dev/peps/pep-0257/"&gt;PEP-257&lt;/a&gt; Docstring Conventions. A docstring is a string literal that occurs as the first statement in a module, function, class, or method definition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;complex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;real&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;imag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""Form a complex number.

    Keyword arguments:
    real -- the real part (default 0.0)
    imag -- the imaginary part (default 0.0)
    """&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;imag&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;real&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mf"&gt;0.0&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;complex_zero&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are tools capable of generating documentation directly from the code if the docstrings are consistent in the code.&lt;/p&gt;

&lt;p&gt;Some organisations like Google have their own &lt;a href="https://google.github.io/styleguide/"&gt;style guides&lt;/a&gt;. &lt;br&gt;
Checkout google's &lt;a href="https://google.github.io/styleguide/pyguide.html"&gt;python style guide&lt;/a&gt;.  &lt;/p&gt;
&lt;h2&gt;
  
  
  How to measure code quality?
&lt;/h2&gt;

&lt;p&gt;There are different ways to measure code quality in general. This article talks about some basic tools&lt;br&gt;
provided in Python to measure the code quality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linters&lt;/li&gt;
&lt;li&gt;Formatters&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Linters
&lt;/h2&gt;

&lt;p&gt;Linters analyze code to detect various categories of issues:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Logical Issue&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code errors&lt;/li&gt;
&lt;li&gt;Code with potentially unintended results&lt;/li&gt;
&lt;li&gt;Dangerous code patterns&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Stylistic Issue&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code not conforming to defined conventions/style guide&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Popular python linters
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.pylint.org/"&gt;Pylint&lt;/a&gt;: Features like checking &lt;strong&gt;coding standards&lt;/strong&gt;, &lt;strong&gt;error detection&lt;/strong&gt;, &lt;strong&gt;refactoring help&lt;/strong&gt; and more.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/PyCQA/pycodestyle"&gt;pycodestyle&lt;/a&gt;: for checking some of the style conventions in PEP8&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pypi.org/project/flake8/"&gt;Flake8&lt;/a&gt;: a combination of following linters: &lt;a href="https://github.com/PyCQA/pyflakes"&gt;PyFlakes&lt;/a&gt;, 
&lt;a href="https://github.com/PyCQA/pycodestyle"&gt;pycodestyle&lt;/a&gt;, &lt;a href="https://github.com/PyCQA/mccabe"&gt;Ned Batchelder’s McCabe script&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/klen/pylama"&gt;Pylama&lt;/a&gt;: composed of the following linters and other tools for analyzing code: &lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/PyCQA/pycodestyle"&gt;pycodestyle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/PyCQA/pydocstyle"&gt;pydocstyle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/PyCQA/pyflakes"&gt;PyFlakes&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/PyCQA/mccabe"&gt;Mccabe&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.pylint.org/"&gt;Pylint&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://radon.readthedocs.io/en/latest/"&gt;Radon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://atom.io/packages/linter-gjslint"&gt;gjslint&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every linter has its advantages and disadvantages and should be picked up based on the project you are working on.&lt;br&gt;
If a linter doesn't give out any warning for any lint, that doesn't mean that code is always correct, a linter is just a &lt;br&gt;
static tool for code analysis. It cannot check if the job that is supposed to be done is done or not.&lt;/p&gt;
&lt;h2&gt;
  
  
  Formatters
&lt;/h2&gt;

&lt;p&gt;Formatters automatically format your code based on a style guide. Some popular python formatters are:&lt;/p&gt;
&lt;h3&gt;
  
  
  Black
&lt;/h3&gt;

&lt;p&gt;as per the black's documentation, &lt;a href="https://github.com/psf/black"&gt;Black&lt;/a&gt; is "The uncompromising Python code formatter". &lt;br&gt;
It is my personal favourite because it has minimal configuration and is fast enough. Black is used by some very popular open-source projects, such as pytest, tox, Pyramid, Django Channels, Poetry, and so on. Example usage:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;unique.py&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_unique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
               &lt;span class="n"&gt;s&lt;/span&gt;
               &lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"__main__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;is_unique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
         &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;$ black unique.py&lt;/code&gt; produces the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_unique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"__main__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_unique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  YAPF
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/google/yapf"&gt;YAPF&lt;/a&gt; (Yet Another Python Formatter) is Google's official python formatter which&lt;br&gt;
follows google's &lt;a href="https://google.github.io/styleguide/pyguide.html"&gt;style guide&lt;/a&gt;. The documentation is easy to&lt;br&gt;
understand the installation and configuration for this formatter.&lt;/p&gt;
&lt;h3&gt;
  
  
  autopep8
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://pypi.org/project/autopep8/"&gt;autopep8&lt;/a&gt; is an unofficial, yet popular, tool that automatically formates &lt;br&gt;
Python code to conform to PEP 8. It uses pycodestyle, Python’s official PEP-8 violation checker tool, to determine what parts of the code need to be formatted.&lt;/p&gt;
&lt;h3&gt;
  
  
  isort
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/PyCQA/isort"&gt;isort&lt;/a&gt; is a Python utility/library to sort imports alphabetically, and &lt;br&gt;
automatically separated into sections and by type.&lt;/p&gt;

&lt;p&gt;Before isort:&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="nn"&gt;my_lib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;my_lib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Object3&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;my_lib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Object2&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;third_party&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;lib15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib14&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;__future__&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;absolute_import&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;third_party&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;lib3&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hey"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"yo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After isort:&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="nn"&gt;__future__&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;absolute_import&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;third_party&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lib1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="n"&gt;lib9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lib15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;my_lib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Object2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Object3&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hey"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"yo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Where to use the code quality tools?
&lt;/h2&gt;

&lt;p&gt;You can use these code quality tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In your IDE/editor, when you are writing your code&lt;/li&gt;
&lt;li&gt;on committing the code&lt;/li&gt;
&lt;li&gt;merging the code or while running the tests&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  IDE/editor
&lt;/h3&gt;

&lt;p&gt;Most modern IDEs and editors have inbuilt support for linters. Some editors like &lt;a href="https://code.visualstudio.com/docs/python/linting"&gt;VS Code&lt;/a&gt; have great support for linters. You can also run a specific formatter on running the auto-format command in VS Code. Check more about it&lt;br&gt;
&lt;a href="https://code.visualstudio.com/docs/python/editing#_formatting"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For IDE like Pycharm, there are plugins available for running lints and formatters. For example, check out the &lt;a href="https://plugins.jetbrains.com/plugin/11084-pylint"&gt;pylint plugin&lt;/a&gt; and &lt;br&gt;
&lt;a href="https://plugins.jetbrains.com/plugin/10563-black-pycharm"&gt;black formatter plugin&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  On Committing the code: Hooks
&lt;/h3&gt;

&lt;p&gt;Like many other Version Control Systems, Git has a way to fire off custom scripts when certain important actions occur through &lt;a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks"&gt;git-hooks&lt;/a&gt;. You can use these scripts to run the &lt;br&gt;
lints and formatters to block any new code that doesn’t meet quality standards or to automatically format the commit.&lt;br&gt;
A useful &lt;a href="https://pre-commit.co%20m/"&gt;pre-commit&lt;/a&gt; (written in python) is a multi-language package manager for &lt;br&gt;
pre-commit hooks. You specify a list of hooks you want and pre-commit manages the installation and execution of any hook written in any language before every commit&lt;/p&gt;

&lt;h3&gt;
  
  
  When running tests: Continuous Integration
&lt;/h3&gt;

&lt;p&gt;You can also place linters &amp;amp; formatters directly into whatever system you may use for continuous integration. &lt;br&gt;
The linters can be set up to fail the build if the code doesn’t meet quality standards. A CI(continuous integration)  is a practice of automating the integration of code changes from multiple contributors into a single software project. This means that as soon as a developer merges their code in the main branch, the CI  pipeline(for eg: git workflow) can perform some automatic operations like &lt;code&gt;linting&lt;/code&gt; before the code is deployed.&lt;/p&gt;

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

&lt;p&gt;A code is of high quality if it does what it is supposed to do, it &lt;strong&gt;does not contain defects&lt;/strong&gt; or problems and&lt;br&gt;
it is easy to &lt;strong&gt;read, maintain, and extend&lt;/strong&gt;. Style guides like A style guide like &lt;a href="https://pep8.org/"&gt;PEP8&lt;/a&gt; and google's &lt;a href="https://google.github.io/styleguide/"&gt;style guide&lt;/a&gt; help serve the purpose of defining a consistent way to write your code. The different tools for measuring and improving the code quality are linters &amp;amp; formatters.&lt;/p&gt;

&lt;p&gt;Linters analyze code to detect various categories of issues like logistical issue and stylistic issues. Some popular linters are &lt;a href="https://www.pylint.org/"&gt;Pylint&lt;/a&gt;, &lt;a href="https://github.com/PyCQA/pycodestyle"&gt;pycodestyle&lt;/a&gt;, [Flake8 (&lt;a href="https://pypi.org/project/flake8/"&gt;https://pypi.org/project/flake8/&lt;/a&gt;) and &lt;a href="https://github.com/klen/pylama"&gt;Pylama&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Formatters automatically format your code based on a style guide. Some popular formatters are &lt;a href="https://github.com/psf/black"&gt;Black&lt;/a&gt;, &lt;a href="https://github.com/google/yapf"&gt;YAPF&lt;/a&gt;, &lt;a href="https://pypi.org/project/autopep8/"&gt;autopep8&lt;/a&gt; and [isort (&lt;a href="https://github.com/PyCQA/isort"&gt;https://github.com/PyCQA/isort&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;Finally, You can use these code quality tools using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IDE/editors - when you are writing your code&lt;/li&gt;
&lt;li&gt;pre-commit hooks - on committing the code using &lt;/li&gt;
&lt;li&gt;continuous integration - while running the tests&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Similar Posts by me
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/dollardhingra/python-code-best-practices-4k96"&gt;Best Practices For Writing Clean Pythonic Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/dollardhingra/1-anti-pattern-mutable-default-arguments-3bp5"&gt;#1 Anti-Pattern - Mutable Default Arguments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/dollardhingra/understanding-the-abstract-base-class-in-python-k7h"&gt;Beginner's guide to abstract base class in Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>codequality</category>
      <category>python</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>CoWIN Vaccine Availability - My first open source project</title>
      <dc:creator>Dollar Dhingra</dc:creator>
      <pubDate>Mon, 17 May 2021 12:02:15 +0000</pubDate>
      <link>https://dev.to/dollardhingra/contribution-required-for-a-simple-cowin-vaccine-availability-website-15f4</link>
      <guid>https://dev.to/dollardhingra/contribution-required-for-a-simple-cowin-vaccine-availability-website-15f4</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.cowin.gov.in/home"&gt;CoWIN&lt;/a&gt; is a vaccination booking platform for booking vaccination for Indian citizens. This is the largest vaccination drive ever. Anyone can simple go and book the vaccination slots as per the availability in the respective state and districts. In this post I have created another platform just for checking the vaccine availability.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But what's the need for creating a different platform for checking the availability when you already have the official platform?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Problem
&lt;/h1&gt;

&lt;p&gt;I had a hard time finding the vaccination slots (for 18-45 age group). Some of the problems I(and other people I think) faced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most of the times the slots were not available and when they were available, they were booked in seconds. &lt;/li&gt;
&lt;li&gt;The User experience of the original CoWIN portal is not that great. Firstly you need to login through your phone number(by an OTP which sometimes refuses to arrive on your phone). You are automatically logged out after 15-20 mins.&lt;/li&gt;
&lt;li&gt;There are some features that are missing, but can be really helpful in finding the slots. For eg: Ability to search across multiple districts.&lt;/li&gt;
&lt;li&gt;A filter for hiding the unavailable slots from the search result would have been really helpful.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Some people have also written scripts for notifying whenever the slots are available. The idea is really great but there are couple of problems with the scripts approach:&lt;br&gt;
As soon as you get the notification that slots are available in your district, you open up your browser -&amp;gt;login into the &lt;a href="https://www.cowin.gov.in/home"&gt;CoWIN portal&lt;/a&gt; -&amp;gt; select the beneficiaries that you want to get vaccinated -&amp;gt; select the state &amp;amp; district/enter pin code and click search -&amp;gt; BOOM! the slots have already been booked! &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;p&gt;I created a simple HTML page which calls the public CoWIN API in JS. Checkout the live demo &lt;a href="https://dollardhingra.com/cowinquick/"&gt;here&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Note:&lt;/strong&gt; This website can only be used for checking the available slots. For booking, the &lt;a href="https://www.cowin.gov.in/home"&gt;official site&lt;/a&gt; must be used.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/knjqHZNs7LM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;This helps in booking as&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There is no need for entering phone number/otp again and again&lt;/li&gt;
&lt;li&gt;The results are visible for multiple districts at once.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  How I have booked more than 20 slots till now
&lt;/h1&gt;

&lt;p&gt;I have booked more than 20 slots(for friends and family) with the following approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;There is usually a 1-2 hour window when the slots are open. Usually between 6-10pm on weekdays and 12-4pm on weekends. These timings may change so keep casually looking for the slots whenever you have your phone in hand through the &lt;a href="https://dollardhingra.com/cowinquick/"&gt;cowinquick site&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let's say that you find available slots in your district or a nearby district. Note the name of the center. Let's say that the name of the center is "BLK Hospital Site 1". &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In one tab, login into the &lt;a href="https://www.cowin.gov.in/home"&gt;cowin portal&lt;/a&gt; and select the city and distric/pin code. In the other tab you can open the &lt;a href="https://dollardhingra.com/cowinquick/"&gt;cowinquick site&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now check if "BLK Hospital Site 1" is available. If not, then come back to the &lt;a href="https://dollardhingra.com/cowinquick/"&gt;cowinquick site&lt;/a&gt; and search again. There is high probability that "BLK Hospital Site 2" will come up next in few minutes. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Keep searching after every 5-10 seconds. There is a chance that you are searching in the time window where the slots are being updated. You will come to know that the slots are being updated if you keep searching for 5-10 mins(clicking search after every 10-20 seconds). Either of following will happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You will see that for some centers the slots are being open and booked in 15-20 seconds. Try booking that center in those 15 seconds. The advantage you have on &lt;a href="https://dollardhingra.com/cowinquick/"&gt;cowinquick site&lt;/a&gt; is that you can see the results for multiple districts at once &amp;amp; you don't need to select 18+ again on every search. &lt;/li&gt;
&lt;li&gt;There maybe a situation when you don't see any centers updating slots. You can then try the same after some time. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>html</category>
      <category>javascript</category>
      <category>css</category>
    </item>
    <item>
      <title>Beginner's guide to abstract base class in Python</title>
      <dc:creator>Dollar Dhingra</dc:creator>
      <pubDate>Fri, 02 Apr 2021 14:33:48 +0000</pubDate>
      <link>https://dev.to/dollardhingra/understanding-the-abstract-base-class-in-python-k7h</link>
      <guid>https://dev.to/dollardhingra/understanding-the-abstract-base-class-in-python-k7h</guid>
      <description>&lt;h2&gt;
  
  
  What is an abstract base class?
&lt;/h2&gt;

&lt;p&gt;In simple words, an abstract base class provides a blueprint for other classes. Abstract base classes don't contain the implementation. Instead, they provide an interface and make sure that the derived classes are properly implemented.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we need abstract base classes?
&lt;/h2&gt;

&lt;p&gt;Imagine that you are creating a game in which you have different animals. For defining animals you can have an abstract class called &lt;code&gt;Animal&lt;/code&gt;. A Dog/Cat/Duck are all the classes that are derived from the base class &lt;code&gt;Animal&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Animal Base Class
&lt;/h3&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;Animal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_age&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="c1"&gt;## return age of the animal
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_dead&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="c1"&gt;## return the colour of the animal
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Every animal will have both of these methods. So, we want every animal to implement these methods whenever we are inheriting an animal class from the &lt;code&gt;Animal&lt;/code&gt; class. We cannot have an animal that doesn't support any of these methods. [Rule 1]&lt;/li&gt;
&lt;li&gt;Whenever we see an animal, we call it a dog/cat/duck/tiger. These are all kinds of &lt;strong&gt;animals&lt;/strong&gt;. That is, you never look at something purple and furry and say "that is an animal and there is a no more specific way of defining it". The point is, that you can never see an animal walking around that isn't more specifically something else (duck, pig, etc.) [Rule 2]&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Rules
&lt;/h2&gt;

&lt;p&gt;By using these 2 rules we can make our code more maintainable and programmer-friendly&lt;/p&gt;

&lt;h3&gt;
  
  
  Rule 1
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Subclasses inherited from a specific base class must implement all the methods and properties defined in the abstract base class.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Rule 2
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Abstract base classes cannot be instantiated. They are inherited by the other subclasses.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Implementation in Python
&lt;/h2&gt;

&lt;p&gt;Let's try to implement these animal classes in Python with the rules we talked about.&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;Animal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_age&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# return the animal's age
&lt;/span&gt;        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nb"&gt;NotImplementedError&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;is_dead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# check if animal is dead or alive
&lt;/span&gt;        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nb"&gt;NotImplementedError&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;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Animal&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;bark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"whoof whoof!!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_age&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"5 years"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;In the above program, we are creating a &lt;code&gt;Dog&lt;/code&gt; class that is inheriting all the methods from the &lt;code&gt;Animal&lt;/code&gt; class. Let's see if rule 1 is followed. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rule 1: Subclasses inherited from a specific base class must implement all the methods and properties defined in the abstract base class.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's create an object of the &lt;code&gt;Dog&lt;/code&gt; class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;bulldog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;bulldog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_age&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 5 years
&lt;/span&gt;
&lt;span class="n"&gt;bulldog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_dead&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# NotImplementedError
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The subclass &lt;code&gt;Dog&lt;/code&gt; does not implement the &lt;code&gt;is_dead&lt;/code&gt; method of the &lt;code&gt;Animal&lt;/code&gt; base class and when we try to call this method from the bulldog object we get an error. So this works as expected. But we can run the program successfully if we don't call this method without even a warning for breaking this rule. Ideally, all the methods of the base class should be implemented by the subclass.&lt;/p&gt;

&lt;p&gt;** The above program does not follow Rule 1.**&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rule 2: Abstract base classes cannot be instantiated. They are inherited by the other subclasses.&lt;br&gt;
Let's check if Rule 2 is followed. Let's try to instantiate the base class.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_age&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# NotImplementedError
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We get the error if we try to call the base class' method. But, we can instantiate the base class. &lt;br&gt;
&lt;strong&gt;So, the above program doesn't follow Rule 2&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;code&gt;abc&lt;/code&gt; module to the rescue
&lt;/h2&gt;

&lt;p&gt;With Python's &lt;code&gt;abc&lt;/code&gt; module, we can do better and make sure that both the rules are followed.&lt;br&gt;
Let's update the above program&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&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;Animal&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="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_age&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&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="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_dead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&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;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Animal&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;bark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"whoof whoof!!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_age&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"5 years"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


    &lt;span class="c1"&gt;# we forgot to declare "is_dead" again
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above program, we have imported the helper class &lt;code&gt;ABC&lt;/code&gt; from the module &lt;code&gt;abc&lt;/code&gt; through which we have implemented the base class. Also, we have used the decorator &lt;code&gt;@abstractmethod&lt;/code&gt; for all the methods in our base class.&lt;/p&gt;

&lt;p&gt;Let's try to instantiate our subclass: &lt;code&gt;Dog&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;bulldog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TypeError: Can't instantiate abstract class Dog with abstract methods is_dead
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time we get a &lt;code&gt;TypeError&lt;/code&gt; specifying that the abstract method is not implemented.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This follows Rule 1 successfully.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's try to instantiate our base class: &lt;code&gt;Animal&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TypeError: Can't instantiate abstract class Animal with abstract methods get_age, is_dead
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time we get a &lt;code&gt;TypeError&lt;/code&gt; specifying that the abstract class cannot be instantiated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This follows Rule 2 successfully.&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;Using ABCs in your code will make your class hierarchies more robust and more readily maintainable. Some of the key takeaways in this article are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Abstract e Classes(ABCs) ensure that derived classes implement the particular methods from the base class at instantiation time.&lt;/li&gt;
&lt;li&gt;Using ABCs can help in writing bug-free class hierarchies which are easy to read and maintain.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>oop</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
