<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kah</title>
    <description>The latest articles on DEV Community by Kah (@kahdev).</description>
    <link>https://dev.to/kahdev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F320021%2F3e62e36c-f578-4976-aa86-2c773d306b54.jpg</url>
      <title>DEV Community: Kah</title>
      <link>https://dev.to/kahdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kahdev"/>
    <language>en</language>
    <item>
      <title>Never trust an upload's filename</title>
      <dc:creator>Kah</dc:creator>
      <pubDate>Sat, 22 May 2021 09:25:21 +0000</pubDate>
      <link>https://dev.to/kahdev/never-trust-an-upload-s-filename-3fhj</link>
      <guid>https://dev.to/kahdev/never-trust-an-upload-s-filename-3fhj</guid>
      <description>&lt;p&gt;It's generally accepted that we should never simply trust a user's input. Otherwise, we're vulnerable to malicious input (&lt;a href="https://owasp.org/www-project-proactive-controls/v3/en/c5-validate-inputs" rel="noopener noreferrer"&gt;CE-5&lt;/a&gt;). For a file upload from a user, it’s common to check their file size or type, especially when restricting them by those two attributes. But one that might get overlooked is the filename.&lt;/p&gt;

&lt;p&gt;Checking the filename is especially important when it displayed on a web page to prevent HTML or XSS injection. That’s just on the frontend. On the backend, there are the other usual injections to worry about. Like SQL injection, when storing the name in a database. Or path injection, if storing in a path based on the name.&lt;/p&gt;

&lt;p&gt;It might be tempting to dismiss this possibility as something that would never happen. After all, we must make the files first before we can upload them and there are file-naming rules. We can't simply make one with just any name they want! However, the rules won’t prevent malicious filenames!&lt;/p&gt;

&lt;h2&gt;
  
  
  OS file naming rules won't prevent injection
&lt;/h2&gt;

&lt;p&gt;Operating systems have rules about what &lt;em&gt;can&lt;/em&gt; be in a filename. But, different operating systems can have different rules. So, a filename prohibited in one operating system may be allowed in another.&lt;/p&gt;

&lt;p&gt;For example, &lt;code&gt;&amp;lt;img onerror="alert('XSS')" src="nowhere"&amp;gt;.txt&lt;/code&gt;. The file can't be created in Windows because it &lt;em&gt;doesn't&lt;/em&gt; allow &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&lt;/code&gt; (see &lt;a href="https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions" rel="noopener noreferrer"&gt;Naming a file&lt;/a&gt;). However, Linux &lt;em&gt;does&lt;/em&gt; allow them. For example, we could use &lt;a href="https://man7.org/linux/man-pages/man1/touch.1.html" rel="noopener noreferrer"&gt;touch&lt;/a&gt; to create the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;img onerror="alert('&lt;/span&gt;&lt;span class="s2"&gt;"'XSS'"&lt;/span&gt;&lt;span class="s1"&gt;')" src="nowhere"&amp;gt;.txt'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Actually, we don't even need to make the files
&lt;/h2&gt;

