<?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: chaitdwivedi</title>
    <description>The latest articles on DEV Community by chaitdwivedi (@chaitdwivedi).</description>
    <link>https://dev.to/chaitdwivedi</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%2F232138%2F2e6e7b75-ab11-4a91-a46d-0e62816880b9.png</url>
      <title>DEV Community: chaitdwivedi</title>
      <link>https://dev.to/chaitdwivedi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chaitdwivedi"/>
    <language>en</language>
    <item>
      <title>Pretty print JSON on command line</title>
      <dc:creator>chaitdwivedi</dc:creator>
      <pubDate>Thu, 27 Jul 2023 02:17:28 +0000</pubDate>
      <link>https://dev.to/chaitdwivedi/pretty-print-json-on-command-line-26ji</link>
      <guid>https://dev.to/chaitdwivedi/pretty-print-json-on-command-line-26ji</guid>
      <description>&lt;p&gt;Use python to pretty print JSON on command line using &lt;a href="https://docs.python.org/3/library/json.html#module-json.tool"&gt;json&lt;/a&gt; std library module&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python -m json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo '{"foo": "bar", "baz": [1, 2, 3]}' | python -m json.tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "foo": "bar",
    "baz": [
        1,
        2,
        3
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
      <category>unix</category>
      <category>json</category>
    </item>
    <item>
      <title>Swap Base class methods in Python</title>
      <dc:creator>chaitdwivedi</dc:creator>
      <pubDate>Wed, 26 Jul 2023 16:39:00 +0000</pubDate>
      <link>https://dev.to/chaitdwivedi/swap-base-class-methods-in-python-4ip1</link>
      <guid>https://dev.to/chaitdwivedi/swap-base-class-methods-in-python-4ip1</guid>
      <description>&lt;h2&gt;
  
  
  Problem Statement
&lt;/h2&gt;

&lt;p&gt;Recently I came across this problem where I had to "swap" out a function in a Base class.&lt;/p&gt;

&lt;p&gt;I had a base class &lt;code&gt;Base&lt;/code&gt; and a bunch of derived classes: &lt;code&gt;Derived0..N&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;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customs&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="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;base_func&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="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;'Printing from base: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Derived0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;#
#
#
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DerivedN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Base&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;I wanted some of the derived classes to use a custom function instead of the &lt;code&gt;base_func&lt;/code&gt;, i.e. override the functionality.&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;custom_func&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="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;'Printing from fancy custom func: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a&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;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;Ideally, I should have simply overridden the Base class function, but I did not want to write the same implementation for each derived class. &lt;/p&gt;

&lt;p&gt;Instead, I updated the base class to accept a way to override a member function, and let the derived classes pass along their implementation to swap out base functionality.&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;functools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customs&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="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;customs&lt;/span&gt; &lt;span class="ow"&gt;or&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;func_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customs&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="n"&gt;current_func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;getattr&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="n"&gt;func_name&lt;/span&gt;&lt;span class="p"&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="nb"&gt;callable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current_func&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; 
        &lt;span class="nb"&gt;setattr&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="n"&gt;func_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&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;base_func&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="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;'Printing from base: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="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;Call changed to:&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="n"&gt;Derived0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'base_func'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;custom_func&lt;/span&gt;&lt;span class="p"&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;base_func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Printing from fancy custom func: self.a=5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use of partial
&lt;/h3&gt;

&lt;p&gt;I used &lt;a href="https://docs.python.org/3/library/functools.html"&gt;functools.partial&lt;/a&gt; to bind the function call with the object it will be called with, when called via derived class. &lt;/p&gt;

&lt;h3&gt;
  
  
  Use of self in custom function
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;self&lt;/code&gt; will be required in the custom function to allow access to other attributes of that object. &lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>oop</category>
    </item>
    <item>
      <title>How to modify a string in Python</title>
      <dc:creator>chaitdwivedi</dc:creator>
      <pubDate>Mon, 22 Nov 2021 22:07:32 +0000</pubDate>
      <link>https://dev.to/chaitdwivedi/how-to-modify-a-string-in-python-3lkg</link>
      <guid>https://dev.to/chaitdwivedi/how-to-modify-a-string-in-python-3lkg</guid>
      <description>&lt;p&gt;You cannot!&lt;/p&gt;

&lt;p&gt;Strings in Python are immutable (something that cannot be changed)&lt;/p&gt;

&lt;h2&gt;
  
  
  Why are Python strings immutable?
&lt;/h2&gt;

&lt;p&gt;Read &lt;a href="https://docs.python.org/3/faq/design.html#why-are-python-strings-immutable"&gt;here&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  What can you do?
&lt;/h2&gt;

&lt;p&gt;You can create a new modified string. &lt;/p&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Convert all characters to upper case
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"My String"&lt;/span&gt; 
&lt;span class="n"&gt;new_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&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;new_string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# "MY STRING"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Change one character
&lt;/h3&gt;

&lt;p&gt;Since you can't really change the string, the solution is to convert it a mutable type like &lt;code&gt;list&lt;/code&gt; and modify that.&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;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"My String"&lt;/span&gt; 
&lt;span class="n"&gt;original_list&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;original&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;original_list&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;'m'&lt;/span&gt; 
&lt;span class="n"&gt;new_string&lt;/span&gt; &lt;span class="o"&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;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;original_list&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;new_string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 'my String' 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;You could also try slicing to speed up the process&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>Guiding Principles for Writing Documentation</title>
      <dc:creator>chaitdwivedi</dc:creator>
      <pubDate>Tue, 09 Nov 2021 22:08:22 +0000</pubDate>
      <link>https://dev.to/chaitdwivedi/guiding-principles-for-writing-documentation-169n</link>
      <guid>https://dev.to/chaitdwivedi/guiding-principles-for-writing-documentation-169n</guid>
      <description>&lt;p&gt;Your documentation should be:&lt;/p&gt;

&lt;h2&gt;
  
  
  👥 Inclusive and clear
&lt;/h2&gt;

&lt;p&gt;Write docs in an inclusive and clear manner. Your language should be easy to understand and inviting. Try not to make assumptions about user's base level knowledge. &lt;/p&gt;

&lt;p&gt;Easy to read documentation is an easy way to increase number of users and contributors to your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Complete
&lt;/h2&gt;

&lt;p&gt;Describe all aspects of your project. Try to document all of the common use cases. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Support queries are usually holes in your documentation. If you find yourself answering to questions about your project, which could have been 'searched', you should add that to your documentation. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ✨ Up-to-date
&lt;/h2&gt;

&lt;p&gt;This is particularly hard. Outdated documentation might cause more harm than no documentation at all. &lt;/p&gt;

&lt;p&gt;For Python projects, &lt;a href="https://dev.to/chaitdwivedi/documenting-your-way-to-better-tests-in-python-h5n"&gt;doctests&lt;/a&gt; does help to a certain extent in keeping documentation up-to-date, but really the onus of maintaining the docs lies on the developer. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Adding documentation as a measure of completeness of coding tasks is very helpful. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  💻 Easy to contribute
&lt;/h2&gt;

&lt;p&gt;Add clear instructions on how to contribute to your project. This may include coding guidelines and standards, running test suites etc. &lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 Easy to find
&lt;/h2&gt;

&lt;p&gt;If working on "inner source" projects, make sure your project is searchable within your organization. Some companies use Confluence/Sharepoint to host docs, you may be able to keep a static landing page that may point to your project's homepage, which might be generated dynamically.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Essentials of README</title>
      <dc:creator>chaitdwivedi</dc:creator>
      <pubDate>Wed, 03 Nov 2021 22:23:35 +0000</pubDate>
      <link>https://dev.to/chaitdwivedi/essentials-of-readme-3i79</link>
      <guid>https://dev.to/chaitdwivedi/essentials-of-readme-3i79</guid>
      <description>&lt;p&gt;&lt;code&gt;README.md&lt;/code&gt; is a minimum qualifying requirement to call a project well documented. It is basically an introduction to your project. &lt;/p&gt;

&lt;p&gt;A &lt;code&gt;README&lt;/code&gt; file typically written in &lt;a href="https://github.com/adam-p/markdown-here/wiki/Markdown-Here-Cheatsheet"&gt;Markdown&lt;/a&gt; and contains: &lt;/p&gt;

&lt;h2&gt;
  
  
  📋 Summary
&lt;/h2&gt;

&lt;p&gt;A short description of the problem the project solves. &lt;/p&gt;

&lt;h2&gt;
  
  
  🌟 Key Features
&lt;/h2&gt;

&lt;p&gt;A list of features that make your project great at solving the given problem. &lt;/p&gt;

&lt;h2&gt;
  
  
  ▶️ Getting Started
&lt;/h2&gt;

&lt;p&gt;This section is basically a usage guide. Include installation and usage instructions here. &lt;/p&gt;

&lt;p&gt;This is also a good place to add some code examples as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  💻 Contribution Notes
&lt;/h2&gt;

&lt;p&gt;Discuss coding style and guidelines. Include steps to run test suite and introduce the contributor to any CI validation (if already setup)&lt;/p&gt;

&lt;h2&gt;
  
  
  ❗ Support
&lt;/h2&gt;

&lt;p&gt;List ways in which your end users can seek help. Email, Slack and JIRA are some good ways of allowing your users and developers to file bugs and ask for help. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Focus on building a community of expert users and developers, so that you don't have to support your project all the time.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ©️ License
&lt;/h2&gt;

&lt;p&gt;Read about licenses &lt;a href="https://choosealicense.com"&gt;here&lt;/a&gt;. &lt;/p&gt;




&lt;p&gt;I found a collection of &lt;a href="https://github.com/matiassingers/awesome-readme"&gt;awesome-readmes&lt;/a&gt; which you might enjoy as well! &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>documentation</category>
    </item>
    <item>
      <title>Why write documentation for your projects</title>
      <dc:creator>chaitdwivedi</dc:creator>
      <pubDate>Tue, 02 Nov 2021 22:06:55 +0000</pubDate>
      <link>https://dev.to/chaitdwivedi/why-write-documentation-for-your-projects-4hpo</link>
      <guid>https://dev.to/chaitdwivedi/why-write-documentation-for-your-projects-4hpo</guid>
      <description>&lt;h2&gt;
  
  
  💰 Reduce future development effort
&lt;/h2&gt;

&lt;p&gt;Lack of proper documentation is one of the main reasons why developers rewrite a project/tool. Instead of putting in the effort to understand the code is old now, they just prefer to write new code from scratch. &lt;/p&gt;

&lt;p&gt;Documentation helps future you and other developers contributing/building upon your project. &lt;/p&gt;

&lt;h2&gt;
  
  
  📢 Marketing your project
&lt;/h2&gt;

&lt;p&gt;You want people to use your project. For that to happen, people need to first understand: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why your project is useful &lt;/li&gt;
&lt;li&gt;What problems does it solve&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Documentation for your project helps you address these questions. &lt;/p&gt;

&lt;h2&gt;
  
  
  ⭐ Building your personal brand
&lt;/h2&gt;

&lt;p&gt;Within an organization or in the open source community, good documentation can make your work look very professional and outstanding. Users start to associate your name with good documentation if you keep up the practice. &lt;/p&gt;

&lt;h2&gt;
  
  
  👥 Collaboration
&lt;/h2&gt;

&lt;p&gt;One of the cornerstones of improving code base in open source community or even "inner source" (for proprietary software) is collaboration. Easiest way to invite others to collaborate is by allowing them to make "less intimidating" doc changes. &lt;/p&gt;

&lt;p&gt;Contributions from community are aligned with original intentions of the author if the code is well documented. &lt;/p&gt;

&lt;h2&gt;
  
  
  ⬆️ Improve Code quality
&lt;/h2&gt;

&lt;p&gt;Thinking about documentation along with writing code enables you to make good design decisions. If you are unable to define what a module or function does in simple language, you probably need to rethink about the logic. &lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>beginners</category>
      <category>documentation</category>
    </item>
    <item>
      <title>Rename multiple files with vim and sed</title>
      <dc:creator>chaitdwivedi</dc:creator>
      <pubDate>Fri, 28 May 2021 22:31:56 +0000</pubDate>
      <link>https://dev.to/chaitdwivedi/rename-multiple-files-with-vim-and-sed-10a6</link>
      <guid>https://dev.to/chaitdwivedi/rename-multiple-files-with-vim-and-sed-10a6</guid>
      <description>&lt;p&gt;There are multiple ways to rename a bunch of files in a programmatic manner in Unix-based systems. Here, I will talk about 2 possible ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using vim (a little long winded - but good to build understanding)&lt;/li&gt;
&lt;li&gt;Shell one liner - using &lt;code&gt;sed&lt;/code&gt; and &lt;code&gt;xargs&lt;/code&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Suppose you have a directory with some &lt;code&gt;.html&lt;/code&gt; files that you want to rename to &lt;code&gt;.htm&lt;/code&gt; and add a suffix (&lt;code&gt;generated&lt;/code&gt;) to the base name.&lt;/p&gt;

&lt;p&gt;You want to do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mv &lt;/span&gt;file.html file-generated.htm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Using vim
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Create a list of files
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;ls&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt; to create a list files to update:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;html &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; exec_me 
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;exec_me

genindex.html
index.html
py-modindex.html
search.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Search and replace to generate commands to execute
&lt;/h2&gt;

&lt;p&gt;The idea is to generate a list of commands that can be executed from the command line to get the desired result. &lt;/p&gt;

&lt;p&gt;Perform &lt;a href="https://vim.fandom.com/wiki/Search_and_replace"&gt;search and replace&lt;/a&gt; in &lt;code&gt;vim&lt;/code&gt;'s command mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;%s&lt;span class="sr"&gt;/\(.*\)\.html/&lt;/span&gt;mv \&lt;span class="m"&gt;1&lt;/span&gt;\&lt;span class="p"&gt;.&lt;/span&gt;html \&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;generated&lt;span class="p"&gt;.&lt;/span&gt;htm/&lt;span class="k"&gt;g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;\1&lt;/code&gt; allows access to data captured in group - &lt;code&gt;\(.*\)&lt;/code&gt;. Read about vim modes in &lt;a href="https://www.freecodecamp.org/news/vim-editor-modes-explained/"&gt;vim modes explained&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which should change your file list text to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mv genindex.html genindex-generated.htm
mv index.html index-generated.htm
mv py-modindex.html py-modindex-generated.htm
mv search.html search-generated.htm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save, quit and execute your file!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod 700 exec_me
./exec_me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Using sed and xargs
&lt;/h1&gt;

&lt;p&gt;This technique is very similar to the vim style, except we don't create a new file - but create and execute commands on-the-fly using &lt;a href="https://man7.org/linux/man-pages/man1/xargs.1.html"&gt;&lt;code&gt;xargs&lt;/code&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;html | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/\(.*\)\.html/\1\.html \1-generated\.htm/g'&lt;/span&gt; | xargs &lt;span class="nt"&gt;-L1&lt;/span&gt; &lt;span class="nb"&gt;mv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Scripting in shell is awesome and powerful, but also dangerous. It is like having a shotgun with no one stopping you from shooting yourself in the foot. Have fun with it but don't go deleting your entire code base!&lt;/p&gt;

</description>
      <category>vim</category>
      <category>sed</category>
      <category>shell</category>
      <category>scripting</category>
    </item>
    <item>
      <title>Documenting your way to better tests in Python</title>
      <dc:creator>chaitdwivedi</dc:creator>
      <pubDate>Fri, 14 May 2021 04:42:28 +0000</pubDate>
      <link>https://dev.to/chaitdwivedi/documenting-your-way-to-better-tests-in-python-h5n</link>
      <guid>https://dev.to/chaitdwivedi/documenting-your-way-to-better-tests-in-python-h5n</guid>
      <description>&lt;h2&gt;
  
  
  Writing and Reading Code
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Writing code is hard, reading code is harder&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I participate in a lot of code reviews and one thing I've realized is - developers spend most of their time coding a solution, not enough time explaining it. &lt;/p&gt;

&lt;p&gt;There are two ways you could explain how your code works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write simple code that is self-explanatory&lt;/li&gt;
&lt;li&gt;Write "good" documentation&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Value of Good Documentation
&lt;/h2&gt;

&lt;p&gt;In this post, I am going to make a case for how writing good documentation can improve the quality of your code and should be done &lt;strong&gt;along with&lt;/strong&gt; writing self-explanatory code. &lt;/p&gt;

&lt;p&gt;Let me illustrate with an example.&lt;/p&gt;

&lt;p&gt;I've defined &lt;code&gt;my_function&lt;/code&gt; below, that computes some "arbitrary" logic:&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;my_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input_list&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="n"&gt;head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Start:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;input_list&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;input_string&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;tail&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;input_string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;head&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;input_string&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;tail&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;In a real-world problem, this piece of code might be much more complex. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As a reader, you could read this code and understand what it is doing. However, I can make the reader's job easier by using &lt;a href="https://www.python.org/dev/peps/pep-0257/#what-is-a-docstring" rel="noopener noreferrer"&gt;docstring&lt;/a&gt;.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Docstrings: Make code easy to read
&lt;/h2&gt;

&lt;p&gt;Docstring holds immense value when developing code in a large organization and/or in a collaborative community. &lt;/p&gt;

&lt;p&gt;It lets any developer understand what's happening in the function/module without them having to read through the entire codebase. &lt;/p&gt;

&lt;p&gt;It can also be used with tools like &lt;a href="https://www.sphinx-doc.org/en/master/" rel="noopener noreferrer"&gt;sphinxdoc&lt;/a&gt; to generate beautiful documentation for your project.&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;my_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input_list&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="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Sanitize input string and append extra text if required

    The function checks if input_string starts with &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Start:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; 
    if not, it will add the string to the input_string 

    It also converts input_list to a string using join 
    and appends to the input_string
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Start:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;input_list&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;input_string&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;tail&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;input_string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;head&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;input_string&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;tail&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docstring in the above code explains what the code is doing, but it still feels like a repetition of what is written in the code block. &lt;/p&gt;

&lt;p&gt;How do we improve this?&lt;br&gt;
Using &lt;a href="https://docs.python.org/3/library/doctest.html" rel="noopener noreferrer"&gt;doctest&lt;/a&gt;! &lt;/p&gt;
&lt;h2&gt;
  
  
  Doctest: Read, Test and Document better
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.python.org/3/library/doctest.html" rel="noopener noreferrer"&gt;doctest&lt;/a&gt; allows you to not only test interactive Python examples but also makes sure your documentation is up to date.&lt;/p&gt;

&lt;p&gt;Let us take a look at improved &lt;code&gt;docstring&lt;/code&gt; for the same function using &lt;code&gt;doctest&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;my_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input_list&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="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Sanitize input string and append extra text if required
&lt;/span&gt;&lt;span class="gp"&gt;
    &amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;my_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;hi&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Start: hi&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="gp"&gt;    &amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;my_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Start: some string&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Start: some string&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="gp"&gt;    &amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;my_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;hi&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;other&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;item&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Start: hi other item&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="s"&gt;    :param input_string: string to sanitize
    :type input_string: str
    :param input_list: extra items to append, defaults to None
    :type input_list: list, optional
    :return: sanitized string
    :rtype: str
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Start:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;input_list&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;input_string&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;tail&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;input_string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;head&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;input_string&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;tail&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, I have defined some input-output examples for the given function which illustrate what the function is doing. For instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;my_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;hi&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;other&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;item&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;should return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Start: hi other item&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above documentation tells developers/readers the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What the function does&lt;/li&gt;
&lt;li&gt;Parameters and their types &lt;/li&gt;
&lt;li&gt;Return value and its type &lt;/li&gt;
&lt;li&gt;Expected behavior - describes input/output examples&lt;/li&gt;
&lt;/ul&gt;




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

&lt;h3&gt;
  
  
  Generating documentation
&lt;/h3&gt;

&lt;p&gt;I used &lt;a href="https://www.sphinx-doc.org/en/master/" rel="noopener noreferrer"&gt;sphinxdoc&lt;/a&gt; to generate documentation for the above function:&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Practicing TDD
&lt;/h3&gt;

&lt;p&gt;Writing documentation in Python also allows me to follow Test Driven Development, where I first define the behavior in &lt;code&gt;docstring&lt;/code&gt; then write the code. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;doctest&lt;/code&gt; can be run by any testing framework like &lt;code&gt;unittest&lt;/code&gt; or &lt;code&gt;pytest&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pytest &lt;span class="nt"&gt;--doctest-modules&lt;/span&gt; &lt;span class="nt"&gt;-vv&lt;/span&gt; top.py
&lt;span class="o"&gt;===================&lt;/span&gt; &lt;span class="nb"&gt;test &lt;/span&gt;session starts &lt;span class="o"&gt;======================&lt;/span&gt;
platform darwin &lt;span class="nt"&gt;--&lt;/span&gt; Python 3.8.2, pytest-6.2.4 
&lt;span class="nt"&gt;--&lt;/span&gt; /projects/virtualenvs/dev-to/bin/python3
cachedir: .pytest_cache
rootdir: /Users/chaitanyadwivedi/projects/dev-to
collected 1 item                                                                                                                                           

top.py::top.my_function PASSED                          &lt;span class="o"&gt;[&lt;/span&gt;100%]

&lt;span class="o"&gt;====================&lt;/span&gt; 1 passed &lt;span class="k"&gt;in &lt;/span&gt;0.05s &lt;span class="o"&gt;=======================&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
      <category>tdd</category>
      <category>documentation</category>
      <category>docstring</category>
    </item>
    <item>
      <title>How to fix dictionary access bugs in Python</title>
      <dc:creator>chaitdwivedi</dc:creator>
      <pubDate>Fri, 09 Apr 2021 05:50:21 +0000</pubDate>
      <link>https://dev.to/chaitdwivedi/how-to-fix-dictionary-access-bugs-in-python-16ph</link>
      <guid>https://dev.to/chaitdwivedi/how-to-fix-dictionary-access-bugs-in-python-16ph</guid>
      <description>&lt;p&gt;In this post I am going to discuss how accessing a value in a &lt;code&gt;dict&lt;/code&gt; can easily introduce a bug in your code and how to fix it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Access
&lt;/h1&gt;

&lt;p&gt;One of the most common scenarios with dictionaries is accessing a value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;my_dict&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problem&lt;/strong&gt;: If &lt;code&gt;key&lt;/code&gt; doesn't exist in &lt;code&gt;my_dict&lt;/code&gt;, the code will raise a &lt;code&gt;KeyError&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: To avoid this scenario you have three options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Check if &lt;code&gt;key&lt;/code&gt; exists before accessing&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
    &lt;span class="k"&gt;if&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;my_dict&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;my_dict&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;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Wrap the access in &lt;code&gt;try-except&lt;/code&gt; block&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
    &lt;span class="k"&gt;try&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;my_dict&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="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;KeyError&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;/li&gt;
&lt;li&gt;
&lt;p&gt;Use Python's &lt;a href="https://docs.python.org/3/library/stdtypes.html#dict.get"&gt;get&lt;/a&gt; function to avoid checking for &lt;code&gt;key&lt;/code&gt; in &lt;code&gt;dict&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
    &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;my_dict&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&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;/code&gt;&lt;/pre&gt;

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

&lt;p&gt;Since, &lt;code&gt;get&lt;/code&gt; option (3) looks the neatest, I tend to use that the most. &lt;/p&gt;

&lt;p&gt;Now, suppose for a function I am writing, I am accessing a value from &lt;code&gt;dict&lt;/code&gt; but I only want to proceed if the given key exists in the &lt;code&gt;dict&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;I would write something 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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;my_dict&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&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="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;MyError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Found bad key'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# continue with code 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, the code looks fine, but I have introduced a bug in it. &lt;/p&gt;

&lt;p&gt;Let me illustrate with an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Assume my_dict as:
&lt;/span&gt;&lt;span class="n"&gt;my_dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;'key1'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'value1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;'key3'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;th&gt;Expected?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;key1&lt;/td&gt;
&lt;td&gt;Regular code execution&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;key2&lt;/td&gt;
&lt;td&gt;raises &lt;code&gt;MyError&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;key3&lt;/td&gt;
&lt;td&gt;raises &lt;code&gt;MyError&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;key2&lt;/code&gt; raises the exception since &lt;code&gt;get&lt;/code&gt; function will return &lt;code&gt;None&lt;/code&gt; by default for non-existing keys. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;key3&lt;/code&gt; exists in the &lt;code&gt;dict&lt;/code&gt; however my code will still throw an error because &lt;code&gt;if not []&lt;/code&gt; is also &lt;code&gt;True&lt;/code&gt;, leading to unintentional behavior. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick Bad Fix
&lt;/h2&gt;

&lt;p&gt;Reading points about &lt;code&gt;key2&lt;/code&gt; and &lt;code&gt;key3&lt;/code&gt; from above, modifying the validation condition seems like the most obvious fix:&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;my_dict&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&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="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;MyError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Found bad key'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This, however, only fixes one symptom/effect of the bug that is when the value is an empty data type like &lt;code&gt;''&lt;/code&gt; or &lt;code&gt;[]&lt;/code&gt;. If the value in &lt;code&gt;my_dict&lt;/code&gt; is &lt;code&gt;None&lt;/code&gt; the above code will still raise the error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fix
&lt;/h2&gt;

&lt;p&gt;Before writing a fix for your code, it is usually a good idea to think about the root cause of the bug, rather than the symptoms that are showing up. In our case, it was not the &lt;code&gt;if&lt;/code&gt; condition that was causing the bug - it was the &lt;code&gt;get&lt;/code&gt; function. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I only want to proceed if the given key exists in the &lt;code&gt;dict&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To encode the described behavior the correct code block would look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&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;my_dict&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;my_dict&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="c1"&gt;# rest of code
&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;MyError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Found bad key'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Learning
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Capturing intent is critical in writing robust code.&lt;/li&gt;
&lt;li&gt;First step to fixing bugs should be to list assumptions and work from there.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>dict</category>
      <category>debugging</category>
    </item>
  </channel>
</rss>
