<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Best Practice | Haobin Tan</title><link>https://haobin-tan.netlify.app/tags/best-practice/</link><atom:link href="https://haobin-tan.netlify.app/tags/best-practice/index.xml" rel="self" type="application/rss+xml"/><description>Best Practice</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Wed, 11 May 2022 00:00:00 +0000</lastBuildDate><image><url>https://haobin-tan.netlify.app/media/icon_hu7d15bc7db65c8eaf7a4f66f5447d0b42_15095_512x512_fill_lanczos_center_3.png</url><title>Best Practice</title><link>https://haobin-tan.netlify.app/tags/best-practice/</link></image><item><title>Best Practices</title><link>https://haobin-tan.netlify.app/docs/coding/docker/docker-best-practices/</link><pubDate>Tue, 05 Apr 2022 00:00:00 +0000</pubDate><guid>https://haobin-tan.netlify.app/docs/coding/docker/docker-best-practices/</guid><description/></item><item><title>Beautiful Python Code with PEP 8</title><link>https://haobin-tan.netlify.app/docs/coding/python/best-practice/beautiful-py-code-with-pep8/</link><pubDate>Mon, 06 Jul 2020 00:00:00 +0000</pubDate><guid>https://haobin-tan.netlify.app/docs/coding/python/best-practice/beautiful-py-code-with-pep8/</guid><description>&lt;p>Source: &lt;a href="https://realpython.com/python-pep8/">How to Write Beautiful Python Code With PEP 8&lt;/a>&lt;/p>
&lt;h2 id="naming-conventions">Naming Conventions&lt;/h2>
&lt;blockquote>
&lt;p>“Explicit is better than implicit.”
— The Zen of Python&lt;/p>
&lt;/blockquote>
&lt;p>‼️ Note: Never use l (\ell), O (zero), or I (capital i) single letter names as these can be mistaken for 1 and 0, depending on typeface:&lt;/p>
&lt;h3 id="naming-styles">Naming styles&lt;/h3>
&lt;p>&lt;img src="https://raw.githubusercontent.com/EckoTan0804/upic-repo/master/uPic/Untitled.png" alt="Beautiful%20Python%20Code%20with%20PEP%208%20ad6a9a89c353410c813a83ebda6504c3/Untitled.png">&lt;/p>
&lt;h3 id="how-to-choose-names">How to choose names&lt;/h3>
&lt;p>The best way to name your objects in Python is to use &lt;strong>descriptive&lt;/strong> names to make it clear what the object represents.&lt;/p>
&lt;p>&lt;strong>Always try to use the most concise but descriptive names possible.&lt;/strong>&lt;/p>
&lt;p>❌&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Not recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;gt;&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;John Smith&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;gt;&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">z&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">split&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;gt;&amp;gt;&amp;gt;&lt;/span> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">z&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">sep&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;, &amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">&amp;#39;Smith, John&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>✅&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;gt;&amp;gt;&amp;gt;&lt;/span> &lt;span class="c1"># Recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;gt;&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">name&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;John Smith&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;gt;&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">first_name&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">last_name&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">name&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">split&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;gt;&amp;gt;&amp;gt;&lt;/span> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">last_name&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">first_name&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">sep&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;, &amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">&amp;#39;Smith, John&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="code-layout">Code Layout&lt;/h2>
&lt;blockquote>
&lt;p>“Beautiful is better than ugly.”
— The Zen of Python&lt;/p>
&lt;/blockquote>
&lt;h3 id="blank-lines">Blank lines&lt;/h3>
&lt;p>&lt;strong>Surround top-level functions and classes with two blank lines&lt;/strong>&lt;/p>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">MyFirstClass&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">pass&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">MySecondClass&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">pass&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">top_level_function&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">None&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Surround method definitions inside classes with a single blank line.&lt;/strong>&lt;/p>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">first_method&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="bp">self&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">None&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">second_method&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="bp">self&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">None&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>Use blank lines sparingly inside functions to show clear steps.&lt;/strong>&lt;/p>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">calculate_variance&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">number_list&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sum_list&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">number&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">number_list&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sum_list&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">sum_list&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">number&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">mean&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">sum_list&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">number_list&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sum_squares&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">number&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">number_list&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sum_squares&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">sum_squares&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">number&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="mi">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">mean_squares&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">sum_squares&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">number_list&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">mean_squares&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">mean&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="mi">2&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="maximum-line-length-and-line-breaking">Maximum Line Length and Line Breaking&lt;/h3>
&lt;p>&lt;strong>Lines should be limited to 79 characters.&lt;/strong>&lt;/p>
&lt;p>Outlines ways to allow statements to run over several lines:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>Assume line continuation if code is contained within parentheses, brackets, or braces:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">function&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">arg_one&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">arg_two&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">arg_three&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">arg_four&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">arg_one&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>&lt;strong>Use backslashes to break lines if it is impossible to use implied continuation:&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">mypkg&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">example1&lt;/span>&lt;span class="p">,&lt;/span> \\
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">example2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">example3&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>&lt;strong>if you can use implied continuation, then you should do so.&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>If line breaking needs to occur around binary operators, like + and *, it should occur &lt;strong>before&lt;/strong> the operator&lt;/p>
&lt;p>❌&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Not Recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">total&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">first_variable&lt;/span> &lt;span class="o">+&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">second_variable&lt;/span> &lt;span class="o">-&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">third_variable&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>✅&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">total&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">first_variable&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">+&lt;/span> &lt;span class="n">second_variable&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">-&lt;/span> &lt;span class="n">third_variable&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="indentation">Indentation&lt;/h2>
&lt;ul>
&lt;li>Use &lt;strong>4&lt;/strong> consecutive spaces to indicate indentation.&lt;/li>
&lt;li>Prefer &lt;strong>spaces over tabs&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;h3 id="indentation-following-line-breaks">Indentation Following Line Breaks&lt;/h3>
&lt;p>When you’re using line continuations to keep lines to under 79 characters, it is useful to use indentation to improve readability. It allows the reader to &lt;strong>distinguish between two lines of code and a single line of code that spans two lines.&lt;/strong>&lt;/p>
&lt;p>There are two styles of indentation you can use:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>align the indented block with the opening delimiter:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl"> &lt;span class="k">def&lt;/span> &lt;span class="nf">function&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">arg_one&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">arg_two&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">arg_three&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">arg_four&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">arg_one&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Sometimes only 4 spaces are needed to align with the opening delimiter. This will often occur in if statements that span multiple lines as the &lt;code>if&lt;/code>, space, and opening bracket make up 4 characters. In this case, it can be difficult to determine where the nested code block inside the if statement begins:&lt;/p>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">5&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">3&lt;/span> &lt;span class="ow">and&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">10&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In this case, PEP 8 provides two alternatives to help improve readability:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Add a comment after the final condition.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">5&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">3&lt;/span> &lt;span class="ow">and&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">10&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Both conditions satisfied&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Add extra indentation on the line continuation:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">5&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">3&lt;/span> &lt;span class="ow">and&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">10&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>hanging indent&lt;/strong>: You can use a hanging indent to visually represent a continuation of a line of code.&lt;/p>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">var&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">function&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">arg_one&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">arg_two&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">arg_three&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">arg_four&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>‼️ When you’re using a hanging indent, &lt;strong>there must not be any arguments on the first line&lt;/strong>.
The following example is &lt;strong>not&lt;/strong> PEP 8 compliant:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">var&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">function&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">arg_one&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">arg_two&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">arg_three&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">arg_four&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>
&lt;p>When using a hanging indent, &lt;strong>add extra indentation&lt;/strong> to distinguish the continued line from code contained inside the function.&lt;/p>
&lt;p>❌&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Not Recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">function&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">arg_one&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">arg_two&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">arg_three&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">arg_four&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">arg_one&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Instead, it’s better to use a double indent on the line continuation. This helps you to distinguish between function arguments and the function body, improving readability:&lt;/p>
&lt;p>✅&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">function&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">arg_one&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">arg_two&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">arg_three&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">arg_four&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">arg_one&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h3 id="where-to-put-the-closing-brace">Where to Put the Closing Brace&lt;/h3>
&lt;p>Two options for the position of the closing brace in implied line continuations:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Line up the closing brace with the first non-whitespace character of the previous line:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">list_of_numbers&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">4&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">5&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">6&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">7&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">8&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">9&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>Line up the closing brace with the first character of the line that starts the construct:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">list_of_numbers&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">4&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">5&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">6&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="mi">7&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">8&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">9&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Consistency is key, try to stick to one of the above methods.&lt;/strong>&lt;/p>
&lt;h2 id="comments-and-documentations">Comments and Documentations&lt;/h2>
&lt;p>See: &lt;a href="quiver:///notes/CE487BE2-FAC4-4997-A723-244CFC727EA2">Documenting Python Code&lt;/a>&lt;/p>
&lt;h2 id="whitespace-in-expressions-and-statements">Whitespace in Expressions and Statements&lt;/h2>
&lt;blockquote>
&lt;p>“Sparse is better than dense.”— The Zen of Python&lt;/p>
&lt;/blockquote>
&lt;h3 id="whitespace-around-binary-operators">Whitespace Around Binary Operators&lt;/h3>
&lt;p>Surround the following binary operators with a single space on either side:&lt;/p>
&lt;ul>
&lt;li>Assignment operators (&lt;code>=&lt;/code>, &lt;code>+=&lt;/code>, &lt;code>-=&lt;/code>, and so forth)&lt;/li>
&lt;li>Comparisons (&lt;code>==&lt;/code>, &lt;code>!=&lt;/code>, &lt;code>&amp;gt;&lt;/code>, &lt;code>&amp;lt;&lt;/code>. &lt;code>&amp;gt;=&lt;/code>, &lt;code>&amp;lt;=&lt;/code>) and (&lt;code>is&lt;/code>, &lt;code>is not&lt;/code>, &lt;code>in&lt;/code>, &lt;code>not in&lt;/code>)&lt;/li>
&lt;li>Booleans (&lt;code>and&lt;/code>, &lt;code>not&lt;/code>, &lt;code>or&lt;/code>)&lt;/li>
&lt;/ul>
&lt;p>‼️ &lt;strong>Note&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>When &lt;code>=&lt;/code> is used to assign a default value to a function argument, do &lt;strong>NOT&lt;/strong> surround it with spaces.&lt;/p>
&lt;p>✅&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">function&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">default_parameter&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">5&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># ...&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>❌&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Not recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">function&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">default_parameter&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">5&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># ...&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>If there&amp;rsquo;s more than one operator in a statement, &lt;strong>only add whitespace around the operators with the lowest priority&lt;/strong>. especially when performing mathematical manipulation.&lt;/p>
&lt;p>✅&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">y&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="mi">2&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">5&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">z&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>❌&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Not recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">y&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">**&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">5&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">z&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>
&lt;p>Apply this rule to &lt;code>if&lt;/code> statements where there are multiple conditions:&lt;/p>
&lt;p>✅&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="mi">5&lt;/span> &lt;span class="ow">and&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="o">%&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="o">==&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;x is larger than 5 and divisible by 2!&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>❌&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Not recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">5&lt;/span> &lt;span class="ow">and&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;x is larger than 5 and divisible by 2!&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>In slices, colons act as a binary operators. Therefore, the rules outlined in the previous section apply, and there should be the &lt;strong>same amount of whitespace&lt;/strong> either side. The following examples of list slices are valid:&lt;/p>
&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">list&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Treat the colon as the operator with lowest priority&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">list&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="mi">1&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># In an extended slice, both colons must be&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># surrounded by the same amount of whitespace&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">list&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="mi">5&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">list&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="mi">1&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="mi">2&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># The space is omitted if a slice parameter is omitted&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">list&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="mi">1&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="mi">2&lt;/span> &lt;span class="p">:]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;h3 id="summary">Summary&lt;/h3>
&lt;p>Surround most operator with whitespace, except:&lt;/p>
&lt;ul>
&lt;li>in function arguments&lt;/li>
&lt;li>combining multiple operators in one statement&lt;/li>
&lt;/ul>
&lt;h2 id="programming-recommendations">Programming Recommendations&lt;/h2>
&lt;blockquote>
&lt;p>“Simple is better than complex.”— The Zen of Python&lt;/p>
&lt;/blockquote>
&lt;p>🎯 Goal: readability and simplicity&lt;/p>
&lt;h3 id="dont-compare-boolean-values-to-true-or-false-using-the-equivalence-operator">Don’t compare boolean values to &lt;code>True&lt;/code> or &lt;code>False&lt;/code> using the equivalence operator.&lt;/h3>
&lt;p>❌&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Not recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">my_bool&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">6&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">5&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="n">my_bool&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="kc">True&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="s1">&amp;#39;6 is bigger than 5&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>✅&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="n">my_bool&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="s1">&amp;#39;6 is bigger than 5&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="use-the-fact-that-empty-sequences-are-falsy-in-if-statements">Use the fact that empty sequences are falsy in &lt;code>if&lt;/code> statements.&lt;/h3>
&lt;p>In Python any empty list, string, or tuple is &lt;a href="https://docs.python.org/3/library/stdtypes.html#truth-value-testing">falsy&lt;/a>.&lt;/p>
&lt;p>❌&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Not recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">my_list&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">my_list&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;List is empty!&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>✅&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">my_list&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="n">my_list&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;List is empty!&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="use-is-not-rather-than-not--is-in-if-statements">Use &lt;code>is not&lt;/code> rather than &lt;code>not ... is&lt;/code> in &lt;code>if&lt;/code> statements.&lt;/h3>
&lt;p>❌&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Not recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="ow">is&lt;/span> &lt;span class="kc">None&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="s1">&amp;#39;x exists!&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>✅&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="ow">is&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="kc">None&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="s1">&amp;#39;x exists!&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="dont-use-if-x-when-you-mean-if-x-is-not-none">Don’t use &lt;code>if x:&lt;/code> when you mean &lt;code>if x is not None:&lt;/code>.&lt;/h3>
&lt;p>❌&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Not recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="n">arg&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Do something with arg...&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>✅&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="n">arg&lt;/span> &lt;span class="ow">is&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="kc">None&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Do something with arg...&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="use-startswith-and-endswith-instead-of-slicing">Use &lt;code>.startswith()&lt;/code> and &lt;code>.endswith()&lt;/code> instead of slicing.&lt;/h3>
&lt;ul>
&lt;li>
&lt;p>prefix&lt;/p>
&lt;p>❌&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Not recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="n">word&lt;/span>&lt;span class="p">[:&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s1">&amp;#39;cat&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;The word starts with &amp;#34;cat&amp;#34;&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>✅&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="n">word&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">startswith&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;cat&amp;#39;&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;The word starts with &amp;#34;cat&amp;#34;&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>suffix&lt;/p>
&lt;p>❌&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Not recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="n">file_name&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">:]&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s1">&amp;#39;jpg&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;The file is a JPEG&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>✅&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Recommended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="n">file_name&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">endswith&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;jpg&amp;#39;&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;The file is a JPEG&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;h2 id="tips-and-tricks-to-help-ensure-your-code-follows-pep-8">Tips and Tricks to Help Ensure Your Code Follows PEP 8&lt;/h2>
&lt;p>&lt;strong>Never ignore PEP 8!!!&lt;/strong>&lt;/p>
&lt;h3 id="linters">Linters&lt;/h3>
&lt;p>Linters are programs that analyze code and flag errors. They provide suggestions on how to fix the error.&lt;/p>
&lt;p>Best linters for Python code:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>&lt;a href="https://pypi.org/project/pycodestyle/">&lt;code>pycodestyle&lt;/code>&lt;/a>&lt;/strong> is a tool to check your Python code against some of the style conventions in PEP 8.&lt;/p>
&lt;p>Install &lt;code>pycodestyle&lt;/code> using &lt;code>pip&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="err">$&lt;/span> &lt;span class="n">pip&lt;/span> &lt;span class="n">install&lt;/span> &lt;span class="n">pycodestyle&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>&lt;strong>&lt;a href="https://pypi.org/project/flake8/">&lt;code>flake8&lt;/code>&lt;/a>&lt;/strong> is a tool that combines a debugger, &lt;code>pyflakes&lt;/code>, with &lt;code>pycodestyle&lt;/code>.&lt;/p>
&lt;p>Install &lt;code>flake8&lt;/code> using &lt;code>pip&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="err">$&lt;/span> &lt;span class="n">pip&lt;/span> &lt;span class="n">install&lt;/span> &lt;span class="n">flake8&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;h3 id="autoformatters">Autoformatters&lt;/h3>
&lt;p>Autoformatters are programs that refactor your code to conform with PEP 8 automatically. Once such program is &lt;a href="https://pypi.org/project/black/">&lt;code>black&lt;/code>&lt;/a>, which autoformats code following &lt;em>most&lt;/em> of the rules in PEP 8.&lt;/p>
&lt;p>Install &lt;code>black&lt;/code> using &lt;code>pip&lt;/code>. It requires Python 3.6+ to run:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ pip install black
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Documenting Python Code</title><link>https://haobin-tan.netlify.app/docs/coding/python/best-practice/documenting-py-code/</link><pubDate>Mon, 06 Jul 2020 00:00:00 +0000</pubDate><guid>https://haobin-tan.netlify.app/docs/coding/python/best-practice/documenting-py-code/</guid><description>&lt;p>Source: &lt;a href="https://realpython.com/documenting-python-code/">Documenting Python Code: A Complete Guide&lt;/a>&lt;/p>
&lt;h2 id="commenting-vs-documenting-code">Commenting vs. Documenting Code&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;/th>
&lt;th>Description&lt;/th>
&lt;th>Audience&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>Commenting&lt;/strong>&lt;/td>
&lt;td>Purpose and design of code&lt;/td>
&lt;td>Maintainers and developers&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Documenting&lt;/strong>&lt;/td>
&lt;td>Use and functionality of code&lt;/td>
&lt;td>Users&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="commenting-code">Commenting Code&lt;/h2>
&lt;p>Comments are created in Python using the pound sign (&lt;code>#&lt;/code>) and should be &lt;strong>brief statements no longer than a few sentences&lt;/strong>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">hello_world&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># A simple comment preceding a simple print statement&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Hello World!&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>According to &lt;a href="http://pep8.org/#maximum-line-length">PEP 8&lt;/a>, comments should have a &lt;strong>maximum length of 72&lt;/strong> characters. This is true even if your project changes the max line length to be greater than the recommended 80 characters.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">hello_long_world&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># A very long statement that just goes on and on and on and on and&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># never ends until after it&amp;#39;s reached the 80 char limit&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Hellooooooooooooooooooooooooooooooooooooooooooooooooooooooo World&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="purpose-of-commenting-code">Purpose of Commenting Code&lt;/h3>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>Planning and reviewing&lt;/strong>
When developing new portion of code, first use comments as a way of planning or outlineing that section of code. &lt;strong>Remember to remove these comments once the actual coding has been implemented and reviewed/tested&lt;/strong>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">new_function&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Step 1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Step 2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Step 3&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>&lt;strong>Code description&lt;/strong>
Explain the intent of specific sections of code&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Algorithmic description&lt;/strong>
When algorithms are used, especially complicated ones, it can be useful to explain how the algorithm works or how it’s implemented within your code.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Using quick sort for performance gains&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>&lt;strong>Tagging:&lt;/strong>
The use of tagging can be used to label specific sections of code where known issues or areas of improvement are located.
Some examples are: &lt;code>BUG&lt;/code>, &lt;code>FIXME&lt;/code>, and &lt;code>TODO&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># TODO: Add condition for when val is None### &lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;h3 id="rules-of-commenting">Rules of Commenting&lt;/h3>
&lt;ul>
&lt;li>Should be kept brief and focused&lt;/li>
&lt;li>Avoid using long comments when possible&lt;/li>
&lt;/ul>
&lt;p>Essential rules as &lt;a href="https://blog.codinghorror.com/when-good-comments-go-bad/">suggested by Jeff Atwood&lt;/a>:&lt;/p>
&lt;ul>
&lt;li>Keep comments as close to the code being described as possible.&lt;/li>
&lt;li>Don’t use complex formatting (such as tables or ASCII figures).&lt;/li>
&lt;li>Don’t include redundant information. Assume the reader of the code has a basic understanding of programming principles and language syntax.&lt;/li>
&lt;li>Design your code to comment itself. 💪&lt;/li>
&lt;/ul>
&lt;h3 id="commenting-code-via-type-hinting-python-35">Commenting Code via Type Hinting (Python 3.5+)&lt;/h3>
&lt;p>Type hinting was added to Python 3.5 and is an additional form to help the readers of your code.&lt;/p>
&lt;p>Example&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">hello_name&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">name&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">str&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">-&amp;gt;&lt;/span> &lt;span class="nb">str&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Hello &lt;/span>&lt;span class="si">{name}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You can immediately tell that&lt;/p>
&lt;ul>
&lt;li>the function expects the input &lt;code>name&lt;/code> to be of a type &lt;code>str&lt;/code>, or string.&lt;/li>
&lt;li>the expected output of the function will be of a type &lt;code>str&lt;/code>, or string, as well.&lt;/li>
&lt;/ul>
&lt;h2 id="documenting-code-base-using-docstrings">Documenting Code Base using Docstrings&lt;/h2>
&lt;h3 id="docstings-background">Docstings Background&lt;/h3>
&lt;p>&lt;strong>Docstrings are built-in strings that, when configured correctly, can help your users and yourself with your project’s documentation.&lt;/strong>&lt;/p>
&lt;p>Python also has the built-in function &lt;code>help()&lt;/code> that prints out the objects docstring to the console.&lt;/p>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">say_hello&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">name&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;A simple function that says hello&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Hello &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">name&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;gt;&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">help&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">say_hello&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">Help&lt;/span> &lt;span class="n">on&lt;/span> &lt;span class="n">function&lt;/span> &lt;span class="n">say_hello&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">module&lt;/span> &lt;span class="n">__main__&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">say_hello&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">name&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">A&lt;/span> &lt;span class="n">simple&lt;/span> &lt;span class="n">function&lt;/span> &lt;span class="n">that&lt;/span> &lt;span class="n">says&lt;/span> &lt;span class="n">hello&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="docstring-types">Docstring Types&lt;/h3>
&lt;p>Docstring conventions:&lt;/p>
&lt;ul>
&lt;li>Are described within &lt;a href="https://www.python.org/dev/peps/pep-0257/">PEP 257&lt;/a>&lt;/li>
&lt;li>Purpose: provide your users with a brief overview of the object.&lt;/li>
&lt;li>Should be kept concise enough to be easy to maintain but still be elaborate enough for new users to understand their purpose and how to use the documented object.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>In all cases, the docstrings should use the triple-double quote (&lt;code>&amp;quot;&amp;quot;&amp;quot;&lt;/code>) string format.&lt;/strong> This should be done whether the docstring is multi-lined or not.&lt;/p>
&lt;p>At a bare minimum, a docstring should be a quick summary of whatever is it you’re describing and should be contained within a single line:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;This is a quick summary line used as a description of the object.&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Multi-lined docstrings are used to further elaborate on the object beyond the summary. All multi-lined docstrings have the following parts:&lt;/p>
&lt;ul>
&lt;li>A one-line summary line&lt;/li>
&lt;li>A blank line proceeding the summary&lt;/li>
&lt;li>Any further elaboration for the docstring&lt;/li>
&lt;li>Another blank line&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;This is the summary line
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">This is the further elaboration of the docstring. Within this section,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">you can elaborate further on details as appropriate for the situation.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">Notice that the summary and the elaboration is separated by a blank new
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">line.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Notice the blank line above. Code should continue on this line.&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>All docstrings should have the same &lt;strong>max character length as comments (72 characters).&lt;/strong>&lt;/p>
&lt;p>Three major categories:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Class Docstrings:&lt;/strong> Class and class methods&lt;/li>
&lt;li>&lt;strong>Package and Module Docstrings:&lt;/strong> Package, modules, and functions&lt;/li>
&lt;li>&lt;strong>Script Docstrings:&lt;/strong> Script and functions&lt;/li>
&lt;/ul>
&lt;h4 id="class-docstrings">Class Docstrings&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">SimpleClass&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Class docstrings go here.&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">def&lt;/span> &lt;span class="nf">say_hello&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="bp">self&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">name&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">str&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Class method docstrings go here.&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s1">&amp;#39;Hello &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">name&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s1">&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Class docstrings should contain the following information:&lt;/p>
&lt;ul>
&lt;li>A brief summary of its purpose and behavior&lt;/li>
&lt;li>Any public methods, along with a brief description&lt;/li>
&lt;li>Any class properties (attributes)&lt;/li>
&lt;li>Anything related to the interface for subclassers, if the class is intended to be subclassed&lt;/li>
&lt;/ul>
&lt;p>The class constructor parameters should be documented within the &lt;code>__init__&lt;/code> class method docstring.&lt;/p>
&lt;p>Individual methods should be documented using their individual docstrings. Class method docstrings should contain the following:&lt;/p>
&lt;ul>
&lt;li>A brief description of what the method is and what it’s used for&lt;/li>
&lt;li>Any arguments (both required and optional) that are passed including keyword arguments&lt;/li>
&lt;li>Label any arguments that are considered optional or have a default value&lt;/li>
&lt;li>Any side effects that occur when executing the method&lt;/li>
&lt;li>Any exceptions that are raised&lt;/li>
&lt;li>Any restrictions on when the method can be called&lt;/li>
&lt;/ul>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">class&lt;/span> &lt;span class="nc">Animal&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> A class used to represent an Animal
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> ...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Attributes
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> ----------
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> says_str : str
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> a formatted string to print out what the animal says
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> name : str
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> the name of the animal
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> sound : str
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> the sound that the animal makes
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> num_legs : int
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> the number of legs the animal has (default 4)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Methods
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> -------
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> says(sound=None)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Prints the animals name and what sound it makes
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">says_str&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;A &lt;/span>&lt;span class="si">{name}&lt;/span>&lt;span class="s2"> says &lt;/span>&lt;span class="si">{sound}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">def&lt;/span> &lt;span class="fm">__init__&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="bp">self&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">name&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">sound&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">num_legs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Parameters
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> ----------
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> name : str
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> The name of the animal
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> sound : str
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> The sound the animal makes
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> num_legs : int, optional
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> The number of legs the animal (default is 4)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">name&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">name&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sound&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">sound&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">num_legs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">num_legs&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">def&lt;/span> &lt;span class="nf">says&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="bp">self&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">sound&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">None&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Prints what the animals name is and what sound it makes.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> If the argument `sound` isn&amp;#39;t passed in, the default Animal
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> sound is used.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Parameters
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> ----------
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> sound : str, optional
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> The sound the animal makes (default is None)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Raises
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> ------
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> NotImplementedError
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> If no sound is set for the animal or passed in as a
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> parameter.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sound&lt;/span> &lt;span class="ow">is&lt;/span> &lt;span class="kc">None&lt;/span> &lt;span class="ow">and&lt;/span> &lt;span class="n">sound&lt;/span> &lt;span class="ow">is&lt;/span> &lt;span class="kc">None&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">raise&lt;/span> &lt;span class="ne">NotImplementedError&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Silent Animals are not supported!&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">out_sound&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sound&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="n">sound&lt;/span> &lt;span class="ow">is&lt;/span> &lt;span class="kc">None&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="n">sound&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">says_str&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">format&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">name&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">sound&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">out_sound&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="package-and-module-docstrings">Package and Module Docstrings&lt;/h4>
&lt;p>Package Docstrings:&lt;/p>
&lt;ul>
&lt;li>Should be placed at the top of the package’s &lt;code>__init__.py&lt;/code> file&lt;/li>
&lt;li>Should list the modules and sub-packages that are exported by the package&lt;/li>
&lt;/ul>
&lt;p>Module Docstrings:&lt;/p>
&lt;ul>
&lt;li>Placed at the top of the file even before any imports&lt;/li>
&lt;li>Should include:
&lt;ul>
&lt;li>A brief description of the module and its purpose&lt;/li>
&lt;li>A list of any classes, exception, functions, and any other objects exported by the module&lt;/li>
&lt;li>Docstring for a module function should include the same items as a class method&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h4 id="script-docstrings">Script Docstrings&lt;/h4>
&lt;p>Scripts: single file executables run from the console.&lt;/p>
&lt;p>Docstrings for scripts:&lt;/p>
&lt;ul>
&lt;li>Placed at the &lt;strong>top of the file&lt;/strong>&lt;/li>
&lt;li>should be documented well enough for users to be able to have a sufficient understanding of how to use the script&lt;/li>
&lt;li>Should be usable for its “usage” message, when the user incorrectly passes in a parameter or uses the &lt;code>-h&lt;/code> option&lt;/li>
&lt;/ul>
&lt;p>Any custom or third-party imports should be listed within the docstrings to allow users to know which packages may be required for running the script&lt;/p>
&lt;p>Example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Spreadsheet Column Printer
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">This script allows the user to print to the console all columns in the
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">spreadsheet. It is assumed that the first row of the spreadsheet is the
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">location of the columns.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">This tool accepts comma separated value files (.csv) as well as excel
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">(.xls, .xlsx) files.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">This script requires that `pandas` be installed within the Python
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">environment you are running this script in.
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">This file can also be imported as a module and contains the following
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">functions:
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> * get_spreadsheet_cols - returns the column headers of the file
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> * main - the main function of the script
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">argparse&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">pandas&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">pd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">get_spreadsheet_cols&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">file_loc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">print_cols&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Gets and prints the spreadsheet&amp;#39;s header columns
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Parameters
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> ----------
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> file_loc : str
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> The file location of the spreadsheet
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> print_cols : bool, optional
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> A flag used to print the columns to the console (default is
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> False)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> Returns
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> -------
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> list
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> a list of strings used that are the header columns
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">file_data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">read_excel&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">file_loc&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">col_headers&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">list&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">file_data&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">columns&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">values&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">print_cols&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">join&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">col_headers&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">col_headers&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">parser&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">argparse&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">ArgumentParser&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">description&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="vm">__doc__&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">add_argument&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;input_file&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="nb">str&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">help&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;The spreadsheet file to pring the columns of&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">args&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">parser&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">parse_args&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">get_spreadsheet_cols&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">input_file&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">print_cols&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">main&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="docstring-formats">Docstring Formats&lt;/h3>
&lt;p>Some of the most common formats are the following:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Formatting Type&lt;/th>
&lt;th>Description&lt;/th>
&lt;th>Supported by Sphinx&lt;/th>
&lt;th>Formal Specification&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;a href="https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings">Google docstrings&lt;/a>&lt;/td>
&lt;td>Google’s recommended form of documentation&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>No&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;a href="http://docutils.sourceforge.net/rst.html">reStructured Text&lt;/a>&lt;/td>
&lt;td>Official Python documentation standard; Not beginner friendly but feature rich&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Yes&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;a href="https://numpydoc.readthedocs.io/en/latest/format.html">NumPy/SciPy docstrings&lt;/a>&lt;/td>
&lt;td>NumPy’s combination of reStructured and Google Docstrings&lt;/td>
&lt;td>Yes&lt;/td>
&lt;td>Yes&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;a href="http://epydoc.sourceforge.net/epytext.html">Epytext&lt;/a>&lt;/td>
&lt;td>A Python adaptation of Epydoc; Great for Java developers&lt;/td>
&lt;td>Not officially&lt;/td>
&lt;td>Yes&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>The selection of the docstring format is up to you, but you should stick with the same format throughout your document/project. The following are examples of each type to give you an idea of how each documentation format looks.&lt;/p></description></item><item><title>pre-commit</title><link>https://haobin-tan.netlify.app/docs/coding/python/best-practice/pre-commit/</link><pubDate>Mon, 01 Nov 2021 00:00:00 +0000</pubDate><guid>https://haobin-tan.netlify.app/docs/coding/python/best-practice/pre-commit/</guid><description>&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>Before committing any staged Python files, &lt;code>pre-commit&lt;/code> automatically formats the code, validates compliance to PEP8, and performs different types of checking to keep the code and the project clean. This automatical process can greatly save our time on code formatting so that we can concentrate on code logic.&lt;/p>
&lt;figure>&lt;img src="https://raw.githubusercontent.com/EckoTan0804/upic-repo/master/uPic/precommit_pipeline-20211101151024237-20211101153634949.png"
alt="Basic pre-commit workflow (source: Automate Python workflow using pre-commits: black and flake8)">&lt;figcaption>
&lt;p>Basic &lt;code>pre-commit&lt;/code> workflow (source: &lt;a href="https://ljvmiranda921.github.io/notebook/2018/06/21/precommits-using-black-and-flake8/">Automate Python workflow using pre-commits: black and flake8&lt;/a>)&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;h2 id="what-is-pre-commit">What is &lt;code>pre-commit&lt;/code>?&lt;/h2>
&lt;p>&lt;code>pre-commit&lt;/code> is a multi-language package manager for 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>
&lt;h2 id="quick-start">Quick start&lt;/h2>
&lt;ol>
&lt;li>
&lt;p>Install pre-commit package manager&lt;/p>
&lt;ul>
&lt;li>
&lt;p>pip&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pip install pre-commit
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>conda&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">conda install -c conda-forge pre-commit
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;p>Check if the installation is successful:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pre-commit --version
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If successful, you can see the version information&lt;/p>
&lt;/li>
&lt;li>
&lt;p>(Optional) Add &lt;code>pre-commit&lt;/code> to &lt;code>requirements.txt&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Add a pre-commit configuration&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Create a file named &lt;code>.pre-commit-config.yaml&lt;/code> in the root of the project&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Define hooks/plugins in &lt;code>.pre-commit-config.yaml&lt;/code> (More see: &lt;a href="#adding-pre-commit-plugins">Adding pre-commit plugins&lt;/a>)&lt;/p>
&lt;blockquote>
&lt;p>You can generate a very basic configuration using &lt;a href="https://pre-commit.com/#pre-commit-sample-config">&lt;code>pre-commit sample-config&lt;/code>&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>
&lt;p>Install the git hook scripts (prerequisite: git is already initialized)&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pre-commit install
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now &lt;code>pre-commit&lt;/code> will run automatically on every &lt;code>git commit&lt;/code> (usually &lt;code>pre-commit&lt;/code> will only run on the changed files during git hooks).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>(Optional) Run &lt;code>pre-commit&lt;/code> against all the files&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pre-commit run --all-files
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ol>
&lt;h2 id="adding-pre-commit-plugins">Adding pre-commit plugins&lt;/h2>
&lt;p>Once you have &lt;code>pre-commit&lt;/code> installed, adding pre-commit hooks/plugins to your project is done with the &lt;code>.pre-commit-config.yaml&lt;/code> configuration file, which describes what repositories and hooks are installed.&lt;/p>
&lt;p>The top-level of &lt;code>.pre-commit-config.yaml&lt;/code> is a map. Among them, the most important key is &lt;code>repos&lt;/code>, which is a list of repository mappings. For other keys see: &lt;a href="https://pre-commit.com/#pre-commit-configyaml---top-level">.pre-commit-config.yaml - top level&lt;/a>.&lt;/p>
&lt;h3 id="repos">&lt;code>repos&lt;/code>&lt;/h3>
&lt;p>The repository mapping tells pre-commit where to get the code for the hook from.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;a href="https://pre-commit.com/#repos-repo">&lt;code>repo&lt;/code>&lt;/a>&lt;/th>
&lt;th>the repository url to &lt;code>git clone&lt;/code> from&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;a href="https://pre-commit.com/#repos-rev">&lt;code>rev&lt;/code>&lt;/a>&lt;/td>
&lt;td>the revision or tag to clone at. (&lt;em>new in 1.7.0&lt;/em>: previously &lt;code>sha&lt;/code>)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;a href="https://pre-commit.com/#repos-hooks">&lt;code>hooks&lt;/code>&lt;/a>&lt;/td>
&lt;td>A list of &lt;a href="https://pre-commit.com/#pre-commit-configyaml---hooks">hook mappings&lt;/a>.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Example&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">repos&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>- &lt;span class="w"> &lt;/span>&lt;span class="nt">repo&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">https://github.com/pre-commit/pre-commit-hooks&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">rev&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">v1.2.3&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">hooks&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="w"> &lt;/span>&lt;span class="l">...&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="hooks">&lt;code>hooks&lt;/code>&lt;/h4>
&lt;p>The &lt;a href="https://pre-commit.com/#pre-commit-configyaml---hooks">hook mapping&lt;/a> configures which hook from the repository is used and allows for customization.&lt;/p>
&lt;ul>
&lt;li>
&lt;p>The necessary key is &lt;code>id&lt;/code>, telling which hook from the repository to use. Other keys are optional.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>All optional keys will receive their default from the repository&amp;rsquo;s configuration.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>Example&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">repos&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>- &lt;span class="w"> &lt;/span>&lt;span class="nt">repo&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">https://github.com/pre-commit/pre-commit-hooks&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">rev&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">v1.2.3&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">hooks&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="w"> &lt;/span>&lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">trailing-whitespace&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="useful-repos-and-hooks">Useful repos and hooks&lt;/h2>
&lt;p>We briefly introduce some important and useful hooks. For supported hooks, check the &lt;a href="https://pre-commit.com/hooks.html">website&lt;/a> of &lt;code>pre-commit&lt;/code>.&lt;/p>
&lt;h3 id="pre-commit-hooks">&lt;code>pre-commit-hooks&lt;/code>&lt;/h3>
&lt;p>Some out-of-the-box hooks for pre-commit.&lt;/p>
&lt;p>Example&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">repo&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">https://github.com/pre-commit/pre-commit-hooks&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">rev&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">v4.0.1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">hooks&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">check-added-large-files&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Prevent giant files from being committed.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">check-ast&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Simply check whether files parse as valid python.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">check-byte-order-marker&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">check-case-conflict&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Check for files with names that would conflict on a case-insensitive filesystem like MacOS HFS+ or Windows FAT&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">check-docstring-first&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Checks for a common error of placing code before the docstring.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">check-json&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Attempts to load all json files to verify syntax.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">check-yaml&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Attempts to load all yaml files to verify syntax.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">end-of-file-fixer&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Makes sure files end in a newline and only a newline.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">trailing-whitespace&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Trims trailing whitespace.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">mixed-line-ending&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Replaces or checks mixed line ending.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="black">black&lt;/h3>
&lt;p>The &lt;a href="https://github.com/psf/black">black&lt;/a> code formatter in Python is an &amp;ldquo;uncompromising&amp;rdquo; tool that formats your code in the best way possible.&lt;/p>
&lt;p>Example&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">repo&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">https://github.com/psf/black&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">rev&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">20.&lt;/span>&lt;span class="l">8b1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">hooks&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">black&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">args&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">line-length=119&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="isort">isort&lt;/h3>
&lt;p>&lt;a href="https://pycqa.github.io/isort/index.html">isort&lt;/a> is a Python utility / library to sort imports alphabetically, and automatically separated into sections and by type.&lt;/p>
&lt;p>To allow customizations to be integrated into any project quickly, isort supports various standard config formats. Check the &lt;a href="https://pycqa.github.io/isort/docs/configuration/config_files.html">documentation&lt;/a> for all supported formats. I personally prefer &lt;code>setup.cfg&lt;/code>.&lt;/p>
&lt;blockquote>
&lt;p>When applying configurations, isort looks for the closest supported config file, in the order files are listed below. You can manually specify the settings file or path by setting &lt;code>--settings-path&lt;/code> from the command-line. Otherwise, isort will traverse up to 25 parent directories until it finds a suitable config file.&lt;/p>
&lt;/blockquote>
&lt;p>For projects that officially use both isort and &lt;a href="https://github.com/psf/black">black&lt;/a>, it is recommended to set the black profile in a config file.&lt;/p>
&lt;p>Example: &lt;code>setup.cfg&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">isort&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">multi_line_output&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="mi">3&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">include_trailing_comma&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">True&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">force_grid_wrap&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="mi">0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">use_parentheses&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">True&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">line_length&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="mi">88&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">profile&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">black&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="flex px-4 py-3 mb-6 rounded-md bg-primary-100 dark:bg-primary-900">
&lt;span class="pr-3 pt-1 text-primary-600 dark:text-primary-300">
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m11.25 11.25l.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0a9 9 0 0 1 18 0m-9-3.75h.008v.008H12z"/>&lt;/svg>
&lt;/span>
&lt;span class="dark:text-neutral-300">Sometimes the skip options do not work well, to skip some file for some reasons, check: &lt;a href="https://pycqa.github.io/isort/docs/configuration/action_comments.html">Action Comments&lt;/a>.&lt;/span>
&lt;/div>
&lt;h3 id="flake8">flake8&lt;/h3>
&lt;p>&lt;a href="https://github.com/PyCQA/flake8">flake8&lt;/a> is a command-line utility for enforcing style consistency across Python projects. It is a popular lint wrapper for python. Under the hood, it runs three other tools and combines their results:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="http://pep8.readthedocs.io/en/latest/">pep8&lt;/a> for checking style&lt;/li>
&lt;li>&lt;a href="https://github.com/pyflakes/pyflakes">pyflakes&lt;/a> for checking syntax&lt;/li>
&lt;li>&lt;a href="https://github.com/pycqa/mccabe">mccabe&lt;/a> for checking complexity&lt;/li>
&lt;/ul>
&lt;p>A good practice to customized flake8 checking is to define custom configurations in &lt;code>setup.cfg&lt;/code> and specify its path with &lt;code>--args&lt;/code> in &lt;code>.pre-commit-config.yaml&lt;/code>:&lt;/p>
&lt;p>&lt;code>setup.cfg&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">flake8&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">max-line-length&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="mi">119&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">max-complexity&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="mi">11&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">ignore&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">C901&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">W503&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">W504&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">E203&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">F401&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">isort&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">multi_line_output&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="mi">3&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">include_trailing_comma&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">True&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">force_grid_wrap&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="mi">0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">use_parentheses&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">True&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">line_length&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="mi">88&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">profile&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">black&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>and in &lt;code>.pre-commit-config.yaml&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">repo&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">https://github.com/PyCQA/flake8&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">rev&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">4.0.1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">hooks&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">flake8&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">args&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- --&lt;span class="l">config=setup.cfg&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="github-gist">GitHub Gist&lt;/h2>
&lt;p>My &lt;a href="https://gist.github.com/EckoTan0804/8d08e4cea323644dd82c43190a55eaa7">personal pre-commit config&lt;/a> for python projects.&lt;/p>
&lt;h2 id="reference">Reference&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://pre-commit.com/#usage">Documentation of pre-commit&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://ljvmiranda921.github.io/notebook/2018/06/21/precommits-using-black-and-flake8/">Automate Python workflow using pre-commits: black and flake8&lt;/a>: a simple tutorial on pre-commit&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://rednafi.github.io/digressions/python/2020/04/06/python-precommit.html">Running Python Linters with Pre-commit Hooks&lt;/a>: Another tutorial on pre-commit&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://mojotv.cn/tutorial/how-get-setup-perfect-python-projetc">Python教程:如何建立完美自动化的Python-starter项目&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://www.youtube.com/watch?v=Wmw-VGSjSNg&amp;amp;ab_channel=SoftwareEngineerHaydn">Python Pre-Commit Hooks Setup in a single video!&lt;/a>: Video tutorial&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Some good examples of &lt;code>.pre-commit-config.yaml&lt;/code>&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/NCAS-CMS/cfunits/blob/master/.pre-commit-config.yaml">https://github.com/NCAS-CMS/cfunits/blob/master/.pre-commit-config.yaml&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/open-mmlab/mmsegmentation/blob/master/.pre-commit-config.yaml">https://github.com/open-mmlab/mmsegmentation/blob/master/.pre-commit-config.yaml&lt;/a>: &lt;code>.pre-commit-config.yaml&lt;/code> of &lt;a href="https://github.com/open-mmlab/mmsegmentation">mmsegmentation&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul></description></item><item><title>STAR Method</title><link>https://haobin-tan.netlify.app/docs/notes/jobs/cover-letter/star_method/</link><pubDate>Sun, 03 Apr 2022 00:00:00 +0000</pubDate><guid>https://haobin-tan.netlify.app/docs/notes/jobs/cover-letter/star_method/</guid><description>&lt;p>A good way to provide more information about skills and qualification listed in the resume is to tell stories using the &lt;strong>STAR&lt;/strong> method.&lt;/p>
&lt;h2 id="what-is-star">What is STAR?&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>S&lt;/strong>ituation: What was the context of the story?&lt;/li>
&lt;li>&lt;strong>T&lt;/strong>ask: What ws your role in the situation?&lt;/li>
&lt;li>&lt;strong>A&lt;/strong>ssessment/&lt;strong>A&lt;/strong>ction: What did you do?&lt;/li>
&lt;li>&lt;strong>R&lt;/strong>esults: What did your action lead to? What was the accomplishment?
&lt;ul>
&lt;li>If possible, always try to include something quantifiable in your success statement&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="example">Example&lt;/h2>
&lt;figure>&lt;img src="https://raw.githubusercontent.com/EckoTan0804/upic-repo/master/uPic/STAR_eg.png"
alt="STAR example">&lt;figcaption>
&lt;p>STAR example&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;ul>
&lt;li>&lt;strong>S&lt;/strong>ituation: “as a lead project manager placed in the challenging project”&lt;/li>
&lt;li>&lt;strong>T&lt;/strong>ask: “managed the overhaul of our product’s design and user experience”&lt;/li>
&lt;li>&lt;strong>A&lt;/strong>ssessment/&lt;strong>A&lt;/strong>ction: “ensure the project met its deadlines and help eliminate process inefficiencies”&lt;/li>
&lt;li>&lt;strong>R&lt;/strong>esults: “saved the company more than $15,000”&lt;/li>
&lt;/ul></description></item><item><title>Common Phrases for Cover Letter</title><link>https://haobin-tan.netlify.app/docs/notes/jobs/cover-letter/common_phrases_for_cover_letter/</link><pubDate>Sun, 03 Apr 2022 00:00:00 +0000</pubDate><guid>https://haobin-tan.netlify.app/docs/notes/jobs/cover-letter/common_phrases_for_cover_letter/</guid><description>&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;ul>
&lt;li>At present, I am studying at…..&lt;/li>
&lt;li>At the moment, I am working for…..&lt;/li>
&lt;li>For the last 5 years, I have been working in the position of…..&lt;/li>
&lt;li>My current job title is…&lt;/li>
&lt;/ul>
&lt;h2 id="reason-for-writing">Reason For Writing&lt;/h2>
&lt;p>Explain why you are contacting the reader.&lt;/p>
&lt;ul>
&lt;li>I am writing in response to an advertisement which was placed in…….&lt;/li>
&lt;li>I am enquiring as to whether you currently have any positions in the area of……&lt;/li>
&lt;li>I am writing to apply for the position of…&lt;/li>
&lt;/ul>
&lt;h2 id="education-and-previous-experience">Education And Previous Experience&lt;/h2>
&lt;ul>
&lt;li>I have experience in…..and have worked at…….for the last…..years.&lt;/li>
&lt;li>My education includes a degree from XY university.&lt;/li>
&lt;li>I have been studying (subject) for 3 years.&lt;/li>
&lt;li>I am a native English speaker and have ample knowledge of Spanish and Chinese.&lt;/li>
&lt;/ul>
&lt;h2 id="what-makes-you-ideal-for-this-position">What Makes You Ideal For This Position?&lt;/h2>
&lt;p>Convince the reader that you are the best option for this position.&lt;/p>
&lt;ul>
&lt;li>I am a driven and ambitious person who is keen to learn new skills.&lt;/li>
&lt;li>I believe I am the best choice for this position as I have a lot of experience in my previous role.&lt;/li>
&lt;li>I feel that I am the most suitable candidate for &lt;a href="https://7esl.com/jobs-vocabulary/">this job&lt;/a> because of my ambition and drive to make a change.&lt;/li>
&lt;li>I am excited to have the opportunity to be able to work with a reputable company like yours.&lt;/li>
&lt;/ul>
&lt;h2 id="closing-statement">Closing Statement&lt;/h2>
&lt;ul>
&lt;li>Thank you for taking the time to read through my application.&lt;/li>
&lt;li>Please contact me at any time should you wish to arrange a meeting.&lt;/li>
&lt;li>Please do not hesitate to contact me for any further information.&lt;/li>
&lt;li>I appreciate your consideration for this application and look forward to hearing from you.&lt;/li>
&lt;/ul>
&lt;h2 id="additional-tipps">Additional Tipps&lt;/h2>
&lt;figure>&lt;img src="https://raw.githubusercontent.com/EckoTan0804/upic-repo/master/uPic/How-To-Write-A-Cover-Letter-2.jpg"
alt="Comman phrases for writing a cover letter">&lt;figcaption>
&lt;p>Comman phrases for writing a cover letter&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;figure>&lt;img src="https://raw.githubusercontent.com/EckoTan0804/upic-repo/master/uPic/Writing-A-Cover-Letter.jpg"
alt="Steps to write a cover letter">&lt;figcaption>
&lt;p>Steps to write a cover letter&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;h2 id="reference">Reference&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://7esl.com/how-to-write-a-cover-letter/#Common_Phrases_To_Include_In_Cover_Letters">How To Write A Cover Letter: Useful Tips, Phrases and Examples&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Best Practice</title><link>https://haobin-tan.netlify.app/docs/cs/software-engineering/best_practice/</link><pubDate>Wed, 11 May 2022 00:00:00 +0000</pubDate><guid>https://haobin-tan.netlify.app/docs/cs/software-engineering/best_practice/</guid><description/></item><item><title>CI/CD</title><link>https://haobin-tan.netlify.app/docs/cs/software-engineering/best_practice/ci_cd/</link><pubDate>Wed, 11 May 2022 00:00:00 +0000</pubDate><guid>https://haobin-tan.netlify.app/docs/cs/software-engineering/best_practice/ci_cd/</guid><description>&lt;figure>&lt;img src="https://raw.githubusercontent.com/EckoTan0804/upic-repo/master/uPic/cicd.svg.imgo.svg"
alt="CI/CD (Source: Synopsys)">&lt;figcaption>
&lt;p>CI/CD (Source: &lt;a href="https://www.synopsys.com/glossary/what-is-cicd.html">Synopsys&lt;/a>)&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;h2 id="what-is-cicd">What is CI/CD?&lt;/h2>
&lt;ul>
&lt;li>A method to frequently deliver &lt;a href="https://www.redhat.com/en/topics/cloud-native-apps">apps&lt;/a> to customers by introducing &lt;a href="https://www.redhat.com/en/topics/automation">automation&lt;/a> into the stages of &lt;a href="https://www.redhat.com/en/topics/cloud-native-apps/why-choose-red-hat-cloud-native">app development&lt;/a>.
&lt;ul>
&lt;li>&lt;strong>CI&lt;/strong> = &lt;strong>C&lt;/strong>ontinuous &lt;strong>I&lt;/strong>ntegration&lt;/li>
&lt;li>&lt;strong>CD&lt;/strong> = &lt;strong>C&lt;/strong>ontinuous &lt;strong>D&lt;/strong>elivery and &lt;strong>D&lt;/strong>eployment&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Introduces ongoing automation and continuous monitoring throughout the &lt;a href="https://www.redhat.com/en/topics/devops/what-is-application-lifecycle-management-alm">lifecycle of apps&lt;/a>, from integration and testing phases to delivery and &lt;a href="https://www.redhat.com/en/topics/automation/what-is-deployment-automation">deployment&lt;/a>.&lt;/li>
&lt;/ul>
&lt;h3 id="continuous-integration-ci">Continuous Integration (CI)&lt;/h3>
&lt;ul>
&lt;li>An automation process for &lt;strong>developers&lt;/strong>
&lt;ul>
&lt;li>New code changes to an app are regularly built, tested, and merged to a shared repository.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>This process is automated to ensure that teams can build, test, and package their applications in a reliable and repeatable way.&lt;/li>
&lt;li>Helps streamline code changes, thereby increasing time for developers to make changes and contribute to improved software.&lt;/li>
&lt;li>A solution to the problem of having too many branches of an app in development at once that might conflict with each other.&lt;/li>
&lt;/ul>
&lt;h3 id="cotinuous-delivery-andor-deployment-cd">Cotinuous Delivery and/or Deployment (CD)&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>&lt;a href="https://www.synopsys.com/glossary/what-is-continuous-delivery.html">Continuous delivery&lt;/a>&lt;/strong>
&lt;ul>
&lt;li>The automated delivery of completed code to environments like testing and development.
&lt;ul>
&lt;li>&lt;em>I.e.&lt;/em>, a developer’s changes to an application are automatically bug tested and uploaded to a repository&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Provides an automated and consistent way for code to be delivered to these environments.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="https://www.synopsys.com/glossary/what-is-continuous-development.html">&lt;strong>Continuous deployment&lt;/strong>&lt;/a>
&lt;ul>
&lt;li>Next step of continuous delivery&lt;/li>
&lt;li>Every change that passes the automated tests is automatically placed in production, resulting in many production deployments.&lt;/li>
&lt;li>Addresses the problem of overloading operations teams with manual processes that slow down app delivery&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;div class="flex px-4 py-3 mb-6 rounded-md bg-primary-100 dark:bg-primary-900">
&lt;span class="pr-3 pt-1 text-primary-600 dark:text-primary-300">
&lt;svg height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">&lt;path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m11.25 11.25l.041-.02a.75.75 0 0 1 1.063.852l-.708 2.836a.75.75 0 0 0 1.063.853l.041-.021M21 12a9 9 0 1 1-18 0a9 9 0 0 1 18 0m-9-3.75h.008v.008H12z"/>&lt;/svg>
&lt;/span>
&lt;span class="dark:text-neutral-300">They are related concepts that sometimes get used interchangeably. Both are about automating further stages of the pipeline, but they’re sometimes used separately to illustrate just how much automation is happening.&lt;/span>
&lt;/div>
&lt;h3 id="difference-between-ci-and-cd">Difference between CI and CD&lt;/h3>
&lt;p>CI is a set of practices performed &lt;em>as developers are writing&lt;/em> code, and CD is a set of practices performed &lt;em>after&lt;/em> the code is completed.&lt;/p>
&lt;h2 id="how-cicd-pipeline-works">How CI/CD pipeline works?&lt;/h2>
&lt;p>The CI/CD pipeline works like an infinity loop:&lt;/p>
&lt;figure>&lt;img src="https://raw.githubusercontent.com/EckoTan0804/upic-repo/master/uPic/cicd.svg.imgo.svg"
alt="CI/CD (Source: Synopsys)" width="80%">&lt;figcaption>
&lt;p>CI/CD (Source: &lt;a href="https://www.synopsys.com/glossary/what-is-cicd.html">Synopsys&lt;/a>)&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;ol>
&lt;li>Developers write the &lt;strong>code&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Build&lt;/strong> or compile the code&lt;/li>
&lt;li>&lt;strong>Test&lt;/strong> the code for bugs&lt;/li>
&lt;li>&lt;strong>Release&lt;/strong> the code if all tests are passed&lt;/li>
&lt;li>&lt;strong>Deploy&lt;/strong> the change in production&lt;/li>
&lt;li>End users or customers &lt;strong>operate&lt;/strong> the new change&lt;/li>
&lt;li>Project owner or project manager monitors and gets feedback&lt;/li>
&lt;li>&lt;strong>Plan&lt;/strong> the next step based on the feedback&lt;/li>
&lt;li>Back to step 1: Write code based on the plan&lt;/li>
&lt;/ol>
&lt;h2 id="why-is-cicd-important">Why is CI/CD Important?&lt;/h2>
&lt;ul>
&lt;li>Allows organizations to ship software quickly and efficiently.&lt;/li>
&lt;li>Facilitates an effective process for getting products to market faster than ever before, continuously delivering code into production, and ensuring an ongoing flow of new features and bug fixes via the most efficient delivery method.&lt;/li>
&lt;/ul>
&lt;h2 id="benefit-of-cicd">Benefit of CI/CD&lt;/h2>
&lt;ul>
&lt;li>Automated testing enables continuous delivery, which ensures software &lt;strong>quality&lt;/strong> and &lt;strong>security&lt;/strong> and increases the &lt;strong>profitability&lt;/strong> of code in production.&lt;/li>
&lt;li>CI/CD pipelines enable a much &lt;strong>shorter time to market&lt;/strong> for new product features, creating happier customers and lowering strain on development.&lt;/li>
&lt;li>The &lt;strong>great increase in overall speed of delivery&lt;/strong> enabled by CI/CD pipelines improves an organization’s competitive edge.&lt;/li>
&lt;li>Automation &lt;strong>frees team members&lt;/strong> to focus on what they do best, yielding the best end products.&lt;/li>
&lt;li>Organizations with a successful CI/CD pipeline can attract great talent. By moving away from traditional &lt;a href="https://en.wikipedia.org/wiki/Waterfall_model">waterfall methods&lt;/a>, engineers and developers are no longer bogged down with repetitive activities that are often highly dependent on the completion of other tasks.&lt;/li>
&lt;/ul>
&lt;p>##Reference&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://www.redhat.com/en/topics/devops/what-is-ci-cd">What is CI/CD?&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://www.synopsys.com/glossary/what-is-cicd.html">CICD&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Video tutorials&lt;/p>
&lt;ul>
&lt;li>
&lt;p>DevOps CI/CD Explained in 100 Seconds&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/scEDHsr3APg?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"
>&lt;/iframe>
&lt;/div>
&lt;/li>
&lt;li>
&lt;p>CI/CD Explained | How DevOps Use Pipelines for Automation&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/M4CXOocovZ4?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"
>&lt;/iframe>
&lt;/div>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>​&lt;/p></description></item></channel></rss>