<?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: Anže Pečar</title>
    <description>The latest articles on DEV Community by Anže Pečar (@anze3db).</description>
    <link>https://dev.to/anze3db</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%2F218992%2F0196cdd9-bbc6-4516-94b0-211378715f6a.jpeg</url>
      <title>DEV Community: Anže Pečar</title>
      <link>https://dev.to/anze3db</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anze3db"/>
    <language>en</language>
    <item>
      <title>Mastodon Instances with Software Developers</title>
      <dc:creator>Anže Pečar</dc:creator>
      <pubDate>Wed, 17 May 2023 22:11:04 +0000</pubDate>
      <link>https://dev.to/anze3db/mastodon-instances-with-software-developers-26om</link>
      <guid>https://dev.to/anze3db/mastodon-instances-with-software-developers-26om</guid>
      <description>&lt;p&gt;If you are a software engineer or someone learning or interested in software development you might want to create an account on an instance with other software developers so that your local timeline is full of relevant content.&lt;/p&gt;

&lt;p&gt;For &lt;a href="https://fedidevs.com/"&gt;Fedidevs&lt;/a&gt; I have indexed some of the most popular Mastodon instances and used regexes to try and find accounts that belong to software developers.&lt;/p&gt;

&lt;p&gt;I indexed only a small percentage (0.225% by my count 😅) of all Mastodon instances, but this set of instances includes the majority of English-speaking users on Mastodon (see the full list of instances in the &lt;a href="https://fedidevs.com/faq/"&gt;FAQ page&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  The results
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Count   Instance
2963    mastodon.social
1083    hachyderm.io
513     mastodon.online
447     ruby.social
441     mstdn.social
377     fosstodon.org
361     infosec.exchange
343     mas.to
335     phpc.social
258     techhub.social
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No surprise that &lt;a href="https://mastodon.social"&gt;mastodon.social&lt;/a&gt; is on top here. It's one of the largest Mastodon instances with more than 1 million users. That's 1/6 of Mastodon's total users according to &lt;a href="https://mastodon.help"&gt;mastodon.help&lt;/a&gt;. Even though &lt;a href="https://mastodon.social"&gt;mastodon.social&lt;/a&gt; has the most developers of any instance, it also has the most users so the percentage of developers is not that high and your local timeline will most likely not have content relevant to you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hachyderm.io"&gt;hachyderm.io&lt;/a&gt; is an LGBTQIA+ and BLM safe space focused on tech industry professionals worldwide.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mastodon.online/"&gt;mastodon.online&lt;/a&gt; is another very popular general purpose instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://phpc.social/"&gt;phpc.social&lt;/a&gt; and &lt;a href="https://ruby.social/"&gt;ruby.social&lt;/a&gt; are instances for people interested in Ruby and PHP programming languages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://fosstodon.org/"&gt;fosstodon.org&lt;/a&gt; a community for anyone interested in technology; particularly free and open source software. The custom emojis on this instance are amazing 👌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://infosec.exchange/"&gt;infosec.exchange&lt;/a&gt; focuses on info/cyber security. If that's what you are interested in this is probably the best instance for you!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://techhub.social"&gt;techhub.social&lt;/a&gt; is primarily for passionate technologists, but according to the instance description everyone is welcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breakdown by popular languages
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Python developers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Count   Instance
562 mastodon.social
294 hachyderm.io
124 fosstodon.org
108 mastodon.online
100 mas.to
99  infosec.exchange
97  mstdn.social
73  techhub.social
48  mastodon.gamedev.place
35  mastodon.worldCount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Python community has recently started to migrate away from Twitter and a lot of prominent Python community members no longer post on Twitter.&lt;/p&gt;

&lt;p&gt;Besides the two largest instances most Python developers seem to hang out on &lt;a href="https://fosstodon.org/"&gt;fosstodon.org&lt;/a&gt;. This is where some of the largest Python-related accounts live, including the &lt;a href="https://fosstodon.org/@ThePSF@fosstodon.org"&gt;official account&lt;/a&gt; for the Python Software Foundation, &lt;a href="https://fosstodon.org/@mkennedy@fosstodon.org"&gt;Michael Kennedy&lt;/a&gt;, &lt;a href="https://fosstodon.org/@brettcannon@fosstodon.org"&gt;Brett Cannon&lt;/a&gt;, and others.&lt;/p&gt;

&lt;h3&gt;
  
  
  JavaScript developers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Count   Instance
448 mastodon.social
299 hachyderm.io
95  techhub.social
89  mas.to
84  phpc.social
82  mastodon.online
74  fosstodon.org
73  mstdn.social
59  ruby.social
38  infosec.exchange

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

&lt;/div&gt;



&lt;p&gt;The top two largest instances for JavaScript developers are the same as the Python ones, but fosstodon.org isn't as popular with JavaScript developers as it is with Python developers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rust developers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Count   Instance
458 hachyderm.io
226 mastodon.social
57  mastodon.gamedev.place
52  mas.to
49  infosec.exchange
42  mastodon.online
38  fosstodon.org
30  mstdn.social
28  techhub.social
17  chaos.social
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rust developers seem to prefer &lt;a href="https://hachyderm.io"&gt;hachyderm.io&lt;/a&gt; over &lt;a href="https://mastodon.social"&gt;mastodon.social&lt;/a&gt; and it seems to be the only programming language with these instances switched.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ruby developers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Count   Instance
478 ruby.social
151 mastodon.social
118 hachyderm.io
25  mastodon.online
24  mas.to
18  mstdn.social
17  infosec.exchange
15  techhub.social
13  mastodon.world
12  fosstodon.org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No surprise that Ruby developers prefer the ruby Mastodon instance - &lt;a href="https://ruby.social"&gt;ruby.social&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  PHP developers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Count   Instance
370 phpc.social
200 mastodon.social
38  fosstodon.org
38  mas.to
36  hachyderm.io
31  mastodon.online
24  mstdn.social
15  infosec.exchange
13  mastodon.gamedev.place
12  techhub.social
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similar to Ruby developers PHP developers also have their instance &lt;a href="//phpc.social"&gt;phpc.social&lt;/a&gt;. Unlike the Ruby community, it seems like the PHP community is more spread out and the official PHP instance takes up a smaller percentage of users than the ruby.social instance in the Ruby community.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other popular languages
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://fedidevs.com/"&gt;Fedidevs&lt;/a&gt; also allows filtering by &lt;a href="https://fedidevs.com/java/"&gt;Java&lt;/a&gt;, &lt;a href="https://fedidevs.com/csharp/"&gt;C#&lt;/a&gt;, &lt;a href="https://fedidevs.com/golang/"&gt;Golang&lt;/a&gt;, and others. But the amount of accounts isn't as high as the ones listed in this article so I've omitted it for brevity. Let me know if you would still want to see the statistics for these in the comments below.&lt;/p&gt;

</description>
      <category>mastodon</category>
      <category>developers</category>
      <category>socialmedia</category>
      <category>programmers</category>
    </item>
    <item>
      <title>JSON in Python</title>
      <dc:creator>Anže Pečar</dc:creator>
      <pubDate>Sat, 01 Feb 2020 09:11:39 +0000</pubDate>
      <link>https://dev.to/anze3db/json-in-python-139o</link>
      <guid>https://dev.to/anze3db/json-in-python-139o</guid>
      <description>&lt;p&gt;The JavaScript Object Notation (JSON) is a lightweight data-interchange format that just so happens to be remarkably similar to Python's dict notation.&lt;/p&gt;

&lt;p&gt;The two are so similar that you can copy JSON and paste it in the middle of your Python program and it will usually work:&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="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_object&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;         &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_list&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;4.0e10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_string&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;         &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;escaping&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"\"&lt;/span&gt;&lt;span class="s"&gt; 🤔&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_object&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_list&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;40000000000.0&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_string&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;escaping&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'""&lt;/span&gt;&lt;span class="s"&gt; 🤔&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, this breaks down whenever you have those pesky booleans or nulls in your JSON:&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="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_null&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_bool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_second_bool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;Traceback &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;stdin&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;NameError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;null&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;defined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, you might be tempted to do a search and replace that turns &lt;code&gt;null&lt;/code&gt;, &lt;code&gt;true&lt;/code&gt; &amp;amp; &lt;code&gt;false&lt;/code&gt; into Python's &lt;code&gt;None&lt;/code&gt;, &lt;code&gt;True&lt;/code&gt; &amp;amp; &lt;code&gt;False&lt;/code&gt;, but that's tedious and gets really annoying if you want to copy paste back and forth. &lt;/p&gt;

&lt;p&gt;You could even be reasonable and use &lt;code&gt;json.loads&lt;/code&gt; but then your JSON would be a string and your editor would no longer color highlight it correctly:&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="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;span class="gp"&gt;...&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_null&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_bool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_second_bool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_null&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_bool&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_second_bool&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because colors are the most important thing in programming, there has to be a better way! And there is. Python allows us to use &lt;code&gt;null&lt;/code&gt;, &lt;code&gt;true&lt;/code&gt; and &lt;code&gt;false&lt;/code&gt; as regular variable names. This means that we can do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_null&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_bool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my_second_bool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_null&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_bool&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;my_second_bool&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Marvelous, isn't it? You can even put &lt;code&gt;null=None; true=True; false=False&lt;/code&gt; in a separate python file (let's call PJ.py as a shorthand for PythonJson). Now you can do:&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="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;PJ&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And your python file will be ready to accept JSON!&lt;/p&gt;

&lt;p&gt;Do make sure you wear a PJ like the one below when doing this, otherwise, people might think you are being serious 😅&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%2Ffarm2.staticflickr.com%2F1540%2F24600872031_e97aa55116_b.jpg" 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%2Ffarm2.staticflickr.com%2F1540%2F24600872031_e97aa55116_b.jpg" alt="#ViernesDePijamas"&gt;&lt;/a&gt;&lt;a href="https://www.flickr.com/photos/139114328@N06/24600872031" rel="noopener noreferrer"&gt;"#ViernesDePijamas"&lt;/a&gt;&lt;span&gt; by &lt;a href="https://www.flickr.com/photos/139114328@N06" rel="noopener noreferrer"&gt;mrl.itesm2&lt;/a&gt;&lt;/span&gt; is licensed under &lt;a href="https://creativecommons.org/licenses/by-nc-sa/2.0/?ref=ccsearch&amp;amp;atype=html" rel="noopener noreferrer"&gt;CC BY-NC-SA 2.0&lt;/a&gt;&lt;a href="https://creativecommons.org/licenses/by-nc-sa/2.0/?ref=ccsearch&amp;amp;atype=html" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Prefer Books Over Blog Posts</title>
      <dc:creator>Anže Pečar</dc:creator>
      <pubDate>Sat, 25 Jan 2020 21:38:30 +0000</pubDate>
      <link>https://dev.to/anze3db/prefer-books-over-blog-posts-io3</link>
      <guid>https://dev.to/anze3db/prefer-books-over-blog-posts-io3</guid>
      <description>&lt;p&gt;Learning how to become a better software developer is a daunting task. There is so much to learn and it seems like everything is changing constantly.&lt;/p&gt;

&lt;p&gt;Because of this, it's easy to dismiss books as a resource for advancing your skills. Surely everything that people wrote about 10 years ago cannot still be relevant today, right?&lt;/p&gt;

&lt;p&gt;Wrong!&lt;/p&gt;

&lt;p&gt;Even though frameworks and even programming languages come and go (or at least become less popular), the concepts behind them stay the same.&lt;/p&gt;

&lt;p&gt;The internet is an amazing resource for learning (especially dev.to 😉). But free resources in the form of a 700-word blog post usually cannot even scratch the surface of their topic. &lt;/p&gt;

&lt;p&gt;It's also really hard to separate good blog posts from bad ones especially if you are new to the topic they are discussing. Nobody reviews blog posts (the comment section on hackernews excluded). It's even extremely rare to have someone proofread a blog post before posting (yes, nobody proofread this 😅).&lt;/p&gt;

&lt;p&gt;Books, on the other hand, are a lot more work. They are written, proofread, edited, rewritten, approved and finally published and printed. Now all of this doesn't necessarily mean that the content is going to be good, but that's where book reviews come in.&lt;/p&gt;

&lt;p&gt;As software developers, we will never be able to stop learning. When investing our time we have to make sure it's well spent. Because of this I strongly recommend you prioritize reading books over blog posts. Of course, read everything that you can or want, but try to spend more time on books than blogs. &lt;/p&gt;

&lt;p&gt;If you don't know where to start, here's a quick list of books that I think are worth your time. All of them have been published for a long time and are still very much relevant today.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Pragmatic Programmer by David Thomas, Andrew Hunt&lt;/li&gt;
&lt;li&gt;The Phoenix Project by Gene Kim, Kevin Behr (also see The Unicorn Project that came out late last year)&lt;/li&gt;
&lt;li&gt;The Mythical Man-Month by Fred Brooks&lt;/li&gt;
&lt;li&gt;Code by Charles Petzold&lt;/li&gt;
&lt;li&gt;Design Patterns by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides&lt;/li&gt;
&lt;li&gt;Refactoring by Martin Fowler&lt;/li&gt;
&lt;li&gt;Test-Driven Development by Kent Beck&lt;/li&gt;
&lt;li&gt;Domain-driven design by Eric Evans&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have a book you think every developer should read? Let me know about it in the comments!&lt;/p&gt;

</description>
      <category>books</category>
      <category>codenewbie</category>
      <category>learning</category>
    </item>
    <item>
      <title>Prefer Model.DoesNotExist over ObjectDoesNotExist in Django</title>
      <dc:creator>Anže Pečar</dc:creator>
      <pubDate>Sat, 09 Nov 2019 09:00:06 +0000</pubDate>
      <link>https://dev.to/anze3db/prefer-model-doesnotexist-over-objectdoesnotexist-in-django-4lb3</link>
      <guid>https://dev.to/anze3db/prefer-model-doesnotexist-over-objectdoesnotexist-in-django-4lb3</guid>
      <description>&lt;p&gt;In Django it's very common to see code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.contrib.auth.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.core.exceptions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ObjectDoesNotExist&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;myproject.apps.teams.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Team&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1337&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Team&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1337&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;ObjectDoesNotExist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User or Team does not exist"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code will try to fetch an auth user and a team from the database and if either of those does not exist, we'll just log an error. This is so common that I never thought twice when seeing or writing it.&lt;/p&gt;

&lt;p&gt;But it turns out that there is a slightly better way to accomplish the same result. I didn't know this before recently, but the Django Model class has its own &lt;code&gt;DoesNotExist&lt;/code&gt; exception! We can use it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.contrib.auth.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;myproject.apps.teams.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Team&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1337&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Phone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1337&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DoesNotExist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User does not exist"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;Phone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DoesNotExist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Phone does not exist"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is better for a couple of reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The two except blocks are now more explicit and will only catch exceptions when the specific model does not exist. &lt;/li&gt;
&lt;li&gt;This is minor, but you don't have to worry if ObjectDoesNotExist is already imported in the current scope or not.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;MultipleObjectsReturned&lt;/code&gt; exception is implemented the exact same way and if you are curious to learn how Django implements a new Exception type for every subclass that you make, you can check out &lt;a href="https://github.com/django/django/blob/85efc14a2edac532df1a9ad4dd9b6d4a4dcf583e/django/db/models/base.py#L124-L141"&gt;the source code here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My day job codebase currently has 231 occurrences of except ObjectDoesNotExist. I'll slowly start replacing them with model.DoesNotExist 😊&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
    </item>
    <item>
      <title>Reduce Batch Size</title>
      <dc:creator>Anže Pečar</dc:creator>
      <pubDate>Mon, 02 Sep 2019 22:04:46 +0000</pubDate>
      <link>https://dev.to/anze3db/reduce-batch-size-3ihc</link>
      <guid>https://dev.to/anze3db/reduce-batch-size-3ihc</guid>
      <description>&lt;p&gt;In the article in the series we learned how important it is to reduce the friction in code reviews, by making code reviews your top priority. Based on the &lt;a href="https://en.wikipedia.org/wiki/Theory_of_constraints"&gt;theory of constraints&lt;/a&gt;, not working on the bottleneck is counterproductive. If your code review queue is backed up, writing more code will not make you deploy features any faster!&lt;/p&gt;

&lt;p&gt;The theory of constraints doesn't only help us figure out what to focus on, but it also has a solution for increasing throughput: Decrease your batch size as much as possible. For us developers, the batch size is the number of code changes that go into each release.&lt;/p&gt;

&lt;p&gt;If you are reviewing, testing, and deploying multiple thousands of line changes to save time and increase feature velocity the result you'll get might be the exact opposite. By batching so many changes and features together you increase the lead time for each change. Lead time is one of the four key software delivery metrics according to &lt;a href="https://www.goodreads.com/en/book/show/35747076-accelerate"&gt;Accelerate 2018&lt;/a&gt; (other 3 are deployment frequency, time to restore service and change failure rate) and is closely correlated with company performance according to the studies conducted in &lt;a href="https://www.goodreads.com/en/book/show/35747076-accelerate"&gt;Accelerate 2018&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Putting it plainly, your big releases prevent small fixes and changes from going out sooner. Bigger releases require more testing, more preparation for deployment and it makes the process even slower. This is how you end up on a release schedule that can take months, is always late, and causes havoc when deployed to production in the form of blocker bugs.&lt;/p&gt;

&lt;p&gt;Let's focus on the code review side of things and take a look at why big pull requests are never desired. &lt;/p&gt;

&lt;h1&gt;
  
  
  Problem with big pull requests
&lt;/h1&gt;

&lt;p&gt;Developers have this joke that a 5 line pull request will have at least 5 comments or change requests while a 1000 line pull request will be accepted immediately with the words "looks good to me".&lt;/p&gt;

&lt;p&gt;This is because to properly review those 1000 lines, the reviewer needs to invest a lot of their own time to fully understand the scope of the changes. Those 1000 lines could even be too much for any reviewer to fully comprehend since the number of things that a human brain can keep track of is limited to &lt;a href="https://phys.org/news/2009-11-brain-magic.html"&gt;about 7 items&lt;/a&gt;. Often the sheer size of the changes will, at the very least, demotivate the reviewer from doing a good job.&lt;/p&gt;

&lt;p&gt;It's often the case that those 1000 lines or more don't change just one aspect of the system. They are usually a group of changes combined to form a whole. Grouping them might be an efficient way for the developer to implement these changes, but usually isn't an efficient way to review, test or deploy them.&lt;/p&gt;

&lt;p&gt;Let's take a look at how big pull requests can be broken down into smaller ones that are easier to review, test, and deploy.&lt;/p&gt;

&lt;h1&gt;
  
  
  Avoid batching features in a single pull request
&lt;/h1&gt;

&lt;p&gt;We are often tempted to fix or complete multiple tasks while working on a particular part of the codebase and then combine all those changes in a single pull request. &lt;/p&gt;

&lt;p&gt;An example of this could be a pull request that fixes a production issue &lt;em&gt;and&lt;/em&gt; improves logging around that issue.&lt;/p&gt;

&lt;p&gt;When reviewing this pull request a potential problem with the code that adds the logging could delay the merge of the code that fixes a production issue. Your users will be stuck with the bug while you are fixing a logging issue that your users don't even know exists. &lt;/p&gt;

&lt;p&gt;When you write &lt;em&gt;and&lt;/em&gt; in your PR title consider opening two pull requests instead. This will help the reviewer focus on one problem at the time, making it less likely for mistakes to go through.&lt;/p&gt;

&lt;p&gt;This point is even more severe if the issue pops up only when the code is deployed. If there is an issue with the logging code, you might have to revert the bugfix as well to resolve the problem. Not a good place to be in.&lt;/p&gt;

&lt;h1&gt;
  
  
  Small code batches
&lt;/h1&gt;

&lt;p&gt;If you had been burnt by the issue above and then decided to vigilantly deploy only one feature at a time, you still occasionally run into issues. Features that are useful to your customers tend not to be just a change to a few lines of code. Instead, they require days or even weeks of work before they become useful.&lt;/p&gt;

&lt;p&gt;Checking in code after weeks of work tends to be painful. You'll be working on a feature branch and will need to deal with merges and conflicts. And in the end, you'll have a big merge into your master branch, followed by the big deployment of what was probably months of work put into a feature branch.&lt;/p&gt;

&lt;p&gt;The only solution to this is to decouple features from code changes.&lt;/p&gt;

&lt;h1&gt;
  
  
  Decouple Features From Code Changes
&lt;/h1&gt;

&lt;p&gt;The only way to address these issues is to avoid having long-running feature branches in the first place. Instead, all the changes should be reviewed and merged into your develop branch as soon as possible. This means deploying code that's not yet ready to be run on production and is therefore hidden from the word in a form of a feature flag.&lt;/p&gt;

&lt;p&gt;LaunchDarkly raised $44 million this year helping programmers achieve exactly that, but in most cases, a simple &lt;code&gt;ENV&lt;/code&gt; variable or a setting flag should be all you need to make sure the feature is not enabled until the last piece is merged and deployed.&lt;/p&gt;

&lt;p&gt;The technique described above is called &lt;a href="https://trunkbaseddevelopment.com/"&gt;Trunk Based Development&lt;/a&gt; and it tries to address some issues of the &lt;a href="https://datasift.github.io/gitflow/IntroducingGitFlow.html"&gt;GitFlow&lt;/a&gt; development model. Most importantly it helps us reduce the batch size for code reviews and helping us speed up feature lead times.&lt;/p&gt;

&lt;p&gt;It isn't perfect, of course. Now that you are merging things into master immediately after review, you might end up with dead code in your codebase when the priorities of the project shift. Even if this code is guarded by feature flags it can still pop up in unexpected ways and cause a production issue if there is a problem with your configuration, so you will need to spend some time every few sprints to clean it up.&lt;/p&gt;

&lt;p&gt;Do you have a better way of dealing with big pull requests? Let me know in the comments below.&lt;/p&gt;

</description>
      <category>codequality</category>
      <category>devops</category>
      <category>codereview</category>
    </item>
    <item>
      <title>The Code Review Bottleneck</title>
      <dc:creator>Anže Pečar</dc:creator>
      <pubDate>Thu, 29 Aug 2019 10:34:29 +0000</pubDate>
      <link>https://dev.to/anze3db/the-code-review-bottleneck-49ig</link>
      <guid>https://dev.to/anze3db/the-code-review-bottleneck-49ig</guid>
      <description>&lt;p&gt;Code reviews are really useful, but the problem is that they have the nasty habit of making your cool new feature stuck in the queue waiting for reviewers. Let's take a look at how to make sure code reviews are done as efficiently as possible. Let's see how we can do quality code reviews without impeding feature velocity.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Bottleneck
&lt;/h1&gt;

&lt;p&gt;Code reviews are by their nature a bottleneck. They slow down the flow of features on their way to production. In this sense, they work against your goal to ship quality features to your customers as fast as possible. But because code reviews help your team ship fewer bugs and higher quality features they are worth the downside.&lt;/p&gt;

&lt;p&gt;The faster you can ship new features the better your company can adjust to new market trends and resolve user issues. Teams that can deliver in weeks outperform teams that deliver in months or even years.&lt;/p&gt;

&lt;p&gt;If your pull requests are pilling up and staying open for weeks it might be a sign that your process could use some improvement.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Wait Time
&lt;/h1&gt;

&lt;p&gt;The biggest issue with code reviews is the wait time.&lt;/p&gt;

&lt;p&gt;When the author of the code opens a pull request and marks it ready for review, they need to &lt;strong&gt;wait&lt;/strong&gt; until another person comes along and reviews it. This could be 1 hour after the pull request has been opened (if you are lucky) or it might take a few days or even weeks (if you are not lucky).&lt;/p&gt;

&lt;p&gt;After the first review is posted there is almost always a bit of wait time again, before the author sees the review, and then even more if the author needs to adjust the code based on the feedback.&lt;/p&gt;

&lt;p&gt;This process can go on for multiple cycles and every handoff adds another bit of wait time. This is how a simple feature that was ready 2 weeks ago still hasn't shipped yet.&lt;/p&gt;

&lt;p&gt;The wait time is especially painful for us programmers because, after each wait time, the context is lost and needs to be rebuilt again. The longer the wait time the more difficult it is to remember how all the code changes fit together into the shippable feature.&lt;/p&gt;

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

&lt;p&gt;There is only one way to resolve the wait time issue. It is to try to minimize it as much as possible. The best way to accomplish this is to make code reviews &lt;strong&gt;the top priority&lt;/strong&gt; for your team.&lt;/p&gt;

&lt;p&gt;When a pull request is ready for review, the reviewers should drop everything and focus on getting it reviewed and merged ASAP. The wait time between handoffs should be measured in minutes and not hours or days.&lt;/p&gt;

&lt;p&gt;When a pull request is reviewed and needs updates, the author should drop everything and focus on responding to comments. Again trying to limit the wait time to minutes and not hours if possible. If the review requires a substantial amount of code changes you should discuss it with reviewers to make sure changes will bring business value to customers.&lt;/p&gt;

&lt;p&gt;The "drop everything because of code reviews" rule is counter-intuitive for us developers. We like to be in the flow and don't want to break out of it for whatever reason. This is how we feel productive. Code reviews don't make us feel productive because we will not be credited when the feature ships. Usually, it's the author that will take all the credit.&lt;/p&gt;

&lt;p&gt;If you follow the rule of code reviews being the top priority your personal productivity will take a hit.&lt;/p&gt;

&lt;h1&gt;
  
  
  But the productivity of your team will soar
&lt;/h1&gt;

&lt;p&gt;Your personal productivity is not even remotely as important as the productivity of your team. Your team is most productive when it's shipping features to users. When a feature is ready for code review the developer is saying it's ready to be deployed to production. Your team's most important goal at this point needs to be to make sure the code is shippable.&lt;/p&gt;

&lt;p&gt;Anything other than doing the code review is counterproductive for your team. If you spend the rest of the day working on your feature instead of reviewing a pull request, you're blocking a feature from being deployed. Even worse, you are creating a new bottleneck and creating more work in progress which will cause even more context switching down the line.&lt;/p&gt;

&lt;p&gt;This is how pull requests pile up and feature velocity plummets.&lt;/p&gt;

&lt;p&gt;It's absolutely crucial to make the code reviews the top priority. When a code review comes in you need to stop all other nonproductive activity. This is pretty much anything except maybe firefighting a production issue affecting your customers.&lt;/p&gt;

&lt;p&gt;You will be my hero if you say that the current meeting needs to end earlier because you need to go review a newly opened pull request. 🤙&lt;/p&gt;

&lt;p&gt;In the next blog post, we'll take a look at some techniques you can use to make it possible to review and merge pull requests as quickly as possible. Spoiler: it's all about reducing the batch size!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>codequality</category>
      <category>codereview</category>
      <category>devops</category>
    </item>
    <item>
      <title>Code Reviews and the Company Goal</title>
      <dc:creator>Anže Pečar</dc:creator>
      <pubDate>Tue, 27 Aug 2019 00:07:49 +0000</pubDate>
      <link>https://dev.to/anze3db/code-reviews-and-the-company-goal-1j98</link>
      <guid>https://dev.to/anze3db/code-reviews-and-the-company-goal-1j98</guid>
      <description>&lt;p&gt;Code reviews are an important part of how we write code today. It's pretty rare to find a company that doesn't practice code reviews in some shape or form. If the drivers for doing code reviews in the company aren't engineers it's regulation. Code reviews have become a compliance requirement for some security standards (e.g. PCI DSS 3.0)!&lt;/p&gt;

&lt;p&gt;The popularity of code reviews is due to the fact that they bring multiple benefits to the engineering process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ability to catch code defects before the code is shipped to QA or prod.&lt;/li&gt;
&lt;li&gt;Sharing knowledge with the team.&lt;/li&gt;
&lt;li&gt;Increase a sense of mutual responsibility.&lt;/li&gt;
&lt;li&gt;Improve code quality.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Due to all these benefits, we engineers probably all agree that code reviews are necessary to ship stable code to production. But as engineers, we also need to keep in mind how our processes affect our companies. It's important that we ask ourselves how the code review process helps our companies achieve their goal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Goal
&lt;/h2&gt;

&lt;p&gt;According to Eliyahu M. Goldratt and his novel &lt;em&gt;The Goal&lt;/em&gt;, the goal of most companies is to make money:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Suddenly it strikes him that the Goal of his company is to make money! Anything that brings him closer to the Goal is productive. Hence, all other activities are non-productive!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even though The Goal talks about manufacturing and operating a manufacturing plant, most of the ideas apply to other types of processes as well. Read &lt;em&gt;The Phoneix Project&lt;/em&gt; to see how &lt;em&gt;The Goal&lt;/em&gt; can be applied to IT.&lt;/p&gt;

&lt;p&gt;Are code reviews actually a productive activity for the company? As mentioned above, they have a lot of benefits, but they also take precious engineering time away from writing code plus they increase the lead time for new features. Would it be more productive to use that time to write more code instead? The answer to this is no, but only if code reviews are conducted in an efficient manner. When done wrong, even though the intentions were good, they can actually have negative results.&lt;/p&gt;

&lt;h2&gt;
  
  
  A bad example
&lt;/h2&gt;

&lt;p&gt;The CTO of Acme inc is obsessed with code quality and sharing knowledge between the engineering team. So much so that the CTO proposes a process that requires every code change to be reviewed by all developers in the engineering department (more than 10 people!).&lt;/p&gt;

&lt;p&gt;What are the impacts of this new process to the company?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This new process will increase code quality as all these reviewers will find more issues with the code than a single or two reviewers ever could. 👍&lt;/li&gt;
&lt;li&gt;This new process will also increase knowledge sharing. Every engineer on the team will see every change going out. 👍&lt;/li&gt;
&lt;li&gt;But this process will make feature velocity grind to a halt. All the engineers will be too busy reviewing all the code! 👎&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The company will struggle if releasing new features to the customers will require this many reviews, so even though the intention was a noble one, it will actually hurt the company's goal.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The road to hell is paved with good intentions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have seen a much milder version of this first hand and it wasn't at all obvious that we were doing something counterproductive. We were just focusing on the wrong things when reviewing code, making code reviews too rigid and making the process take too much engineering time without bringing enough value.&lt;/p&gt;

&lt;p&gt;So to properly understand how to structure our code review process, let's look at all the main benefits from the list above and see how much value they bring to the company's goal. This will help us figure out what we need to focus on the most when reviewing code.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Catch code defects before the code is shipped to QA or prod
&lt;/h2&gt;

&lt;p&gt;During my career I have heard the following phrase multiple times:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Code reviews aren't there to catch bugs, we have the QA team for that.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But if you are looking at code reviews from the standpoint of the value that they bring to the company, detecting issues early is probably the biggest impact that a code review can make. It's definitely the only thing that the users will notice!&lt;/p&gt;

&lt;p&gt;Even if you have an amazing QA team that makes sure that bugs don't get deployed to production, there is still the value of finding bugs during the code review process. Fixing the bug found during code review will be much easier and quicker as it will require fewer people to be involved. You might not even need a Jira ticket for it! This will increase your turnaround time and make sure users get your new feature sooner. Quick turnaround time adds value to your company.&lt;/p&gt;

&lt;p&gt;Finding bugs is extremely important, but as a reviewer, you also shouldn't spend hours reviewing the code and trying out every edge case by hand. Instead, what you should do is focus on finding bugs when reading through the code as opposed to focusing on styling issues.&lt;/p&gt;

&lt;p&gt;Take special care when you see branches in the code path, ask yourself if both branches are covered by tests. Also, pay attention if the author forgot to handle an error case. When you see something that you think &lt;em&gt;might&lt;/em&gt; cause a bug, ask the author to write a test to cover that edge case.&lt;/p&gt;

&lt;p&gt;According to the company's goal, finding bugs early at the very least allows us to fix defects sooner, allowing us to deploy the new feature to the customers faster. It also helps make sure you don't slip a bug through the cracks and push it to production where it might annoy your users. From this perspective, finding a bug during the code review process is probably the most productive thing that you can do for your company.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Share knowledge with the team
&lt;/h2&gt;

&lt;p&gt;Every code review is a chance to learn something new. Both for the author of the code and for the reviewers. As a reviewer, you can learn how other people on your team solve problems. As the author, you get feedback on your work which is crucial for self-improvement.&lt;/p&gt;

&lt;p&gt;How does sharing knowledge help the goal of your company? It does very little to impact the users directly so this aspect of code reviews is in my opinion not as important as the one described in the previous chapter.&lt;/p&gt;

&lt;p&gt;But sharing knowledge still helps your company as it reduces the bus factor - the measurement of the risk resulting from information and capabilities not being shared among team members. It also integrates learning and self-improvement into your engineering process which is crucial for your company to grow.&lt;/p&gt;

&lt;p&gt;So make sure you look for ways to share knowledge when doing code reviews, but only after you are sure that you can't find any defects with the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Increase a sense of mutual responsibility
&lt;/h2&gt;

&lt;p&gt;Your whole team needs to own their code collectivity. If a single person is responsible for a part of the system it's a risk for your business as that person will be the bottleneck for every new feature that touches that part of the system. Bottlenecks like this can bring your feature velocity to a standstill, so it's always a good idea to see if you can reduce them.&lt;/p&gt;

&lt;p&gt;This doesn't directly impact the company's goal, but it can still have a huge impact indirectly. Make sure that you share as much knowledge as possible during the code review process to avoid bottlenecks like the one described above.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Improve code quality
&lt;/h2&gt;

&lt;p&gt;Code reviews are a good way to catch little improvements to the code. It feels great when you point out that a few lines of code can be deleted because there is already an existing function that does the same thing.&lt;/p&gt;

&lt;p&gt;But be careful, being overly pedantic about every little style issue can have negative impacts on the productivity of your team!&lt;/p&gt;

&lt;p&gt;I have seen requesting a whitespace delay the new feature from shipping for a few weeks because the change request made it miss the release window. Be mindful of how much company value is gained by making code style comments and perhaps rather invest some time to automate this into your test suite or the use of an autoformatter.&lt;/p&gt;

&lt;p&gt;Try to make sure code style issues are detected automatically, without human interaction. After that only mention styling issues only when there are no bugs to point out or there is no way to share knowledge. And if the reviewer doesn't agree with the change, don't persist.&lt;/p&gt;

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

&lt;p&gt;Be mindful of the company goal when doing code reviews. Ask yourself how much value your code review comment brings to the table. If you are asking to change some whitespace, the value will be very small. If you are asking to change the code that might misbehave under certain conditions exposing sensitive customer data, the value will be huge.&lt;/p&gt;

&lt;p&gt;When doing code reviews, try to write more comments with a higher value than lower value.&lt;/p&gt;

&lt;p&gt;Learned something new? Be sure to share what you've learned with your team. Sharing knowledge is one of the most important parts of your job 😉&lt;/p&gt;

&lt;p&gt;In the next blog post, I'll talk about how to make sure code reviews have as little impact on feature velocity as possible. Sign up below to get the article in your inbox as soon as it's ready.&lt;/p&gt;

</description>
      <category>codequality</category>
      <category>codereview</category>
      <category>productivity</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
