<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Helmut.dev</title><link href="https://www.helmut.dev/" rel="alternate"></link><link href="https://www.helmut.dev/feeds/all.atom.xml" rel="self"></link><id>https://www.helmut.dev/</id><updated>2021-05-21T07:30:00+02:00</updated><subtitle>Better code</subtitle><entry><title>Understanding the difference between .get and .first in Django</title><link href="https://www.helmut.dev/understanding-the-difference-between-get-and-first-in-django.html" rel="alternate"></link><published>2021-05-21T07:30:00+02:00</published><updated>2021-05-21T07:30:00+02:00</updated><author><name>Helmut Irle</name></author><id>tag:www.helmut.dev,2021-05-21:/understanding-the-difference-between-get-and-first-in-django.html</id><summary type="html">&lt;p&gt;&lt;img alt="Photo" src="https://www.helmut.dev/get-vs-first.jpg"&gt;&lt;/p&gt;
&lt;p&gt;When retrieving a single record in Django, the ORM offers two possible methods: &lt;code&gt;.get()&lt;/code&gt; and &lt;code&gt;.first()&lt;/code&gt;. Let's learn how each one works and when to use them.&lt;/p&gt;
&lt;h4&gt;Get&lt;/h4&gt;
&lt;p&gt;Django's most basic way to retrieve a single record is &lt;a href="[QuerySet API reference | Django documentation | Django](https://docs.djangoproject.com/en/3.2/ref/models/querysets/#get)"&gt;the .get() method&lt;/a&gt;. It is used as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;burger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Menu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&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;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Beef Burger&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Quick facts about &lt;code&gt;.get()&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It retrieves only one record.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If no record exists that meets the given criteria, it raises a &lt;code&gt;DoesNotExist&lt;/code&gt; exception.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If more than one record with the given criteria exists, it raises a &lt;code&gt;MultipleObjectsReturned&lt;/code&gt; exception.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;First&lt;/h3&gt;
&lt;p&gt;A different way to get one record is …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Photo" src="https://www.helmut.dev/get-vs-first.jpg"&gt;&lt;/p&gt;
&lt;p&gt;When retrieving a single record in Django, the ORM offers two possible methods: &lt;code&gt;.get()&lt;/code&gt; and &lt;code&gt;.first()&lt;/code&gt;. Let's learn how each one works and when to use them.&lt;/p&gt;
&lt;h4&gt;Get&lt;/h4&gt;
&lt;p&gt;Django's most basic way to retrieve a single record is &lt;a href="[QuerySet API reference | Django documentation | Django](https://docs.djangoproject.com/en/3.2/ref/models/querysets/#get)"&gt;the .get() method&lt;/a&gt;. It is used as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;burger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Menu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&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;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Beef Burger&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Quick facts about &lt;code&gt;.get()&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It retrieves only one record.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If no record exists that meets the given criteria, it raises a &lt;code&gt;DoesNotExist&lt;/code&gt; exception.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If more than one record with the given criteria exists, it raises a &lt;code&gt;MultipleObjectsReturned&lt;/code&gt; exception.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;First&lt;/h3&gt;
&lt;p&gt;A different way to get one record is to use &lt;a href="[QuerySet API reference | Django documentation | Django](https://docs.djangoproject.com/en/3.2/ref/models/querysets/#first)"&gt;.first()&lt;/a&gt; on a QuerySet. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;burger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Menu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Beef Burger&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Quick facts about &lt;code&gt;.first()&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It will return the first item of a recordset.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If no record exists, it returns &lt;code&gt;None&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Handling unexpected situations&lt;/h3&gt;
&lt;h4&gt;Get&lt;/h4&gt;
&lt;p&gt;If Django's ORM can't return one record (i.e. there is either no record, or there are more than one), you have to catch the relevant exception. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Menu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&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;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Beef Burger&amp;quot;&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;Menu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DoesNotExist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Could not find a burger&amp;quot;&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;Menu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MultipleObjectsReturned&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Found too many burgers&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;First&lt;/h4&gt;
&lt;p&gt;When using &lt;code&gt;.first()&lt;/code&gt;, the only unexpected situation is if no record was present in the QuerySet. Since it's not a problem if multiple records exist that meet the criteria, we have to deal only with the one case. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;burger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Menu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Beef Burger&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;burger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Could not find a burger&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;burger&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Subtle differences&lt;/h3&gt;
&lt;p&gt;Did you notice the differences between the two above? For &lt;code&gt;.get()&lt;/code&gt; we have to deal with more "error" scenarios. But why is that? The &lt;code&gt;.get()&lt;/code&gt; method expects no more and no less than one record to be returned, whereas &lt;code&gt;.first()&lt;/code&gt; assumes there might be multiple records, and it returns the first. So we have a fundamental difference in the assumptions each of these makes.&lt;/p&gt;
&lt;p&gt;Should we care? Does it really make a difference which of the two methods we use if we get the same result?&lt;/p&gt;
&lt;p&gt;I used to think it didn't matter, but I was wrong.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Using &lt;code&gt;.get()&lt;/code&gt; might point to a problem with our Model that we are unaware of. If we are expecting only one record to be returned, but we get back multiple, we have failed to make sure that one of the fields (or multiple ones) enforce a &lt;a href="[Model field reference | Django documentation | Django](https://docs.djangoproject.com/en/3.2/ref/models/fields/#django.db.models.Field.unique)"&gt;unique constraint&lt;/a&gt;. Handling this at a database layer is crucial. If we had used &lt;code&gt;.first()&lt;/code&gt;, and had not added a unique constraint, we might have never noticed if there were multiple records where we are expecting only one.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;What about readability? I never thought about how the code reads in each case, and what it tells the reader about the data models. When you use &lt;code&gt;.get()&lt;/code&gt;, the reader will (or should) know immediately that the record should be unique for the fields you filtered on. However, if you use &lt;code&gt;.first()&lt;/code&gt;, it implies to the reader that multiple records might exist, but you only care about the first one.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;When to use which&lt;/h3&gt;
&lt;h4&gt;Get&lt;/h4&gt;
&lt;p&gt;Use &lt;code&gt;.get()&lt;/code&gt; when you are expecting only one (or a maximum of one) record to be returned. The code makes your intentions clear, and there's less room for undetected errors.&lt;/p&gt;
&lt;h4&gt;First&lt;/h4&gt;
&lt;p&gt;Use &lt;code&gt;.first()&lt;/code&gt; when you know there might be multiple records (and that's ok), but you only care about the first. In most cases you should also have some &lt;a href="[QuerySet API reference | Django documentation | Django](https://docs.djangoproject.com/en/3.2/ref/models/querysets/#django.db.models.query.QuerySet.order_by)"&gt;order&lt;/a&gt; defined &lt;a href="[Model Meta options | Django documentation | Django](https://docs.djangoproject.com/en/3.2/ref/models/options/#ordering)"&gt;on the model&lt;/a&gt; (or specified &lt;a href="[QuerySet API reference | Django documentation | Django](https://docs.djangoproject.com/en/3.2/ref/models/querysets/#django.db.models.query.QuerySet.order_by)"&gt;on your query&lt;/a&gt;), otherwise the first record might be random. In some cases you might not even care about the order, but just be aware of it. &lt;/p&gt;
&lt;h3&gt;Gotchas&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If you use &lt;code&gt;.first()&lt;/code&gt;, you run the risk of using the &lt;code&gt;None&lt;/code&gt; (in the case of no record found) as a different return data type to signify the fact that nothing was found. It's not very likely, but I've caught myself doing this. I wrote about that trap &lt;a href="https://www.helmut.dev/using-exceptions-instead-of-dynamic-typing.html"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The SQL query generated by &lt;code&gt;.get()&lt;/code&gt; does not have a limit. So if you have multiple records, before the &lt;code&gt;MultipleObjectsReturned&lt;/code&gt; exception is raised, your database will return all the records matching that criteria. But using &lt;code&gt;.first()&lt;/code&gt; adds a &lt;code&gt;LIMIT 1&lt;/code&gt; to your query, so it will only ever return one record. Be careful which one you choose.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;If you query the database and only ever expect one record (maximum) to be returned, don't use &lt;code&gt;.first()&lt;/code&gt;, but rather &lt;code&gt;.get()&lt;/code&gt; instead. You'll thank yourself later.&lt;/p&gt;</content><category term="Better Django"></category></entry><entry><title>Using Exceptions instead of Dynamic Typing</title><link href="https://www.helmut.dev/using-exceptions-instead-of-dynamic-typing.html" rel="alternate"></link><published>2021-05-17T22:00:00+02:00</published><updated>2021-05-17T22:00:00+02:00</updated><author><name>Helmut Irle</name></author><id>tag:www.helmut.dev,2021-05-17:/using-exceptions-instead-of-dynamic-typing.html</id><summary type="html">&lt;p&gt;&lt;img alt="Photo" src="https://www.helmut.dev/using-exceptions-instead-of-dynamic-types.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Python's dynamic typing is great, right? You can just do whatever you want with variables. FREEDOM! ;-) This comes at a price though, and sometimes one we're not always aware of.&lt;/p&gt;
&lt;h3&gt;Trying not to fail&lt;/h3&gt;
&lt;p&gt;For years I took advantage of Python's dynamic typing by having functions return an error state via a different data type. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int_input&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int_input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;An integer must be provided&amp;quot;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;int_input&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And consuming this function would have looked like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;doubled_int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doubled_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;You did not provide an integer&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;

&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Photo" src="https://www.helmut.dev/using-exceptions-instead-of-dynamic-types.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Python's dynamic typing is great, right? You can just do whatever you want with variables. FREEDOM! ;-) This comes at a price though, and sometimes one we're not always aware of.&lt;/p&gt;
&lt;h3&gt;Trying not to fail&lt;/h3&gt;
&lt;p&gt;For years I took advantage of Python's dynamic typing by having functions return an error state via a different data type. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int_input&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int_input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;An integer must be provided&amp;quot;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;int_input&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And consuming this function would have looked like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;doubled_int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doubled_int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;You did not provide an integer&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;

&lt;span class="nb"&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="s2"&gt;&amp;quot;Your doubled value: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;doubled_int&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Seems kind of legit. Performance wise there shouldn't be any problems, right?&lt;/p&gt;
&lt;p&gt;But what we're ignoring here is maintainability. This is an over-simplified example, but if you have longer functions with multiple return statements, and you're using more than just one data type to signify different things, this can quickly become a problem.&lt;/p&gt;
&lt;p&gt;If another developer has to use or modify this function somewhere down the line, it becomes more work to understand what the function is returning in which cases. They will need to read through the function in order to know which return types to expect, and what they mean.&lt;/p&gt;
&lt;h3&gt;The Catch&lt;/h3&gt;
&lt;p&gt;Can we improve on this? Can we make it easier for that developer to use or modify that function? I think there is a way, and that is using exceptions.&lt;/p&gt;
&lt;p&gt;Exceptions are a built-in part of Python, and for some reason, over the years, I made a habit of trying to avoid raising of exceptions. But in this case they can serve us pretty well. Our goal is to have a function that has a consistent return data type. And any problems are caught by said exceptions. If we now refactor the function above, we get this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int_input&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int_input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;An integer must be provided.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;int_input&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Simple, right? Instead of returning a string, we just raise an exception. So far we haven't complicated anything, but the benefit will become apparent in the next step. We are now going to consume this refactored function and catch the exception.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;doubled_int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;double&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&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="s2"&gt;&amp;quot;Your doubled value: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;doubled_int&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;You did not provide an integer&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Finally&lt;/h3&gt;
&lt;p&gt;So, what exactly happened? We use a try/catch block to catch this new exception that we raised. If everything goes well, our integer is doubled and printed to the screen. However, if we provided a wrong value, the exception is caught and we print an error to the screen.&lt;/p&gt;
&lt;p&gt;Have we gained anything? It has come at the cost of an extra line of code, but I think it's clear that we have gained in readability. For any Python developer it is now immediately clear that this function might result in an error, and it's also clear what happens in that case.&lt;/p&gt;
&lt;p&gt;Maintainability has also improved. Any future consumer of this function doesn't need to wonder about the different return types that they could/should be expecting. And if the function is modified, one can now just raise other exceptions if new error cases are added. Again, the return type stays consistent.&lt;/p&gt;</content><category term="Better Python"></category></entry><entry><title>Write better Django views</title><link href="https://www.helmut.dev/write-better-django-views.html" rel="alternate"></link><published>2021-03-12T07:00:00+02:00</published><updated>2021-03-12T07:00:00+02:00</updated><author><name>Helmut Irle</name></author><id>tag:www.helmut.dev,2021-03-12:/write-better-django-views.html</id><summary type="html">&lt;p&gt;&lt;img alt="image" src="https://www.helmut.dev/class-based.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Should you use class-based views (CBV's) or function-based views (FBV's) in Django? It seems a lot of people are pushing CBV's, touting them to be the "standard" way of writing views in Django. But why do FBV's still exist then? Just for backward-compatibility? This is my highly opinionated "view" (see what I did there??) on this matter.&lt;/p&gt;
&lt;p&gt;The topic is hotly debated. Why are some people so passionate about CBV's? CBVs are said to be better because they abstract a lot of boiler-plate code into base classes and mixins. This is true. As a very basic example, instead of writing …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="image" src="https://www.helmut.dev/class-based.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Should you use class-based views (CBV's) or function-based views (FBV's) in Django? It seems a lot of people are pushing CBV's, touting them to be the "standard" way of writing views in Django. But why do FBV's still exist then? Just for backward-compatibility? This is my highly opinionated "view" (see what I did there??) on this matter.&lt;/p&gt;
&lt;p&gt;The topic is hotly debated. Why are some people so passionate about CBV's? CBVs are said to be better because they abstract a lot of boiler-plate code into base classes and mixins. This is true. As a very basic example, instead of writing code to generate and return a rendered template, you can just use an existing base class for your view, and all you have to specify is the template name. And boom, Bob's your mother's cousin's uncle, twice removed. Seems like a no-brainer, right? We're saving at least 1-2 lines of code! (Yes, really)  &lt;/p&gt;
&lt;p&gt;But not all views are that simple. Soon you have CBVs that inherit from multiple base classes and mixins, you've overridden 7 methods of those classes, but your view still doesn't work. To figure out why, you read the documentation of all those classes, some of which have only their source code as documentation. You have 17 tabs open in your browser and it's a mess. Eventually you figure it out, and the problem was that the order in which those methods are run is different than what you expected. Is this all really worth it? Maybe you can figure these things out once, and then you just profit! But what about the next developer. They will read the code, and will have to go through the same process to figure out what is happening when and how. And if you don't touch that code again for the next months, will you remember these things next time?  &lt;/p&gt;
&lt;p&gt;I think you can see where I'm heading. One very important thing we're forgetting is the Zen of Python. In particular, I'm thinking of "Simple is better than complex", and "Explicit is better than implicit". CBVs are certainly not explicit. There's hidden stuff going on. A lot. And they are also not simple - there's a huge tree hierarchy behind the different base classes that Django provides. They hide tons of logic that is not obvious to the developer, and if you don't go and read that internal logic, you might have a hard time using those classes. But FBVs address these issues pretty well. They are explicit: you have one method that shows you all the logic, sequentially. And they are simple: there is no "API" that you need to know - no base classes that have complex, hidden logic. Ok, but what about the down-sides? What if you have many views with common logic? Then surely CBVs are the way to go? Yes and no. In a few cases I admit that CBVs could possibly, maybe, conceivably be beneficial. But for most cases FBVs will give you more advantages. And to reduce the repetition of common logic, there are alternative means.  &lt;/p&gt;
&lt;p&gt;I think the big issue is what we've been taught about abstraction and "DRY". Apart from solving a problem, those are the main things we do when coding. We actively look for things to abstract. And often (preaching to myself here mainly) we pull the trigger way too early. "Hey, this seems like a generic bit of code that we'll surely use again later!" is something I think to myself regularly. But at this point DRY is not even applicable yet, because we haven't repeated ourselves yet. But even if you find code in multiple places that is similar, we should be very careful to immediately create an abstraction. Instead, we should be thinking about how readable and maintainable that code would become as a result. And arguably, readability and maintainability will be more profitable to our employers than saving a few lines of code. Sometimes we should indeed abstract in order to reduce boiler-plate code, but when we do, we must do it veeeewy cawefuwy (my Elmer Fudd impression).&lt;/p&gt;
&lt;p&gt;I get it. There's hardly a better feeling for developers than when you've written a piece of very clever code, and it just works. It might enable other developers (or your future self) to handle similar cases with just a line or two of code, and the thought of that appeals to us. But what we're forgetting is that often "similar" cases are just different enough that the abstraction needs to be tweaked ever so slightly. And this carries on, until the abstraction is nothing short of a Frankenstein. We've all been there, right? So why do we still go down that path?&lt;/p&gt;
&lt;p&gt;Abstraction and DRY are at the heart of CBVs - and in most cases we save just a few lines of code. But it hurts the maintainability of the code in other ways. Future developers will spend hours figuring out the logic of the views, just so that there can be less code. Yes, fewer lines means less code to maintain. But often those fewer lines are harder to maintain because of the abstractions.&lt;/p&gt;
&lt;p&gt;There. I've said it. You might not agree, especially if you've used CBV's for many years, and you're so used to them that they are not an issue for you at all. Often, when we're used to something, we don't see the down-sides anymore. So I hope this has helped in that sense.&lt;/p&gt;
&lt;p&gt;Now, what I haven't done is SHOW you the differences between the two approaches, to prove the things I've claimed. But there's a resource that does a very, very excellent job at that, and you should go and read ALL of it, as soon as possible. It seriously blew my mind. My eternal thanks go to &lt;a href="https://twitter.com/spookylukey"&gt;Luke Plant&lt;/a&gt; for spending hours upon hours to create this.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://spookylukey.github.io/django-views-the-right-way/index.html" title="https://spookylukey.github.io/django-views-the-right-way/index.html"&gt;Django Views — The Right Way&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For extra credit, go and read up about the pitfalls of abstractions. Abstractions have their place, but sometimes we think that place is "everywhere". At least that's how I code at times. Anyway, enough now. Go forth and code simply and explicitly. ;-)&lt;/p&gt;</content><category term="Better Django"></category></entry><entry><title>Learn the subtle differences between Save and Update in Django</title><link href="https://www.helmut.dev/learn-the-subtle-differences-between-save-and-update-in-django.html" rel="alternate"></link><published>2021-02-12T07:10:00+02:00</published><updated>2021-02-12T07:10:00+02:00</updated><author><name>Helmut Irle</name></author><id>tag:www.helmut.dev,2021-02-12:/learn-the-subtle-differences-between-save-and-update-in-django.html</id><summary type="html">&lt;p&gt;To save data in Django, you normally use &lt;a href="[Model instance reference | Django documentation | Django](https://docs.djangoproject.com/en/3.1/ref/models/instances/#saving-objects)"&gt;.save()&lt;/a&gt; on a model instance. However the ORM also provides a &lt;a href="[QuerySet API reference | Django documentation | Django](https://docs.djangoproject.com/en/3.1/ref/models/querysets/#update)"&gt;.update()&lt;/a&gt; method on queryset objects. So which one should you use? Let's take a look at each, and then decide which one to use in which situations.&lt;/p&gt;
&lt;h3&gt;Save&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;.save()&lt;/code&gt; method is used to write a model instance to the database. It can be an existing record or even a new one. For an existing record, Django will run a SQL UPDATE  statement on the database. For a new record, Django will run an INSERT. &lt;a href="[Model instance reference | Django documentation | Django](https://docs.djangoproject.com/en/3.1/ref/models/instances/#how-django-knows-to-update-vs-insert)"&gt;Before Django 3.0&lt;/a&gt;, it would …&lt;/p&gt;</summary><content type="html">&lt;p&gt;To save data in Django, you normally use &lt;a href="[Model instance reference | Django documentation | Django](https://docs.djangoproject.com/en/3.1/ref/models/instances/#saving-objects)"&gt;.save()&lt;/a&gt; on a model instance. However the ORM also provides a &lt;a href="[QuerySet API reference | Django documentation | Django](https://docs.djangoproject.com/en/3.1/ref/models/querysets/#update)"&gt;.update()&lt;/a&gt; method on queryset objects. So which one should you use? Let's take a look at each, and then decide which one to use in which situations.&lt;/p&gt;
&lt;h3&gt;Save&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;.save()&lt;/code&gt; method is used to write a model instance to the database. It can be an existing record or even a new one. For an existing record, Django will run a SQL UPDATE  statement on the database. For a new record, Django will run an INSERT. &lt;a href="[Model instance reference | Django documentation | Django](https://docs.djangoproject.com/en/3.1/ref/models/instances/#how-django-knows-to-update-vs-insert)"&gt;Before Django 3.0&lt;/a&gt;, it would also do a SELECT before the INSERT, to make sure that the primary key doesn't exist (if one was given), and do an UPDATE instead if it found something.&lt;/p&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;new_book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;How to code&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Mike Lambda&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;new_book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&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;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Debugging like a pro&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When updating an existing record, Django will update every field. That means, if you changed only one field on the model instance (like the price in the example above), all the fields will be updated (with the values staying the same). This is rather inefficient, right? Especially if you model has many, many fields. And there's another problem. If there's a significant amount of time in between the fetching of the record and the saving of it, it is possible that another request will have updated one of the fields on that record, and your model instance still has the old value. If you call &lt;code&gt;.save()&lt;/code&gt; now, it will overwrite the new value that someone else saved. These two problems can be prevented by using the &lt;a href="[Model instance reference | Django documentation | Django](https://docs.djangoproject.com/en/3.1/ref/models/instances/#specifying-which-fields-to-save)"&gt;update_fields&lt;/a&gt; parameter. It expects a list of fields (as strings) that you want to save. So if you have only a few fields to save, use this parameter to prevent such data overwrite problems. The UPDATE that is run against the database then only updates those fields that you have specified.&lt;/p&gt;
&lt;p&gt;In the example above, it would change to:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;update_fields&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;price&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h4&gt;When to use Save&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;You are creating a new record (an alternative is using the &lt;a href="[QuerySet API reference | Django documentation | Django](https://docs.djangoproject.com/en/3.1/ref/models/querysets/#create)"&gt;.create()&lt;/a&gt; method).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You have a model instance already, and you need to change some field values.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You've overridden the &lt;code&gt;save&lt;/code&gt; method to include some custom model logic.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You've defined &lt;a href="[Signals | Django documentation | Django](https://docs.djangoproject.com/en/3.1/ref/signals/#pre-save)"&gt;pre_save&lt;/a&gt; and &lt;a href="[Signals | Django documentation | Django](https://docs.djangoproject.com/en/3.1/ref/signals/#post-save)"&gt;post_save&lt;/a&gt; signals for that model.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The changes you need to make are dynamic, based on current field values (e.g. incrementing a value - see the example above).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You want to update fields from a related model (like a &lt;a href="[Model field reference | Django documentation | Django](https://docs.djangoproject.com/en/3.1/ref/models/fields/#foreignkey)"&gt;ForeignKey&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Update&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;.update()&lt;/code&gt; method is available on each queryset object of the ORM. Using it will typically look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price__lt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This would update the price of all books that are below a certain price. While this is for a range of records, it could also be used as in our first example, to update a single record:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Debugging like a pro&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You'll notice that this doesn't increment the price like it does in the first &lt;code&gt;save&lt;/code&gt; example. You would need to use an &lt;a href="[Query Expressions | Django documentation | Django](https://docs.djangoproject.com/en/3.1/ref/models/expressions/#f-expressions)"&gt;F expression&lt;/a&gt; for that, but that's beyond the scope for now.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Update&lt;/code&gt; cannot be used to create a new record, like &lt;code&gt;save&lt;/code&gt; can.&lt;/p&gt;
&lt;h4&gt;When to use Update&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;You are updating fields of one or many records&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You don't need to re-use a model instance after updating&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You don't need your overridden &lt;code&gt;save&lt;/code&gt; method or any &lt;code&gt;pre_save&lt;/code&gt; or &lt;code&gt;post_save&lt;/code&gt; signals to run&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You know what your new field values must be without having retrieved the record(s)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;If you need to update field values, without any other model logic needing to be run, and you know what the changes will be without fetching the record(s) first, use &lt;code&gt;update&lt;/code&gt;. The SQL that is run against the database will be more efficient. However, if you need to, or have already, loaded the record from the database, and you possibly need the change to be dynamic based on existing data, or there's attached model logic that needs to run, use &lt;code&gt;save&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I hope this has been helpful to you. If you have any questions or comments, please don't hesitate to reach out to me. I'd be glad to have a chat.&lt;/p&gt;</content><category term="Better Django"></category></entry><entry><title>Results - VS Code vs PyCharm</title><link href="https://www.helmut.dev/results-vs-code-vs-pycharm.html" rel="alternate"></link><published>2021-02-02T07:00:00+02:00</published><updated>2021-02-02T07:00:00+02:00</updated><author><name>Helmut Irle</name></author><id>tag:www.helmut.dev,2021-02-02:/results-vs-code-vs-pycharm.html</id><summary type="html">&lt;p&gt;I asked Reddit about text editors vs IDEs. In particular, I asked VS Code users why they preferred it over IDEs like PyCharm, and then I asked PyCharm users why they preferred it over text editors like VS Code. The results were very interesting.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.reddit.com/r/Python/comments/kwbck9/vscode_users_why_do_you_prefer_it_over_pycharm/"&gt;VSCode users: Why do you prefer it over PyCharm?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.reddit.com/r/Python/comments/kxoflx/pycharm_users_why_do_you_prefer_it_over_vscode_or/"&gt;PyCharm users: Why do you prefer it over VSCode or other editors?&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Results: VS Code&lt;/h3&gt;
&lt;p&gt;Among VS Code users, the following reasons were listed most:&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="https://www.helmut.dev/vscode.png"&gt;&lt;/p&gt;
&lt;h3&gt;Results: PyCharm&lt;/h3&gt;
&lt;p&gt;And among PyCharm users, the following reasons were most common:&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="https://www.helmut.dev/pycharm.png"&gt;&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Looking at the above, I can conclude a few …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I asked Reddit about text editors vs IDEs. In particular, I asked VS Code users why they preferred it over IDEs like PyCharm, and then I asked PyCharm users why they preferred it over text editors like VS Code. The results were very interesting.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.reddit.com/r/Python/comments/kwbck9/vscode_users_why_do_you_prefer_it_over_pycharm/"&gt;VSCode users: Why do you prefer it over PyCharm?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.reddit.com/r/Python/comments/kxoflx/pycharm_users_why_do_you_prefer_it_over_vscode_or/"&gt;PyCharm users: Why do you prefer it over VSCode or other editors?&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Results: VS Code&lt;/h3&gt;
&lt;p&gt;Among VS Code users, the following reasons were listed most:&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="https://www.helmut.dev/vscode.png"&gt;&lt;/p&gt;
&lt;h3&gt;Results: PyCharm&lt;/h3&gt;
&lt;p&gt;And among PyCharm users, the following reasons were most common:&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="https://www.helmut.dev/pycharm.png"&gt;&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Looking at the above, I can conclude a few things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Users who work with multiple languages frequently prefer VS Code, whereas users who work mainly with Python prefer PyCharm.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Users who don't want to spend much time on set up and configuration prefer PyCharm, because of it's many out-of-the-box features.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Users who like flexibility prefer VS Code because of its vast plugin ecosystem that lets them add virtually any needed functionality.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The price of PyCharm Professional seems to be a significant factor.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PyCharm users say that such deep language integration cannot be found in any text editor.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I myself am a PyCharm Pro user. The price is worth it to me, and my top reasons why I prefer it are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Deep language integration: Even though Python support in VS Code is very good, PyCharm has even better integration. This ranges from smart autocomplete to stellar refactoring tools. To a limited degree, VS Code has these as well (with plugins), but PyCharm takes it to another level.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I like not having to look for and install multiple plugins before having the functionality I need. Plugins also make you dependent on 3rd parties, whereas in PyCharm everything is built-in and always works seamlessly.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content><category term="Misc"></category></entry><entry><title>Speed up bulk-exists check with python sets</title><link href="https://www.helmut.dev/speed-up-bulk-exists-check-with-python-sets.html" rel="alternate"></link><published>2020-08-01T08:00:00+02:00</published><updated>2020-08-01T08:00:00+02:00</updated><author><name>Helmut Irle</name></author><id>tag:www.helmut.dev,2020-08-01:/speed-up-bulk-exists-check-with-python-sets.html</id><summary type="html">&lt;p&gt;&lt;img alt="image" src="https://www.helmut.dev/bulk-exists-check.jpg"&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;.exists()&lt;/code&gt; function of Django's ORM is very useful. However, if you need to do this in bulk (think hundreds of thousands or more), this becomes a strain on your database. Let's say you are fetching records from an external system, and if the record doesn't exist locally, you need to do something:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;external_records&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;external_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="c1"&gt;# Do something&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you are working with a large quantity of records, this will flood your DB with queries. Instead, you could first pull all &lt;code&gt;external_id&lt;/code&gt; values from the DB:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;existing_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="image" src="https://www.helmut.dev/bulk-exists-check.jpg"&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;.exists()&lt;/code&gt; function of Django's ORM is very useful. However, if you need to do this in bulk (think hundreds of thousands or more), this becomes a strain on your database. Let's say you are fetching records from an external system, and if the record doesn't exist locally, you need to do something:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;external_records&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;external_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="c1"&gt;# Do something&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you are working with a large quantity of records, this will flood your DB with queries. Instead, you could first pull all &lt;code&gt;external_id&lt;/code&gt; values from the DB:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;existing_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;external_id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;external_records&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;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;existing_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Do something&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But again, for large volumes of data, this will be slow in terms of computing time. The trick is to use a &lt;code&gt;set&lt;/code&gt; instead of a &lt;code&gt;list&lt;/code&gt;. The python &lt;code&gt;in&lt;/code&gt; operator performs much, much better for sets, since items in sets are guaranteed to be unique. The above code thus becomes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;existing_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;external_id&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;external_records&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;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;existing_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Do something&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A very simple change that increases performance dramatically.&lt;/p&gt;
&lt;p&gt;(Code above can be found on &lt;a href="https://gist.github.com/psyonara/26e9098fc179cc6d4d406d7449fa26e1"&gt;GitHub&lt;/a&gt;)&lt;/p&gt;</content><category term="Better Django"></category></entry><entry><title>Early Exit</title><link href="https://www.helmut.dev/early-exit.html" rel="alternate"></link><published>2020-07-12T07:46:00+02:00</published><updated>2020-07-12T07:46:00+02:00</updated><author><name>Helmut Irle</name></author><id>tag:www.helmut.dev,2020-07-12:/early-exit.html</id><summary type="html">&lt;p&gt;&lt;img alt="Photo" src="https://www.helmut.dev/early-exit.jpg"&gt;&lt;/p&gt;
&lt;p&gt;You will have definitely come across the following pattern often:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;post_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;thing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;thing&amp;quot;&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;thing&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;setting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_user_setting&lt;/span&gt;&lt;span class="p"&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;thing&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;setting&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;permission&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_user_permission&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&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;permission&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;True&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;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_superuser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;DataPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="k"&gt;elif&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;is_staff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;DataPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&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="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;DataPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&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;thing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;thing&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;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Permission denied&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Setting not found&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Thing not specified&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;No data posted&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What is good about the code above? It follows the thought process that most developers would have: which conditions …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Photo" src="https://www.helmut.dev/early-exit.jpg"&gt;&lt;/p&gt;
&lt;p&gt;You will have definitely come across the following pattern often:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;post_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;thing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;thing&amp;quot;&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;thing&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;setting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_user_setting&lt;/span&gt;&lt;span class="p"&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;thing&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;setting&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;permission&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_user_permission&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&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;permission&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;True&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;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_superuser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;DataPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="k"&gt;elif&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;is_staff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;DataPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&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="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;DataPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&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;thing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;thing&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;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Permission denied&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Setting not found&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Thing not specified&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;No data posted&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What is good about the code above? It follows the thought process that most developers would have: which conditions must be met for me to execute the core logic of this feature? So I check each of those conditions and proceed if it is met. Then, in the middle of the code block, I have my core logic bundled up nicely. And at the end I deal with the cases where the conditions were not met.&lt;/p&gt;
&lt;p&gt;But are there any downsides?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The condition checks are quite disjointed. If you  want to see what happens when a condition is not met, you have to carefully follow the indentation down to where the corresponding &lt;code&gt;else&lt;/code&gt; is. This is not ideal, but often accepted by a lot of developers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The indentation can become very acute if there are many layers of conditions.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Is there a better way? Yes, there is: the early exit. Instead of following the thought process of "Which conditions must be met?", we rather ask "Which conditions can I eliminate right off the bat?" Here's how we would rewrite the code above:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;post_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;No data posted&amp;quot;&lt;/span&gt;

&lt;span class="n"&gt;thing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;thing&amp;quot;&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;thing&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Thing not specified&amp;quot;&lt;/span&gt;

&lt;span class="n"&gt;setting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_user_settig&lt;/span&gt;&lt;span class="p"&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;thing&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;setting&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Setting not found&amp;quot;&lt;/span&gt;

&lt;span class="n"&gt;permission&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_user_permission&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&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;permission&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Permission denied&amp;quot;&lt;/span&gt;

&lt;span class="k"&gt;if&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;is_superuser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;DataPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&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;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_staff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;DataPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;DataPoint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&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;thing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;thing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;        
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For each condition that is not met, we return immediately, since no further processing is necessary. And then at the end we have our core logic bundled up again.&lt;/p&gt;
&lt;p&gt;This does a few things for us.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;It still keeps the core logic in one place.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The conditions are also bundled up with their corresponding logic.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We don't have the indentation problem any more.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This may be just me, but I find the refactored code easier to read.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There is one caveat to this pattern: it mostly makes sense if you return something when a conditions is not met. If your application logic needs to &lt;em&gt;not&lt;/em&gt; return anything, but for example append an error message to a list instead (and then continue), the above might have to be structured differently.&lt;/p&gt;
&lt;p&gt;But you'll find tons of places where this pattern is applicable, and if it makes sense in your scenario, go ahead and use it liberally. It's awesome.&lt;/p&gt;
&lt;p&gt;(Code above can be found on &lt;a href="https://gist.github.com/psyonara/3cf53bc7f16e71030b5ad190214002d7"&gt;Github&lt;/a&gt;)&lt;/p&gt;</content><category term="Better Python"></category></entry><entry><title>Faster updating of dictionaries</title><link href="https://www.helmut.dev/faster-updating-of-dictionaries.html" rel="alternate"></link><published>2020-07-09T17:18:00+02:00</published><updated>2020-07-09T17:18:00+02:00</updated><author><name>Helmut Irle</name></author><id>tag:www.helmut.dev,2020-07-09:/faster-updating-of-dictionaries.html</id><summary type="html">&lt;p&gt;&lt;img alt="Photo" src="https://www.helmut.dev/faster-updating-of-dictionaries.jpg"&gt;&lt;/p&gt;
&lt;p&gt;When updating a dictionary, no one would object to this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Pete&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But what about this?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Tom&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;29&lt;/span&gt;
&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Linda&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;
&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Pam&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;
&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Coraline&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Still fine, right? There is another way of writing this, using the &lt;code&gt;.update()&lt;/code&gt; method.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;Tom&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;29&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;Linda&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;Pam&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;Coraline&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which one do you prefer? Would you say it's a matter of preference? I always preferred using the &lt;code&gt;.update()&lt;/code&gt; method when there were at least 3 updates being done. But one day I wondered about the performance of each method. Let's see if one is slower than …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Photo" src="https://www.helmut.dev/faster-updating-of-dictionaries.jpg"&gt;&lt;/p&gt;
&lt;p&gt;When updating a dictionary, no one would object to this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Pete&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But what about this?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Tom&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;29&lt;/span&gt;
&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Linda&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;
&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Pam&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;
&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Coraline&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Still fine, right? There is another way of writing this, using the &lt;code&gt;.update()&lt;/code&gt; method.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;Tom&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;29&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;Linda&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;Pam&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;Coraline&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which one do you prefer? Would you say it's a matter of preference? I always preferred using the &lt;code&gt;.update()&lt;/code&gt; method when there were at least 3 updates being done. But one day I wondered about the performance of each method. Let's see if one is slower than the other.&lt;/p&gt;
&lt;p&gt;Using Python's &lt;code&gt;timeit&lt;/code&gt;, we run the following code to test our first method. This updates the dictionary three times.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt; &lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Tom&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;29&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Linda&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Pam&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, using the same method, we test &lt;code&gt;.update()&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt; &lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Tom&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;29&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Linda&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Pam&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The results?&lt;/p&gt;
&lt;p&gt;Straight assignment: &lt;em&gt;225 nsec per loop&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Using &lt;code&gt;.update()&lt;/code&gt;: &lt;em&gt;522 nsec per loop&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;And the pattern stays linear with more keys.&lt;/p&gt;
&lt;p&gt;So we see that straight assignment is about twice as fast. Does that mean we never use &lt;code&gt;.update()&lt;/code&gt;? No. Like so many other things, it depends on your specific case.&lt;/p&gt;
&lt;h4&gt;The Case for Assignment&lt;/h4&gt;
&lt;p&gt;If you're updating a few keys, and your new data is not already gathered in a second dictionary, it probably makes sense to just use normal assignment.&lt;/p&gt;
&lt;h4&gt;The Case for Update&lt;/h4&gt;
&lt;p&gt;If you've got new data in a second dictionary (either a few items or many), and you'd like to update the first dictionary with these items, I would use the &lt;code&gt;.update()&lt;/code&gt; method. It makes for cleaner code.&lt;/p&gt;</content><category term="Better Python"></category></entry></feed>