<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Grace Wong on Medium]]></title>
        <description><![CDATA[Stories by Grace Wong on Medium]]></description>
        <link>https://medium.com/@gwongz?source=rss-11c4fed2f32a------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*d93DvFQt9qj2AGsFyMKb-w.jpeg</url>
            <title>Stories by Grace Wong on Medium</title>
            <link>https://medium.com/@gwongz?source=rss-11c4fed2f32a------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 24 May 2026 02:28:23 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@gwongz/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[A practical use for namedtuples]]></title>
            <link>https://medium.com/two-factor-authenticity/a-practical-use-for-namedtuples-13a95b72dc95?source=rss-11c4fed2f32a------2</link>
            <guid isPermaLink="false">https://medium.com/p/13a95b72dc95</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[learning]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Grace Wong]]></dc:creator>
            <pubDate>Tue, 18 Aug 2015 17:37:13 GMT</pubDate>
            <atom:updated>2015-08-18T17:40:28.717Z</atom:updated>
            <content:encoded><![CDATA[<p>Tuples are great. Namedtuples are even greater.</p><p>The other day I had to make an update to our database schema because we started tracking the language developers use when they integrate their website with Clef.</p><p>Piece of cake right? We use Flask and SQLAlchemy so adding a column to our MySQL database is as easy as doing this:</p><pre>languages = db.Column(db.String(64))</pre><p>But we don’t want to allow just any string to be stored in this field. We want to restrict the data that’s persisted so we don’t end up in a situation where JavaScript can be represented as ‘javascript’, ‘JS’, and ‘JavaScript.’</p><p>So what’s the best way to do this?</p><p>Declaring a column of type <a href="http://docs.sqlalchemy.org/en/rel_0_9/core/type_basics.html#sqlalchemy.types.Enum"><em>Enum</em></a> (similar to a Django <em>ChoiceField</em>) would allow us to limit this field to a set of fixed string values.</p><pre>language_choices = (&#39;javascript&#39;, &#39;python&#39;, &#39;ruby&#39;, &#39;java&#39;, &#39;go&#39;)<br>language = db.Column(db.Enum(*language_choices))</pre><p>But it would also lock us in to a set of choices that could only be updated by running a migration. (There are also higher-level issues with using <em>Enum</em> — namely that it <a href="http://komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil/">violates normalization</a> by storing data in the column definition rather than the actual database fields.)</p><p>Whereas the <em>Enum</em> type is too rigid, a <em>String</em> type column is too permissive, so we needed to find a way to enforce some constraints. Luckily, Python’s <em>namedtuple</em> module makes this a breeze.</p><p>As its name suggests, a namedtuple assigns names, in addition to the numerical index, to each of its members. This allows us to have tuple-like objects whose contents can be accessed with dot-notation.</p><pre>from collections import namedtuple</pre><pre>LANGUAGES = [ &#39;javascript&#39;, &#39;python&#39;, &#39;ruby&#39;, &#39;java&#39;, &#39;go&#39;]<br>LANGUAGE_CHOICES = namedtuple(&#39;Languages&#39;, LANGUAGES)(*LANGUAGES)</pre><p>In the code above, we declare a namedtuple and specify its field names and then create an instance by unpacking the <em>LANGUAGES</em> array into positional arguments.</p><pre>&gt;&gt; print LANGUAGE_CHOICES<br>&gt;&gt; Languages(javascript=&#39;javascript&#39;, python=&#39;python&#39;, ruby=&#39;ruby&#39;, java=&#39;java&#39;, go=&#39;go&#39;)</pre><p>Now wherever we set the <em>language</em> attribute on the model, we can just use the constant we’ve created.</p><pre>model.language = LANGUAGE_CHOICES.python</pre><p>Or if we need to validate an input, we can easily do that with the <a href="https://docs.python.org/2/library/collections.html#collections.somenamedtuple._asdict"><em>_asdict()</em></a><em> </em>method that maps a namedtuple’s field names to corresponding values.</p><pre>selection = request.values.get(&#39;language&#39;)</pre><pre>if not LANGUAGE_CHOICES._asdict().get(selection):<br>    raise InvalidLanguageException(&#39;Invalid language&#39;)</pre><p>Now, if we want to update the list of languages we track, we only have to modify our constant instead of running a migration. This allows for a more sane database configuration while still maintaining data integrity.</p><p><em>Are you a fan of namedtuples? Show your love by sharing this!</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=13a95b72dc95" width="1" height="1" alt=""><hr><p><a href="https://medium.com/two-factor-authenticity/a-practical-use-for-namedtuples-13a95b72dc95">A practical use for namedtuples</a> was originally published in <a href="https://medium.com/two-factor-authenticity">Two Factor Authenticity</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>