<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Quality Software - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Quality Software - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 19 Jun 2026 16:02:58 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/quality-software/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ What I Learned from Reading "The Pragmatic Programmer" ]]>
                </title>
                <description>
                    <![CDATA[ By Pramono Winata In short: old but gold. Published in 1999, The Pragmatic Programmer is a book about how to become a Pragmatic Programmer. Which really means a ‘Good Programmer’.  Yes, it was published about 20 years ago. But this book still provide... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/thought-on-the-pragmatic-programmer/</link>
                <guid isPermaLink="false">66d460a03a8352b6c5a2aae5</guid>
                
                    <category>
                        <![CDATA[ books ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Quality Software ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 22 Jan 2020 16:28:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/01/51nz9ROuoHL-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Pramono Winata</p>
<p><em>In short: old but gold.</em></p>
<p>Published in 1999, The Pragmatic Programmer is a book about how to become a Pragmatic Programmer. Which really means a ‘Good Programmer’. </p>
<p>Yes, it was published about 20 years ago. But this book still provides many insights that are very relevant to programmers or software engineers, as some people might call them these days.</p>
<p>You might have heard about this book before and questioned what actually it's actually about. Well, today I will share with you some of the interesting things I learned while reading the book.</p>
<h2 id="heading-there-is-more-to-being-a-programmer-than-technical-skills">There is more to being a programmer than technical skills</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-190.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@alexkixa?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Alexandre Debiève / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>When reading the book's title, you might expect it to give out a lot of technical lessons. But in fact it does not. What makes this book still relevant 20 years later is that it teaches us that being a programmer is not all about technical strength. And we often overlook this fact.</p>
<p>The book teaches us that there is more to programming than technical abilities.</p>
<h2 id="heading-the-cat-ate-my-source-code">The cat ate my source code</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-191.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@chen93?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Chen Zhao / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>This is the first chapter in the book and is a very interesting concept.</p>
<p>Remember that one day when we didn’t finish our homework and we said that the dog ate it? (Actually I don’t remember it, because I always finish my homework ?)</p>
<p>What that - and this chapter - teaches us is actually responsibility. When you have responsibility for something, you should be prepared to be held accountable for it. </p>
<p>If you make mistakes and cannot fulfill those responsibilities, you have to make up for it and find a solution. Don’t make up excuses and play the finger pointing game. You can’t just go into work and tell everybody that <strong>a cat just ate your source code</strong>.</p>
<p><strong>Provide options, don’t make lame excuses.</strong></p>
<h2 id="heading-its-all-about-a-broken-window">It’s all about a broken window</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-192.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@pawel_czerwinski?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Paweł Czerwiński / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>In the book, there is a story about an urban area that became very messy and run-down, all because of one broken window.</p>
<p>This is much like our code: when we see some dirty code (which we can see like it's a broken window), we might start to think that it’s okay to let the code be dirty. That it’s okay to just go back later, which most of the time we never do. </p>
<p>Try not to leave “broken windows” unrepaired. When you find that kind of code, fix it up as soon as possible. When you continue to think that no one has the time to fix that broken code, you might as well go and buy yourself a dumpster just to keep your code.</p>
<p>What this chapter discusses is actually simple: it’s about <strong>initiative and taking care of your stuff</strong>.</p>
<h2 id="heading-take-the-initiative-be-the-catalyst">Take the initiative, be the catalyst</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-193.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@bradencollum?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Braden Collum / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>There also might be times when you know that either something is all good or something needs to actually get done. It comes to your mind and you just think to yourself that it’s the right thing to do. </p>
<p>If you just keep thinking, nothing will happen. Or if you just ask for it to be on the project timeline, you might be met with huge feature development requests and technical debt. So it ends up in another year in discussion.</p>
<p>It’s time to step up your game. Work out what you can, don’t overdo it, but also make it <strong>reasonable</strong>. Once you got your complete idea, show it to people. They might think that “Yeah, it might be better if we had that.” </p>
<p>Show them a glimpse of the future and people will rally around you. <strong>Be a catalyst for change</strong>.</p>
<h2 id="heading-more-so-this-book-also-teaches-us-about-basic-fundamentals-that-we-often-forget-as-programmers">More so, this book also teaches us about basic fundamentals that we often forget as programmers.</h2>
<p>Sometimes, the more we delve deeper and deeper into our work, the more often we forgot about the basic things that we learned a long time ago. </p>
<p>Busy chasing features and new tech improvements, we often forget that there are actually a lot more things that we need to pay attention to beforehand before going deeper.</p>
<h3 id="heading-clean-code">Clean code</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-194.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@4themorningshoot?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Oliver Hale / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>One of the most basic principles we often forget about is clean code. As features are piling up more and more, the codebase become fatter and technical debt rises. </p>
<p>But we must always remember to keep our code consistent and clean every time we write it. </p>
<p>One of the things that is mentioned in the book is the DRY principle (Don’t Repeat Yourself). It is related to code reusability. Duplication is evil and that's the truth. Duplicate code will make maintaining your code very hard, and it can cause confusion when you need to change a feature or fix a bug.</p>
<p>Remember that time when you needed to fix some of your code? And you realized that there was code that was very similar to the bit you just changed? So then you gotta change that part too, and another too, and then maybe this bit too…you get the picture.</p>
<h3 id="heading-find-the-correct-tools">Find the correct tools</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-195.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@carlevarino?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Cesar Carlevarino Aragon / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<p>Like a woodcutter, finding the correct and proper tools is very important. Before a woodcutter starts cutting trees. they have to decide - do they need a chainsaw? Or is an axe good enough? Or maybe there is a brand new lightsaber they can use. But using kitchen knife might take some time to cut down a tree.</p>
<p>It's similar for programmers: this book teaches us that it’s very important for us to find the proper tools before we start working (like a good code editor). We shouldn't jump right to coding. </p>
<p>For example, it’s actually possible to code using Windows notepad and compile it using the console. But is it the right tool for you? Try to find the best editor that you are most comfortable using. Learning and mastering it and it will increase your productivity by several times.</p>
<p>There are several editors mentioned in the book, such as Emacs or Vim. But nowadays you can find more modern code editors such as Visual Studio Code. Find one that suites you. It's like your taste in coffee – some people prefer lattes and others prefer cappuccinos.</p>
<h3 id="heading-dont-program-by-coincidence">Don’t program by coincidence</h3>
<p>This is one very important point noted in the book. In all of our programming journeys, there have likely been times when we were just coding blindly and unexpectedly… and somehow it just worked.</p>
<p>You probably weren't sure what you were actually doing, so you kept adding more and more code and it still worked. That is, until one day when there was an issue and you tried to remove some chunk of code and it completely broke everything. And you were not sure which piece caused it.</p>
<p>Relying on unknowns is very dangerous. When you are not sure what the code is supposed to do, try to simplify it and make sure that the code is reliable in its own right, not just reliable by chance.</p>
<p>Rely only on things you are sure of. Don’t program by coincidence.</p>
<h3 id="heading-unit-test">Unit test</h3>
<p>Testing is a hot topic these days. And yes, it was also an important topic 20 years ago (and it will always be).</p>
<p>But sometimes people forget about unit tests these days. They might have just finished their code and they assumed everything was okay...until the code ended up broken in production because of edge cases.</p>
<p>In order to maintain stability and refactor safely, we always need to keep our code protected by writing unit tests. And it’s never enough if your tests only cover the happy path. Perform ruthless testing on your code, and remember that your code is not finished until you've covered every available test. </p>
<p>Unit testing will help you be confident that your piece of code is truly done.</p>
<h3 id="heading-taking-ownership">Taking ownership</h3>
<p>There's one last thing I want to talk about. As we know, programmers like to leave ‘legacies’ behind, in the form of code. And yes, most of the time it’s bad.</p>
<p>Being a programmer, we ought to take pride in our own work. We should be proud of the responsibility we've been given and the piece of code we have been working on. </p>
<p>When we are finally able to take pride in our code and own it, we will be able to leave a good legacy behind. And people will see our code as a signature. When they see our code, they'll know that it will be solid and well-written, by a professional.</p>
<h2 id="heading-finishing-up">Finishing up</h2>
<p>There are even more topics covered in this book that I haven’t discussed here, such as Requirements and Teamwork. If you are interested in exploring these topics, you should try to find and read the book!</p>
<p>Just a note, however: as much as I liked the book, some stuff just didn't seem relate-able, looking at how old the book is (20 years old). It talks about old languages such as Prolog, and speaks about OOP like it’s a really new concept - so these oddities just don't seem right. </p>
<p>But it can’t be blamed since it's already a couple decades old.</p>
<p>Aside from that most of the stuff covered in the book is still quite relevant to the current age of Programming, like those topics I covered above.</p>
<p>If I was trying to sum everything up in this book, I'd say it basically covers <strong>everything I have ever read on the Web about becoming a better engineer</strong>.</p>
<p>Thanks for reading my article about The Pragmatic Programmer! Hopefully it has given you some insight into your journey as a Programmer or Software Engineer. And grab yourself a copy of the book if you are interested in learning more.</p>
<p><em>P.S. I wrote this article on my own, without any means of advertising or marketing from a third party. The cover photo was taken from <a target="_blank" href="https://www.amazon.com/Pragmatic-Programmer-Journey-Mastery-Anniversary/dp/B07TSG6FGJ">amazon's site</a>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How (and why) to embed domain concepts in code ]]>
                </title>
                <description>
                    <![CDATA[ Code should clearly reflect the problem it’s solving, and thus openly expose that problem’s domain. Embedding domain concepts in code requires thought and skill, and doesn't drop out automatically from TDD. However, it is a necessary step on the road... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/embedding-domain-concepts-in-code/</link>
                <guid isPermaLink="false">66bb925a867a396452a80286</guid>
                
                    <category>
                        <![CDATA[ Quality Software ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Code Quality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #Domain-Driven-Design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Cedd Burge ]]>
                </dc:creator>
                <pubDate>Tue, 12 Nov 2019 07:48:19 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/11/2015-Gran-Paradiso-007.JPG" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Code should clearly reflect the problem it’s solving, and thus openly expose that problem’s domain. Embedding domain concepts in code requires thought and skill, and doesn't drop out automatically from TDD. However, it is a necessary step on the road to writing easily understandable code.</p>
<p>I was at a software craftsmanship meetup recently, where we formed pairs to solve a simplified Berlin Clock Kata. A Berlin Clock displays the time using rows of flashing lights, which you can see below (although in the kata we just output a text representation, and the lights in a row are all the same colour).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/11/berlin-clock-2.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-initial-test-driven-solution">Initial Test Driven solution</h2>
<p>Most pairs used inside out TDD, and there were a lot of solutions that looked something like this (complete <a target="_blank" href="https://github.com/ceddlyburge/berlin-clock-initial-tdd-solution/blob/master/BerlinClock.py">code available on GitHub</a>).</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">berlin_clock_time</span>(<span class="hljs-params">julian_time</span>):</span>
    hours, minutes, seconds = list(map(int, julian_time.split(<span class="hljs-string">":"</span>)))

    <span class="hljs-keyword">return</span> [
        seconds_row_lights(seconds % <span class="hljs-number">2</span>)
        , five_hours_row_lights(hours)
        , single_hours_row_lights(hours % <span class="hljs-number">5</span>)
        , five_minutes_row_lights(minutes)
        , single_minutes_row_lights(minutes % <span class="hljs-number">5</span>)
    ]

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">five_hours_row_lights</span>(<span class="hljs-params">hours</span>):</span>
    lights_on = hours // <span class="hljs-number">5</span>
    lights_in_row = <span class="hljs-number">4</span>
    <span class="hljs-keyword">return</span> lights_for_row(<span class="hljs-string">"R"</span>, lights_on, lights_in_row)

<span class="hljs-comment"># ...</span>
</code></pre>
<p>This type of solution drops out naturally from applying inside out TDD to the problem. You write some tests for the seconds row, then some tests for the five hours row, and so on, and then you put it all together and do some refactoring. This solution does expose some of the domain concepts at a glance:</p>
<ul>
<li>There are 5 rows</li>
<li>There is one second row, 2 hour rows and 2 minute rows</li>
</ul>
<p>Some more concepts are available after a bit of digging, but aren't immediately obvious. The rows are made up of lights that can be on (or presumably off), and that the number of lights on is an indication of the time.</p>
<p>However there are some big parts of the problem that are not exposed. And since I haven't yet explained it, you probably don't know exactly how the Berlin Clock works yet.</p>
<h2 id="heading-elevate-the-concepts">Elevate the concepts</h2>
<p>To improve this we can bring some of the details that are buried in the helper functions (such as <code>get_five_hours</code>) closer to the top of the file. This brings you to something like the following (complete <a target="_blank" href="https://github.com/ceddlyburge/berlin-clock-elevated-concepts/blob/master/BerlinClock.py">code available on GitHub</a>), although the downside is that it breaks nearly all of the tests. Solutions like this are rarer on GitHub, but do exist.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">berlin_clock_time</span>(<span class="hljs-params">julian_time</span>):</span>
    hours, minutes, seconds = list(map(int, julian_time.split(<span class="hljs-string">":"</span>)))

    single_seconds = seconds_row_lights(seconds % <span class="hljs-number">2</span>)
    five_hours = row_lights(
        light_colour=<span class="hljs-string">"R"</span>,
        lights_on=hours // <span class="hljs-number">5</span>,
        lights_in_row=<span class="hljs-number">4</span>)
    single_hours = row_lights(
        light_colour=<span class="hljs-string">"R"</span>,
        lights_on=hours % <span class="hljs-number">5</span>,
        lights_in_row=<span class="hljs-number">4</span>)
    five_minutes = row_lights(
        light_colour=<span class="hljs-string">"Y"</span>,
        lights_on=minutes // <span class="hljs-number">5</span>,
        lights_in_row=<span class="hljs-number">11</span>)
    single_minutes = row_lights(
        light_colour=<span class="hljs-string">"Y"</span>,
        lights_on=minutes % <span class="hljs-number">5</span>,
        lights_in_row=<span class="hljs-number">4</span>)

    <span class="hljs-keyword">return</span> [
        single_seconds,
        five_hours,
        single_hours,
        five_minutes,
        single_minutes
    ]

<span class="hljs-comment"># ...</span>
</code></pre>
<p>This improves the concepts that are now exposed at a glance:</p>
<ul>
<li>There are 5 rows</li>
<li>The seconds row is a special case</li>
<li>There are 2 hour rows and 2 minute rows</li>
<li>The rows use different colour lights</li>
<li>The rows have a different number of lights</li>
</ul>
<p>This is pretty good, and is already better that most of the solutions out there. However, it's still a bit mysterious how the rows are related to each other (there are 2 rows to display the hours and the minutes, so presumably these are linked). It's also not obvious what amount of time each light represents.</p>
<h2 id="heading-name-implicit-concepts">Name implicit concepts</h2>
<p>At the moment some of the concepts (such as the amount of time each light represents) are implicit in the code. Making these explicit, and naming them, forces us to understand them and to embed that understanding in the code.</p>
<p>In order to make the amount of time each light represents explicit, it seems like it would be sensible to pass a <code>time_per_light</code> value to <code>row_lights</code>. This means we have to push the calculation of <code>lights_on</code> down into <code>row_lights</code>.</p>
<p>This in turn makes it obvious that there are two kinds of rows: one related to the quotient (<code>\\</code>) of the time value, and one related to the remainder / modulus (<code>%</code>). If we look at the quotient case, we see that the 2nd parameter to the operation is the <code>time_per_light</code>, which is 5 in both cases (5 hours in one case and 5 minutes in the other).</p>
<p>This allows us to write these rows like this:</p>
<pre><code class="lang-python">five_hour_row = row_lights(
    time_per_light=<span class="hljs-number">5</span>,
    value=hours, 
    light_colour=<span class="hljs-string">"R"</span>,
    lights_in_row=<span class="hljs-number">4</span>)
</code></pre>
<p>If we now turn our attention to the remainder case, we realise that <code>time_per_light</code> is always singular (one hour or one minute), as it is filling in the gaps in the quotient case. </p>
<p>For example, the five hours row can represent 0, 5, 10, 15, or 20 hours, but nothing in between. In order to represent any hour, there must be another row to represent +1, +2, +3 and +4. This means that this row must have exactly 4 lights, and that each light must represent 1 hour.</p>
<p>This implies that the remainder case is dependent on the quotient one, which most people would describe as a parent / child relationship.</p>
<p>With this knowledge in hand, we can now create a function for the child remainder rows, and the solution now looks like this (complete <a target="_blank" href="https://github.com/ceddlyburge/berlin-clock">code on GitHub</a>):</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">berlin_clock_time</span>(<span class="hljs-params">julian_time</span>):</span>
    hours, minutes, seconds = list(map(int, julian_time.split(<span class="hljs-string">":"</span>)))

    <span class="hljs-keyword">return</span> [
        seconds_row_lights(
            seconds % <span class="hljs-number">2</span>),
        parent_row_lights(
            time_per_light=<span class="hljs-number">5</span>,
            value=hours, 
            light_colour=<span class="hljs-string">"R"</span>,
            lights_in_row=<span class="hljs-number">4</span>),
        child_remainder_row_lights(
            parent_time_per_light=<span class="hljs-number">5</span>,
            value=hours,
            light_colour=<span class="hljs-string">"R"</span>),
        parent_row_lights(
            time_per_light=<span class="hljs-number">5</span>,
            value=minutes, 
            light_colour=<span class="hljs-string">"Y"</span>,
            lights_in_row=<span class="hljs-number">11</span>),
        child_remainder_row_lights(
            parent_time_per_light=<span class="hljs-number">5</span>,
            light_colour=<span class="hljs-string">"Y"</span>,
            value=minutes)
    ]

<span class="hljs-comment"># ...</span>
</code></pre>
<p>A quick glance at this code now reveals nearly all the domain concepts</p>
<ul>
<li>The first row represents the seconds and is a special case</li>
<li>On the second row each "R" light represents 5 hours</li>
<li>The third row shows the remainder from the second</li>
<li>On the fourth row each "Y" light represents 5 hours</li>
<li>The fifth row shows the remainder from the fourth</li>
</ul>
<p>This took something thinking about, which will have cost us some time / money. But we increased our understanding of the problem while we did it, and most importantly we embedded that knowledge in to the code. This means that the next person to read the code will not have to do this, which will save some time / money. Since we spend about 10 times longer reading code than we do writing it, this is probably a worthwhile endeavour.</p>
<p>Embedding this understanding has also made it harder for future programmers to make mistakes. For example, the concept of parent / child rows didn't exist in earlier examples, and it would be easy to mismatch them. Now the concept is plain to see, and the values are mostly worked out for you. It is also easier to refactor to support new clock variants, for example where lights in the first hours row represent 6 hours.</p>
<h2 id="heading-how-far-should-you-take-it">How far should you take it?</h2>
<p>There are things we can do to take this further. For example the <code>parent_time_per_light</code> of a child row must match the <code>time_per_light</code> of its parent, and there is nothing enforcing this. There is also a relationship between <code>time_per_light</code> and <code>lights_in_row</code> for the parent rows, and again it is not enforced. </p>
<p>However, at the moment we are only required to support one clock variant, so these probably aren't worth doing. When a change is required for the code, we should refactor so that the change is easy (which might be hard) and then make the easy change.</p>
<h2 id="heading-conclusions">Conclusions</h2>
<p>Embedding domain concepts in code requires thought and skill, and TDD won't necessarily do it for you. It takes longer than a naive solution, but makes the code easier to understand, and will very likely save time in the medium term. Time is money, and finding the right balance of spending time now versus saving time later is also an important skill for a professional programmer to have. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The Tangled World of Custom Data in WordPress ]]>
                </title>
                <description>
                    <![CDATA[ By Kamil Grzegorczyk Reducing Risk and Managing Your Custom Fields source https://pixabay.com Have you ever wondered how to properly name keys of WordPress custom fields? Does it make any difference? Should you care? What are the potential risks? Re... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-tangled-world-of-custom-data-in-wordpress-2ee8b57d49c/</link>
                <guid isPermaLink="false">66c36290ef766eb77cd787e1</guid>
                
                    <category>
                        <![CDATA[ PHP ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Quality Software ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ WordPress ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sat, 02 Dec 2017 01:07:07 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*ZdgftYvXborZxb4LL_WW8g.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Kamil Grzegorczyk</p>
<h4 id="heading-reducing-risk-and-managing-your-custom-fields">Reducing Risk and Managing Your Custom Fields</h4>
<p><img src="https://cdn-media-1.freecodecamp.org/images/T7IWEtq6emQ8ewTaeh51rey6BLxOwcWWD9E8" alt="Image" width="800" height="476" loading="lazy">
<em>source https://pixabay.com</em></p>
<p>Have you ever wondered how to properly name keys of <a target="_blank" href="https://wordpress.org">WordPress</a> custom fields? Does it make any difference? Should you care? What are the potential risks?</p>
<p>Recently I wrote a tutorial about filtering WordPress admin views. In the code, I named custom fields key like <code>kg_order_items</code>. You could ask why? Why not name it just <code>items</code>? Well… read below!</p>
<p>If you try to google for naming custom fields there is not so much information about it. Even the <a target="_blank" href="https://codex.wordpress.org/Custom_Fields">Codex entry</a> tells nothing about naming the field keys in a proper way. I found only <a target="_blank" href="https://support.advancedcustomfields.com/forums/topic/best-practice-for-name-the-fields/">one resource at ACF forums</a> that contains proper information.</p>
<p>If there is no problem, what is the fuss about? You could ask.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/FPg2xCt4KCRLjf4JzMlakYO1-fuN8qhrY63B" alt="Image" width="800" height="249" loading="lazy">
_Found on [http://dilbert.com](http://dilbert.com" rel="noopener" target="<em>blank" title=")</em></p>
<p>The days when WordPress was a simple CMS supporting small blog websites with only posts and pages are gone. Today even the smallest website uses a plethora of plugins and complex themes. And all of them bring new custom fields into the game.</p>
<p>The situation gets even worse if you use any of the fancy “premium” themes. Unfortunately, many of these are not well written and combine 1001 functions in one. Final result? Slow, not performant, and tangled site which looks nice only on demo content and stock images. And they <strong>add a lot</strong> of custom fields too.</p>
<h3 id="heading-danger">Danger!</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/m8se5ytEdXwvEddSjmVS3dVkmvy4XZ2x0TCr" alt="Image" width="581" height="407" loading="lazy">
<em>Source unknown</em></p>
<p>WordPress <code>wp_postmeta</code> table is very simple. It is a key-value pair attached to particular post_id. It means that all <strong>custom fields keys share a common namespace</strong>. That is especially true for the particular ID of the post.</p>
<p><strong>First example</strong><br>a) Imagine that your post has a “learn more” link. After you click the link it redirects you to a particular URL. The address is provided in a custom field. Let’s name the field key as <code>redirect_to</code>.</p>
<p>b) Now imagine that you install a plugin called for example “Redirect me, Honey”. The plugin is very, very simple. When the user enters the page it immediately redirects the user based on custom field setting attached to a post. Oh… and its field key is named <code>redirect_to</code> as well.</p>
<p>Result? After you activate the plugin, all of your posts with “learn more” button are redirecting users out of your website. And the reason why is not obvious at the first sight. It may even be unnoticed for quite a while.</p>
<p>This scenario is, of course, made up but the dangers are real. With thousands of plugins and thousands of themes available it’s just a matter of time to encounter such name collision.</p>
<p><strong>Second example</strong><br>WordPress can store multiple values for the same key name and post ID. (Unless you provide special parameter called <code>$unique</code>).</p>
<p>It means that if you save your data 5 times under the key <code>location</code> you will receive an array consisting of 5 elements when calling <code>get_post_meta().</code></p>
<p>Let’s assume that you have a post about the cities you have visited. You have been to 5 cities and those locations are shown on the embedded map in the post. Simple, right?</p>
<p>Attention! Not useful code ahead. ;) !</p>
<pre><code><span class="hljs-comment">//NYadd_post_meta($post_id, 'location', '40.7127753, 73.989308');</span>
</code></pre><pre><code><span class="hljs-comment">//LAadd_post_meta($post_id, 'location', '34.0522342, -118.2436849');</span>
</code></pre><pre><code><span class="hljs-comment">//Parisadd_post_meta($post_id, 'location', '48.856614, 2.3522219000000177');</span>
</code></pre><pre><code><span class="hljs-comment">//Viennaadd_post_meta($post_id, 'location', '48.2081743, 16.37381890000006');</span>
</code></pre><pre><code><span class="hljs-comment">//Romeadd_post_meta($post_id, 'location', '41.90278349999999, 12.496365500000024');</span>
</code></pre><pre><code><span class="hljs-comment">//Lets check what we have herevar_dump(get_post_meta($post_id, 'location');</span>
</code></pre><pre><code>array (size=<span class="hljs-number">5</span>)<span class="hljs-number">0</span> =&gt; string <span class="hljs-string">'40.7127753, 73.989308'</span> (length=<span class="hljs-number">21</span>)<span class="hljs-number">1</span> =&gt; string <span class="hljs-string">'34.0522342, -118.2436849'</span> (length=<span class="hljs-number">24</span>)<span class="hljs-number">2</span> =&gt; string <span class="hljs-string">'48.856614, 2.3522219000000177'</span> (length=<span class="hljs-number">29</span>)<span class="hljs-number">3</span> =&gt; string <span class="hljs-string">'48.2081743,16.37381890000006'</span> (length=<span class="hljs-number">28</span>)<span class="hljs-number">4</span> =&gt; string <span class="hljs-string">'41.90278349999999,12.496365500000024'</span> (length=<span class="hljs-number">36</span>)
</code></pre><p>What if after a while you use a new theme or plugin. It has a feature which can set the position of a post on a front page. You can pick between slider, sidebar or featured posts etc. This scenario may end up like this:</p>
<pre><code>array (size=<span class="hljs-number">6</span>) <span class="hljs-number">0</span> =&gt; string ‘<span class="hljs-number">40.7127753</span>, <span class="hljs-number">73.989308</span>’ (length=<span class="hljs-number">21</span>) <span class="hljs-number">1</span> =&gt; string ‘<span class="hljs-number">34.0522342</span>, <span class="hljs-number">-118.2436849</span>’ (length=<span class="hljs-number">24</span>) <span class="hljs-number">2</span> =&gt; string ‘<span class="hljs-number">48.856614</span>, <span class="hljs-number">2.3522219000000177</span>’ (length=<span class="hljs-number">29</span>) <span class="hljs-number">3</span> =&gt; string ‘<span class="hljs-number">48.2081743</span>,<span class="hljs-number">16.37381890000006</span>’ (length=<span class="hljs-number">28</span>) <span class="hljs-number">4</span> =&gt; string ‘<span class="hljs-number">41.90278349999999</span>,<span class="hljs-number">12.496365500000024</span>’ (length=<span class="hljs-number">36</span>) <span class="hljs-number">5</span> =&gt; string ‘left_sidebar’ (length=<span class="hljs-number">12</span>) <span class="hljs-comment">// Yeah, right…</span>
</code></pre><p>Or even worse:</p>
<pre><code>array (size=<span class="hljs-number">5</span>)  <span class="hljs-number">0</span> =&gt; string <span class="hljs-string">'left_sidebar'</span> (length=<span class="hljs-number">12</span>)  <span class="hljs-number">1</span> =&gt; string <span class="hljs-string">'left_sidebar'</span> (length=<span class="hljs-number">12</span>)  <span class="hljs-number">2</span> =&gt; string <span class="hljs-string">'left_sidebar'</span> (length=<span class="hljs-number">12</span>)  <span class="hljs-number">3</span> =&gt; string <span class="hljs-string">'left_sidebar'</span> (length=<span class="hljs-number">12</span>)  <span class="hljs-number">4</span> =&gt; string <span class="hljs-string">'left_sidebar'</span> (length=<span class="hljs-number">12</span>)
</code></pre><p>Your pretty little map <strong>is broken now!</strong> And you lost all of your entered data. Not funny right?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/UVx09NmJbiPAIBJ1GJ7CgaDLvClyDxRghgYS" alt="Image" width="800" height="533" loading="lazy">
<em>B-b-b-b-roken?? ;( source https://pixabay.com</em></p>
<h3 id="heading-solution">Solution</h3>
<p>You can never protect your custom fields data from being overwritten or deleted. This is how WordPress works and why it is so flexible. <strong>You can reduce that risk though</strong>.</p>
<p><strong>How?</strong><br>By avoiding common names and namespacing <strong>all</strong> your custom fields keys.</p>
<p>My proposed convention is:</p>
<ul>
<li><strong>cpt-name_field-name</strong><br>like <code>books_author</code> instead of <code>author</code>, <code>order_items</code> instead of <code>items</code>(solution for most lazy ones :) ).</li>
<li><strong>purpose_field-name</strong><br>like <code>front_page_location</code> instead of location, <code>visited_cities_locations</code>instead of <code>location</code>.</li>
<li><strong>prefix_(cpt-name/purpose)_field-name</strong><br>like <code>kg_books_author</code>, <code>kg_visited_cities_locations</code> (for the most strict ones).</li>
</ul>
<p>That is not all. Additionally, you should always take care of optional parameters of built-in WordPress functions:</p>
<ul>
<li><a target="_blank" href="https://codex.wordpress.org/Function_Reference/add_post_meta">add_post_meta()</a> has <code>$unique</code> to not add the custom field if it already exists.</li>
<li><a target="_blank" href="https://developer.wordpress.org/reference/functions/get_post_meta/">get_post_meta()</a> uses <code>$single</code> to retrieve only one record (if you expect only one record).</li>
<li><a target="_blank" href="https://codex.wordpress.org/Function_Reference/update_post_meta">update_post_meta()</a> and <a target="_blank" href="https://codex.wordpress.org/Function_Reference/delete_post_meta">delete_post_meta()</a> leverage <code>$previous_value</code> to ensure that you update/delete the key you want.</li>
</ul>
<p>Those parameters are helping in writing better, cleaner and more predictable code.</p>
<p>And that is not all. Use well tested, well written and extendable plugins like <a target="_blank" href="https://pods.io/">Pods Framework</a> or <a target="_blank" href="https://www.advancedcustomfields.com/">Advanced Custom Fields</a>. These will help manage your custom fields. They are great when it comes to managing the tangled world of your custom data.</p>
<h3 id="heading-summary">Summary</h3>
<p>In the ideal world, we should always be aware of what you are adding to the system. We should know what your plugins, themes, and custom functions are doing. That is unfortunately not always possible.</p>
<p>Therefore we should pay attention to the code we produce and tighten up all those loose ends.</p>
<p>That is all folks! I hope you liked it and have a great day!</p>
<p>This post was originally published on <a target="_blank" href="https://kamilgrzegorczyk.com/2017/10/12/best-practices-naming-convention-for-wordpress-custom-fields/">my private blog</a> where I write about WordPress and development in general.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