&lt;p&gt;HTTP clients usually send file uploads using a multi-part POST request. We can use &lt;a href="https://www.wireshark.org/" rel="noopener noreferrer"&gt;Wireshark&lt;/a&gt; to see what the request looks like. Here's one from &lt;a href="https://curl.se/" rel="noopener noreferrer"&gt;cURL&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /attachments HTTP/1.1
Host: 127.0.0.1:3000
User-Agent: curl/7.76.1
Accept: */*
Content-Length: 250
Content-Type: multipart/form-data; boundary=------------------------6c44be865e1d13e6

--------------------------6c44be865e1d13e6
Content-Disposition: form-data; name="attachment"; filename="Lorem_Ipsum.txt"
Content-Type: text/plain

Lorem ipsum dolor sit amet, consectetur cras amet. 
--------------------------6c44be865e1d13e6--
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the filename field is at the end of the &lt;code&gt;Content-Disposition&lt;/code&gt; header. We can use this as a template to make our own requests. Simply. copy and paste into a file, change the filename and update the &lt;code&gt;Content-Length&lt;/code&gt;. Then use &lt;a href="https://nmap.org/ncat/guide/index.html/" rel="noopener noreferrer"&gt;Ncat&lt;/a&gt; to send the request. For example, to send the request in &lt;code&gt;request.http&lt;/code&gt; to &lt;code&gt;http://localhost:3000&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ncat localhost 3000 &amp;lt; request.http
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using HTTPS isn't enough either
&lt;/h2&gt;

&lt;p&gt;The example above sent a forged request to an insecure server (i.e one that isn't using SSL/TLS). But changing over to HTTPS still won't be enough to prevent malicious filenames - &lt;a href="https://nmap.org/ncat/guide/index.html/" rel="noopener noreferrer"&gt;Ncat&lt;/a&gt; also works with HTTPS connections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ncat -C --ssl localhost 3000 &amp;lt; request.http
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even if it didn't, it we could go back to using a web browser to upload files over HTTPS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pentesting tools makes this easier
&lt;/h2&gt;

&lt;p&gt;Using &lt;a href="https://www.wireshark.org/" rel="noopener noreferrer"&gt;Wireshark&lt;/a&gt; and &lt;a href="https://nmap.org/ncat/guide/index.html/" rel="noopener noreferrer"&gt;Ncat&lt;/a&gt; was how I first learnt to do this. It turns out pentesting tools like &lt;a href="https://mitmproxy.org/" rel="noopener noreferrer"&gt;mitmproxy&lt;/a&gt; make this easier - it can &lt;a href="https://docs.mitmproxy.org/stable/mitmproxytutorial-interceptrequests/" rel="noopener noreferrer"&gt;intercept&lt;/a&gt; and &lt;a href="https://docs.mitmproxy.org/stable/mitmproxytutorial-modifyrequests/" rel="noopener noreferrer"&gt;modify&lt;/a&gt; the requests in-flight.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://portswigger.net/burp" rel="noopener noreferrer"&gt;Burp Suite&lt;/a&gt;'s &lt;a href="https://portswigger.net/burp/documentation/desktop/tools/proxy/getting-started" rel="noopener noreferrer"&gt;proxy&lt;/a&gt; has similar features.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Prevent injection via filenames
&lt;/h2&gt;

&lt;p&gt;There is just no way to guarantee a server never receiving an upload with a bad filename. The server must guard against it - usually by sanitising or encoding and escaping where it is used (&lt;a href="https://owasp.org/www-project-proactive-controls/v3/en/c4-encode-escape-data.html" rel="noopener noreferrer"&gt;OWASP CE-4&lt;/a&gt;). Doing so will help to prevent injection attacks via filenames.&lt;/p&gt;

</description>
      <category>security</category>
      <category>securecoding</category>
    </item>
    <item>
      <title>Why 3 &gt; 2 &gt; 1 gives false</title>
      <dc:creator>Kah</dc:creator>
      <pubDate>Fri, 11 Sep 2020 23:36:53 +0000</pubDate>
      <link>https://dev.to/kahdev/why-3-2-1-gives-false-29j6</link>
      <guid>https://dev.to/kahdev/why-3-2-1-gives-false-29j6</guid>
      <description>&lt;p&gt;Recently, I saw this question about how does Javascript evaluate an expression:&lt;br&gt;
&lt;/p&gt;
&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--RYcJyNZj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/870951469528354817/cB9-tLqt_normal.jpg" alt="gwagsi glenn profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        gwagsi glenn
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @gwagsig
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      why is&lt;br&gt;console.log(1&amp;lt;2&amp;lt;3) ;&lt;br&gt;true &lt;br&gt;and &lt;br&gt;console.log(3&amp;gt;2&amp;gt;1) ;&lt;br&gt;fasle &lt;br&gt;?&lt;br&gt;&lt;a href="https://twitter.com/hashtag/100DaysOfCode"&gt;#100DaysOfCode&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/CodeNewbies"&gt;#CodeNewbies&lt;/a&gt; &lt;a href="https://twitter.com/hashtag/javascript"&gt;#javascript&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      08:58 AM - 10 Sep 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1303981215461105670" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1303981215461105670" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1303981215461105670" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;So, why does &lt;code&gt;1 &amp;lt; 2 &amp;lt; 3&lt;/code&gt; give &lt;code&gt;true&lt;/code&gt;, but &lt;code&gt;3 &amp;gt; 2 &amp;gt; 1&lt;/code&gt; give &lt;code&gt;false&lt;/code&gt;? According to &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table"&gt;operator precedence and associativity&lt;/a&gt;, they are evaluated from left to right. So...&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;1 &amp;lt; 2 &amp;lt; 3&lt;/code&gt; is evaluated as &lt;code&gt;(1 &amp;lt; 2) &amp;lt; 3&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1 &amp;lt; 2&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;, making the expression &lt;code&gt;true &amp;lt; 3&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;How does it compare a &lt;code&gt;true&lt;/code&gt; against a number? It does this by first converting the boolean to a number. &lt;code&gt;true&lt;/code&gt; is converted to &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;false&lt;/code&gt; is converted to &lt;code&gt;0&lt;/code&gt; (see &lt;a href="https://www.ecma-international.org/ecma-262/11.0/index.html#sec-tonumber"&gt;7.1.14 of the ECMAScript specififcation&lt;/a&gt;). Thus, the expression is evaluated as &lt;code&gt;1 &amp;lt; 3&lt;/code&gt; which gives &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now for &lt;code&gt;3 &amp;gt; 2 &amp;gt; 1&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Going left to right, &lt;code&gt;3 &amp;gt; 2&lt;/code&gt; is evaluated first which is &lt;code&gt;true&lt;/code&gt;. The expression becomes &lt;code&gt;true &amp;gt; 1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To evaluate, &lt;code&gt;true&lt;/code&gt; is converted to &lt;code&gt;1&lt;/code&gt;. This gives &lt;code&gt;1 &amp;gt; 1&lt;/code&gt;, which is &lt;code&gt;false&lt;/code&gt;!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For bonus points, try figuring out &lt;code&gt;1 &amp;lt; 3 &amp;gt; 2&lt;/code&gt; and &lt;code&gt;1 &amp;gt; 3 &amp;lt; 2&lt;/code&gt; gives.&lt;br&gt;

  Answers:
  &lt;br&gt;
For &lt;code&gt;1 &amp;lt; 3 &amp;gt; 2&lt;/code&gt;:

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;1 &amp;lt; 3&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;, so it becomes &lt;code&gt;true &amp;gt; 2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;true&lt;/code&gt; is converted to &lt;code&gt;1&lt;/code&gt;, so it becomes &lt;code&gt;1 &amp;gt; 2&lt;/code&gt;, which is &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For &lt;code&gt;1 &amp;gt; 3 &amp;lt; 2&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;1 &amp;gt; 3&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt;, so it becomes &lt;code&gt;false &amp;lt; 2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;false&lt;/code&gt; is converted to &lt;code&gt;0&lt;/code&gt;, so it becomes &lt;code&gt;0 &amp;lt; 2&lt;/code&gt;, which is &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;



&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Python's with/for...else and try...else</title>
      <dc:creator>Kah</dc:creator>
      <pubDate>Sun, 09 Aug 2020 13:32:38 +0000</pubDate>
      <link>https://dev.to/kahdev/python-s-with-for-else-and-try-else-1158</link>
      <guid>https://dev.to/kahdev/python-s-with-for-else-and-try-else-1158</guid>
      <description>&lt;p&gt;In most programming languages like C, Java and Javscript, the &lt;code&gt;else&lt;/code&gt; clause is used with &lt;code&gt;if&lt;/code&gt; statements. But did you know in Python the &lt;code&gt;while&lt;/code&gt; and &lt;code&gt;for&lt;/code&gt; loops as well as the &lt;code&gt;try&lt;/code&gt; statement can also have &lt;code&gt;else&lt;/code&gt; clauses?&lt;/p&gt;

&lt;h2&gt;
  
  
  In the &lt;code&gt;while&lt;/code&gt; loop
&lt;/h2&gt;

&lt;p&gt;To get a sense of how the &lt;code&gt;else&lt;/code&gt; works with the loops, it's easy to write some code to play with. Here's the first one I tried:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;basket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"orange"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"pear"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"banana"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;basket&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"Its not &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Else block ran!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"i is now &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What do you think will be the output? At first, I thought it would output &lt;code&gt;Else block ran!&lt;/code&gt; followed by &lt;code&gt;i is now 0&lt;/code&gt; (i.e. it would execute the &lt;code&gt;else&lt;/code&gt; block) because the first item in the list is already &lt;code&gt;apple&lt;/code&gt;. The output certainly shows this happens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Else block ran!
i is now 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, what if we changed the condition in the &lt;code&gt;while&lt;/code&gt; loop to &lt;code&gt;basket[i] != "banana"&lt;/code&gt;? The body of the &lt;code&gt;while&lt;/code&gt; loop should now run, so I first thought it would surely skip the &lt;code&gt;else&lt;/code&gt; clause ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Its not 0
Its not 1
Its not 2
Else block ran!
i is now 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nope! It printed &lt;code&gt;Else block ran!&lt;/code&gt;, so the &lt;code&gt;else&lt;/code&gt; block must've ran! &lt;/p&gt;

&lt;p&gt;So what's going on here? Turning to the documentation on the &lt;a href="https://docs.python.org/3/reference/compound_stmts.html#the-while-statement"&gt;while statement&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This repeatedly tests the expression and, if it is true, executes the first suite; if the expression is false (which may be the first time it is tested) the suite of the &lt;code&gt;else&lt;/code&gt; clause, if present, is executed and the loop terminates.&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://docs.python.org/3/reference/simple_stmts.html#break"&gt;&lt;code&gt;break&lt;/code&gt;&lt;/a&gt; statement executed in the first suite terminates the loop without executing the &lt;code&gt;else&lt;/code&gt; clause’s suite.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, if we want to skip the &lt;code&gt;else&lt;/code&gt; block, loop needs to exit with a &lt;code&gt;break&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Rewriting the &lt;code&gt;while&lt;/code&gt; loop to use &lt;code&gt;break&lt;/code&gt; to exit when it finds a match:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;basket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"orange"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"pear"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"banana"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basket&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;basket&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"banana"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# We found what we were looking for.
&lt;/span&gt;    &lt;span class="k"&gt;break&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"Its not &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# We couldn't find it in the list.
&lt;/span&gt;  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Else block ran!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"i is now &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output now doesn't contain the &lt;code&gt;print&lt;/code&gt; in the &lt;code&gt;else&lt;/code&gt; block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Its not 0
Its not 1
Its not 2
i is now 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And just to check, setting the &lt;code&gt;if&lt;/code&gt; condition back to &lt;code&gt;basket[i] == "apple"&lt;/code&gt; also doesn't run the &lt;code&gt;else&lt;/code&gt; block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;i is now 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  In the &lt;code&gt;for&lt;/code&gt; loop
&lt;/h2&gt;

&lt;p&gt;The behaviour of the &lt;code&gt;else&lt;/code&gt; clause in the &lt;code&gt;for&lt;/code&gt; loop is the same as that of the &lt;code&gt;while&lt;/code&gt; loop. Rewriting the &lt;code&gt;while&lt;/code&gt; loop to use &lt;code&gt;for&lt;/code&gt; instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;basket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"orange"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"pear"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"banana"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;find&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"banana"&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;basket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"We found &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"There isn't any &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running this, you'll get the output &lt;code&gt;We found banana!&lt;/code&gt;, but changing &lt;code&gt;find&lt;/code&gt; to &lt;code&gt;"grape"&lt;/code&gt; will result in &lt;code&gt;There isn't any grape!&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  In &lt;code&gt;try&lt;/code&gt; statements
&lt;/h2&gt;

&lt;p&gt;For the &lt;code&gt;else&lt;/code&gt; in &lt;code&gt;try&lt;/code&gt; statements, the &lt;a href="https://docs.python.org/3/reference/compound_stmts.html#the-try-statement"&gt;documentation&lt;/a&gt; states:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The optional &lt;code&gt;else&lt;/code&gt; clause is executed if the control flow leaves the &lt;a href="https://docs.python.org/3/reference/compound_stmts.html#try"&gt;&lt;code&gt;try&lt;/code&gt;&lt;/a&gt; suite, no exception was raised, and no &lt;a href="https://docs.python.org/3/reference/simple_stmts.html#return"&gt;&lt;code&gt;return&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://docs.python.org/3/reference/simple_stmts.html#continue"&gt;&lt;code&gt;continue&lt;/code&gt;&lt;/a&gt;, or &lt;a href="https://docs.python.org/3/reference/simple_stmts.html#break"&gt;&lt;code&gt;break&lt;/code&gt;&lt;/a&gt; statement was executed. Exceptions in the else clause are not handled by the preceding &lt;a href="https://docs.python.org/3/reference/compound_stmts.html#except"&gt;&lt;code&gt;except&lt;/code&gt;&lt;/a&gt; clauses.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's an example of a &lt;code&gt;try&lt;/code&gt; with an &lt;code&gt;else&lt;/code&gt; clause:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# This will raise an AssertionError
&lt;/span&gt;  &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Catch all exceptions
&lt;/span&gt;  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Got exception"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Else!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Finally always runs at the end
&lt;/span&gt;  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finally!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the &lt;code&gt;AssertionError&lt;/code&gt; thrown, it skips the &lt;code&gt;else&lt;/code&gt;. This is the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Got exception
Finally!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But changing the assertion to pass (e.g. &lt;code&gt;assertion 1 == 1&lt;/code&gt;), no exception is thrown and, thus, &lt;code&gt;else&lt;/code&gt; is executed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Else!
Finally!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;However, you could do the same thing without an &lt;code&gt;else&lt;/code&gt; clause - anything within the &lt;code&gt;try&lt;/code&gt; block after the line that can throw the exception is effectively the "&lt;code&gt;else&lt;/code&gt;". For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# If this assertion fails, this will throw an AssertionError
&lt;/span&gt;  &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

  &lt;span class="c1"&gt;# No exception thrown, so everything here is the "else"
&lt;/span&gt;  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Else!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Catch all exceptions
&lt;/span&gt;  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Got exception"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Finally always runs at the end
&lt;/span&gt;  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finally!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So given this alternative, apart from style, why would you use the &lt;code&gt;else&lt;/code&gt; clause? The difference is in when the &lt;code&gt;else&lt;/code&gt; block throws an exception (thanks to this &lt;a href="https://stackoverflow.com/a/16138864/256815"&gt;Stackoverflow answer&lt;/a&gt; for pointing it out). If it's part of the &lt;code&gt;try&lt;/code&gt; block, the exception may be handled by one of the &lt;code&gt;try&lt;/code&gt;'s &lt;code&gt;except&lt;/code&gt; handlers, but it's passed up the chain if it's in an &lt;code&gt;else&lt;/code&gt; clause - none of the handlers defined in the same &lt;code&gt;try&lt;/code&gt; statement will handle exceptions from the &lt;code&gt;else&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To see this, let's modify the &lt;code&gt;try&lt;/code&gt; statement so that the &lt;code&gt;assert&lt;/code&gt; becomes the &lt;code&gt;else&lt;/code&gt;. First, without the separate &lt;code&gt;else&lt;/code&gt; clause:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Body of try. Won't throw an exception. 
&lt;/span&gt;  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Try body"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# The "else" part. Make it throw an exception.
&lt;/span&gt;  &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Catch all exceptions
&lt;/span&gt;  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Got exception"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Finally always runs at the end
&lt;/span&gt;  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finally!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output for this is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Try body
Got exception
Finally!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;except&lt;/code&gt; block handled the exception from our "&lt;code&gt;else&lt;/code&gt;". So to check that using the &lt;code&gt;else&lt;/code&gt; clause doesn't trigger one of the handlers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Body of try
&lt;/span&gt;  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Try body"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Catch all exceptions
&lt;/span&gt;  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Got exception"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Make else thrown an exception
&lt;/span&gt;  &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Finally always runs at the end
&lt;/span&gt;  &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Finally!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which gives the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Try body
Finally!
Traceback (most recent call last):
  File "main.py", line 9, in &amp;lt;module&amp;gt;
    assert 1 == 2
AssertionError
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What's in a useful commit message?</title>
      <dc:creator>Kah</dc:creator>
      <pubDate>Sun, 26 Jul 2020 00:53:13 +0000</pubDate>
      <link>https://dev.to/kahdev/what-s-in-a-useful-commit-message-33db</link>
      <guid>https://dev.to/kahdev/what-s-in-a-useful-commit-message-33db</guid>
      <description>&lt;p&gt;When making a commit, Git prompts you to enter a message to store with the commit. Commit messages are messages for someone looking at the change in the future. They can help them in making sense of the changes, but Git can't enforce that you write a useful one - how can it? Instead, it is up to you to write something useful for them. So, what can you write to in a commit message to make it useful?&lt;/p&gt;

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

&lt;p&gt;No matter who is looking at the commit message, it helps to describe &lt;em&gt;what&lt;/em&gt; is in the commit. This is most likely the first thing anyone will want to know about a commit - &lt;em&gt;what&lt;/em&gt; is this commit about? The &lt;a href="https://git-scm.com/docs/git-commit#_discussion" rel="noopener noreferrer"&gt;git commit documentation&lt;/a&gt; recommends this being the first thing in commit message:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Though not required, it’s a good idea to begin the commit message with a single short (less than 50 character) line summarizing the change, followed by a blank line and then a more thorough description. The text up to the first blank line in a commit message is treated as the commit title, and that title is used throughout Git.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Visually, the format looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;commit title (less than 50 characters recommended)

more thorough description
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Log viewers like &lt;a href="https://git-scm.com/docs/gitk" rel="noopener noreferrer"&gt;gitk&lt;/a&gt; display their title in the list of commits.&lt;/p&gt;

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

&lt;p&gt;A descriptive title describing &lt;em&gt;what&lt;/em&gt; is in the commit will make the logs much more easier to work with.&lt;/p&gt;

&lt;p&gt;If you're finding it difficult to write a descriptive title for the commit, perhaps have a look what is in the change and see whether the commit is trying to do more than one thing. Ideally, the commit should be doing just one thing. &lt;/p&gt;

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

&lt;p&gt;When looking back to a previous change, a very common question that is asked is &lt;em&gt;why&lt;/em&gt; did we make that change? When trying to build changes on top of previous changes or trying to fix an issue in code, knowing &lt;em&gt;why&lt;/em&gt; the changes were made in the first place can help avoiding introducing more problems later. For contributions to other projects, it helps to convince maintainers that they should be included. For your future self, it can help to serve as a reminder of &lt;em&gt;why&lt;/em&gt; you did what you did at the time. An explanation of the &lt;em&gt;why&lt;/em&gt; indicates that the changes were thought out and wasn't just done on a whim.&lt;/p&gt;

&lt;p&gt;Sometimes, the &lt;em&gt;why&lt;/em&gt; is implied in the title. For example, "fix spelling errors" would likely be self explanatory. When its not, this is something that should be written in the commit description. Describing the &lt;em&gt;why&lt;/em&gt; could also include answering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the change fixes something, what was wrong in the first place? Were there any lessons learnt?&lt;/li&gt;
&lt;li&gt;If it is an new feature, what does it do?&lt;/li&gt;
&lt;li&gt;If it is an optimisation or improvement, how does it improve things? Are you also able to quantify the improvement?&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;When Git prompts your for a commit message it may be tempting to just fill this in with something to fulfil this step, but to do so would be squandering an opportunity to capture valuable information about it. Writing one is about spending the time and effort now to help someone in the future - it can be immensely helpful in understanding your change and its purpose. Someone may thank you for it one day! &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>codequality</category>
      <category>commits</category>
    </item>
  </channel>
</rss>
