<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alex Loukissas</title>
    <description>The latest articles on DEV Community by Alex Loukissas (@aloukissas).</description>
    <link>https://dev.to/aloukissas</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F244664%2F7a561ff8-94aa-4d60-97c3-55ab7655f52c.jpeg</url>
      <title>DEV Community: Alex Loukissas</title>
      <link>https://dev.to/aloukissas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aloukissas"/>
    <language>en</language>
    <item>
      <title>Programming principles from id software</title>
      <dc:creator>Alex Loukissas</dc:creator>
      <pubDate>Tue, 03 Mar 2020 22:58:03 +0000</pubDate>
      <link>https://dev.to/aloukissas/programming-principles-from-id-software-agh</link>
      <guid>https://dev.to/aloukissas/programming-principles-from-id-software-agh</guid>
      <description>&lt;p&gt;Probably the most iconic video game company of the 1990s, id Software developed such groundbreaking titles as Wolfenstein 3D, Doom, and Quake. In a somewhat recent &lt;a href="https://www.youtube.com/watch?v=KFziBfvAFnM"&gt;talk&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/John_Romero"&gt;John Romero&lt;/a&gt; (the co-founder of id), outlined the company’s programming principles that allowed them to produce so many quality titles, one after the other, in a very short time, with a very small team.&lt;/p&gt;

&lt;p&gt;Think of this as a companion to Lampson’s &lt;a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/acrobat-17.pdf"&gt;timeless paper&lt;/a&gt; on system design. Many of the principles are common and they are all quite relevant today.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uNIud6t0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2Aii_2Vb3H2h2cYJ-Jo46Taw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uNIud6t0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2Aii_2Vb3H2h2cYJ-Jo46Taw.png" alt="idsoft"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although these programming principles refer to video game development, most (if not all) apply to general software development. In this blog post, I outline my own interpretation of these principles, paired with screenshots from Romero’s own slides for reference. I also make an attempt to generalize each principle beyond game development. Here we go.&lt;/p&gt;

&lt;h1&gt;
  
  
  Principle 1: Just do it (and do it well).
&lt;/h1&gt;

&lt;p&gt;This doesn’t necessarily mean overly complicate your current version of the product. In fact, this may one way of describing the iterative development practice. Build something that does one thing really well and keep improving upon it constantly. Just keep your quality standards high in each iteration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nQgZtnKN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2AKQyLKrwQ1ZOgV0ShA5Q7-g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nQgZtnKN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2AKQyLKrwQ1ZOgV0ShA5Q7-g.png" alt="principle 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Principle 2: Keep your code always runnable.
&lt;/h1&gt;

&lt;p&gt;In his talk, Romero mentions how they had programmed the code to show an image of a bagel when the user hit an error loading a sprite. By adding good defaults/fallbacks, they made the game still playable. Had they not done this, the user would be blocked until the bug had been fixed (i.e. lost productivity hours). You can imagine how important this becomes as an engineering team grows larger. A practical example of this is using &lt;a href="https://reactjs.org/docs/react-component.html#defaultprops"&gt;defaultProps&lt;/a&gt; in ReactJS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ot9uhnX0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2AjzUA9sXQ8JMhgGND_DS5nQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ot9uhnX0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2AjzUA9sXQ8JMhgGND_DS5nQ.png" alt="principle 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Principle 3: Keep it simple.
&lt;/h1&gt;

&lt;p&gt;This is obviously not novel. Call it &lt;a href="https://en.wikipedia.org/wiki/Occam%27s_razor"&gt;Occam’s Razor&lt;/a&gt; or the &lt;a href="https://en.wikipedia.org/wiki/KISS_principle"&gt;KISS principle&lt;/a&gt;, keeping things as simple as possible is timeless great advice.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HPYuTxOB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2A-knGkhB9-svUq_ALOomctg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HPYuTxOB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2A-knGkhB9-svUq_ALOomctg.png" alt="principle 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Principle 4: Invest time in building great tools.
&lt;/h1&gt;

&lt;p&gt;In his talk, Romero mentioned that he built a level editor called TED. The time he spent building TED paid hefty dividends, since it immensely helped them rapidly ship one game after the other by boosting productivity. Since those days, there has been an explosion of developer tools that have helped boost developer productivity. But if something off-the-shelf doesn’t cut it, try to identify whether an internal tool can help your developers be at their most productive (even if it can take development resources off the main product).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GjiRSPFP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2A1yo20Dl80vcn0NaBrZN3xg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GjiRSPFP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2A1yo20Dl80vcn0NaBrZN3xg.png" alt="principle 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Principle 5: Test your code thoroughly.
&lt;/h1&gt;

&lt;p&gt;This covers many topics that many of the most effective engineering teams use as best practices: (a) &lt;a href="https://en.wikipedia.org/wiki/Eating_your_own_dog_food"&gt;dogfood&lt;/a&gt; your product as much as possible; (b) don’t delegate to others (e.g. QA engineers, or worse, customers) to find bugs in your code; (c) write as many tests as possible to accompany your code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VxT9nD2Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2As0TC6AsoH0zHyUZN3fayEg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VxT9nD2Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2As0TC6AsoH0zHyUZN3fayEg.png" alt="principle 5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Principle 6: Fix bugs as soon as possible.
&lt;/h1&gt;

&lt;p&gt;We are very strict about this at &lt;a href="https://agentrisk.com"&gt;AgentRisk&lt;/a&gt;, a practice we’ve carried over from our &lt;a href="https://en.wikipedia.org/wiki/Bugsense"&gt;previous&lt;/a&gt; &lt;a href="https://www.crunchbase.com/organization/maginatics"&gt;startups&lt;/a&gt;. During our daily stand-ups, we make sure that any new bugs have the highest priority and get fixed ASAP. Obviously, not all bugs are equal, so some business-related judgement is warranted here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9RQLKpGe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2Al3Eq0AznXZ4RsDzg6N1KEA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9RQLKpGe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2Al3Eq0AznXZ4RsDzg6N1KEA.png" alt="principle 6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Principle 7: Use a superior development system.
&lt;/h1&gt;

&lt;p&gt;This is one that may mostly apply to game development. In other cases, you may want to go the other route when it comes to testing during development. For example, you may have users running your application on a mobile device that has very inferior specs, or they may be accessing your web application over a high-latency 2G connection. Make sure they don’t have a sucky UX.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hYieQsT7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2AiS0G4708rW5kPTg7VcCuaQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hYieQsT7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2AiS0G4708rW5kPTg7VcCuaQ.png" alt="principle 7"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Principle 8: Write code for this version of the product.
&lt;/h1&gt;

&lt;p&gt;This mostly translates to “don’t transfer over limitations of your past code and its implementation to future code”. This is a tricky one and kind of ties with Principle 4 . As engineers, we are often tempted to “rewrite everything” from scratch. This is where having experienced engineering leadership is really important. Often, the choice to take the plunge and do a new implementation can pay dividends down the line (similar to building tools). For example, as Slack started scaling, they &lt;a href="https://softwareengineeringdaily.com/2020/02/27/slack-frontend-architecture-with-anuj-nair/"&gt;scraped their v1.0 implementation entirely&lt;/a&gt; and moved to a brand new architecture, reaping the rewards many times over. We also had a similar experience moving from Python to Elixir, having a much more robust codebase and much increased developer productivity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dpbWqMQf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2A83koVBQCrC2naxTx5FOTwQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dpbWqMQf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2A83koVBQCrC2naxTx5FOTwQ.png" alt="principle 8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Principle 9: Use good component abstractions.
&lt;/h1&gt;

&lt;p&gt;This is really hard. If you have ever built and maintained an API, you know how hard it is to get it right (especially the first time). In his talk, Romero gives the example of encapsulate the functionality of a torch together with the flame and other related objects. Had they needed to move or update all torch instances in a level, having more a granular abstraction could have led to e.g. forgetting to move/update a flame. Spend a lot of time on this and try to get this right the first time. There will be compounding rewards in development and debugging time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ekAciRQ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2AlorAsL0cIrrAjliw7A7nwQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ekAciRQ6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2AlorAsL0cIrrAjliw7A7nwQ.png" alt="principle 9"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Principle 10: Seek feedback from peers while coding.
&lt;/h1&gt;

&lt;p&gt;Using code review software can help with this. For more complex parts of a product, advance architecture review may be warranted. In any case, make sure you promote a culture that values communication and seeking feedback.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vG_eB2bE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2AWAfLN_j8YuEaAnLLwB-0JQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vG_eB2bE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2AWAfLN_j8YuEaAnLLwB-0JQ.png" alt="principle 10"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Principle 11: Give coders creative freedom.
&lt;/h1&gt;

&lt;p&gt;There are many ways to dice an onion. Give your coders the creative freedom to come up with their own solution to the problems they’re working on. Just make sure to enforce some coding standards, so that any member of the team can jump into the codebase. Getting caught up on coding aesthetics can waste valuable time, so it’s best to leave this to linters and auto-formatters. This does not mean that e.g. identifying suboptimal implementations in code reviews shouldn’t be encouraged. Just focus on things that are objectively wrong.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IrgaOv7K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2ABJdtLOgWkvrhDsu-YNgLxQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IrgaOv7K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/940/1%2ABJdtLOgWkvrhDsu-YNgLxQ.png" alt="principle 11"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Thanks for reading!
&lt;/h1&gt;

&lt;p&gt;I hope this has been useful. Below is a link to the entire talk. I suggest you also read &lt;a href="https://en.wikipedia.org/wiki/Masters_of_Doom"&gt;Masters of Doom&lt;/a&gt;, which gives a detailed back-story to id software. Many thanks to &lt;a href="https://twitter.com/jonromero"&gt;Jon V&lt;/a&gt; and &lt;a href="https://twitter.com/diwakergupta"&gt;Diwaker Gupta&lt;/a&gt; for their feedback on initial drafts of this.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/KFziBfvAFnM"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
    </item>
    <item>
      <title>You better work in cents, not dollars 💸</title>
      <dc:creator>Alex Loukissas</dc:creator>
      <pubDate>Sun, 23 Feb 2020 21:56:31 +0000</pubDate>
      <link>https://dev.to/aloukissas/you-better-work-in-cents-not-dollars-ngo</link>
      <guid>https://dev.to/aloukissas/you-better-work-in-cents-not-dollars-ngo</guid>
      <description>&lt;p&gt;When building an application, some lines of code are more important than others. Screw up your mutex logic and you may run into a deadlock or a race condition. Screw up a database query and you can wipe out an entire table. Screw up how you handle money, and someone will get short-changed (or even worse: you get fined by the SEC).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But how can you screw up how you handle money, you ask?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hint: you may have snoozed during that boring lecture where the professor was covering floating point arithmetic and scientific notation. Let’s have a quick refresher from Tom in the video below:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/PZRI1IfStY0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  Why using float to store money is a terrible idea
&lt;/h1&gt;

&lt;p&gt;I couldn’t have said it better than &lt;a href="https://twitter.com/billkarwin"&gt;Bill Karwin&lt;/a&gt;:&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--ADyZR5bH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/732570065665548288/pxH2yVzT_normal.jpg" alt="Bill Karwin profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Bill Karwin
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @billkarwin
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4t6ys1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      If I had a dime for every time I've seen someone use FLOAT to store currency, I'd have $999.997634. &lt;a href="https://twitter.com/hashtag/ieee754jokes"&gt;#ieee754jokes&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      03:49 AM - 20 Jun 2013
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=347561901460447232" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=347561901460447232" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      333
      &lt;a href="https://twitter.com/intent/like?tweet_id=347561901460447232" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      218
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;But let’s try this out! I’ll be using Python in the examples in this post, but this is not a Python-specific issue. This has to do with how computers represent numbers internally.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Rounding errors
&lt;/h2&gt;

&lt;p&gt;The reason issues like the one in the code above occur is due to &lt;strong&gt;rounding errors&lt;/strong&gt; when doing floating point arithmetic. Let’s repeat the example from the video above. Here we’re adding just two floating point numbers:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;If in either of these two examples you pull up your favorite calculator, you will get the “correct” answer, i.e. &lt;code&gt;0.1 + 0.2 = 0.3&lt;/code&gt; and &lt;code&gt;165 * 19.4 = 3201&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Hopefully, by now I should have convinced you that using float to store money is a bad idea. If you’re still not convinced, keep reading!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6SrCULG5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/xOpOgnu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6SrCULG5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/xOpOgnu.jpg" alt="mrmackey"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Always use integers to store money
&lt;/h1&gt;

&lt;p&gt;While float is the troubled child in the family, integer is the poster child that always behaves as it’s expected of her. In our case: &lt;strong&gt;no rounding errors&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does this work? What about cents?
&lt;/h2&gt;

&lt;p&gt;I think the primary reason we automatically use floats to represent money is that we more commonly think in a currency’s main unit, e.g. 19.4 dollars.&lt;/p&gt;

&lt;p&gt;But forget what Diddy and Biggie told you. It’s all about the cents.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To avoid rounding errors, you should store money in a currency’s smallest unit using an integer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, we’d represent 19.4 dollars as 1940 cents. Just make sure you use long integers, so you don’t run into &lt;a href="https://en.wikipedia.org/wiki/Integer_overflow"&gt;brand new problems&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Storing money in a currency’s smallest unit is a common software design pattern made popular by &lt;a href="https://martinfowler.com/eaaCatalog/money.html"&gt;Martin Fowler&lt;/a&gt; back in 2002. It’s even adopted by &lt;a href="https://stripe.com/docs/currencies#zero-decimal"&gt;Stripe in their APIs&lt;/a&gt;. That’s a pretty solid endorsement in my book.&lt;/p&gt;

&lt;p&gt;Let’s retry the code for the example above using this pattern:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Note that now that every monetary value is in cents, we need to be aware of that and properly format stored values into what the user expects to see.&lt;/p&gt;

&lt;p&gt;At minimum, we need to divide the stored value by 100:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; 320100 / 100
3201.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This is what we would expect as a result if we’d done the math by hand.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/xT5LMQRPHbTymgc5Bm/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/xT5LMQRPHbTymgc5Bm/giphy.gif" alt="lisa"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h1&gt;
  
  
  What’s better than an integer? A Money library.
&lt;/h1&gt;

&lt;p&gt;As we saw above, it may be easy to forget that monetary values are in cents and run into new problems in the presentation layer/UI. The best way to deal with this is to use a dedicated library (or class) for everything money-related.&lt;/p&gt;

&lt;p&gt;There are ton of great libraries that implement this pattern: &lt;a href="https://sarahdayan.github.io/dinero.js/"&gt;Dinero.js&lt;/a&gt; is a really great one for JavaScript as is &lt;a href="https://github.com/elixirmoney/money"&gt;Money&lt;/a&gt; for Elixir (the two main languages we use at AgentRisk). Surprisingly, I wasn’t able to find something for Python.&lt;/p&gt;

&lt;p&gt;The most &lt;a href="https://github.com/carlospalol/money"&gt;common one&lt;/a&gt; for Python is good, but it uses &lt;code&gt;Decimal&lt;/code&gt; to store values. While this is generally fine, we really wanted to stick with the Fowler pattern across all systems and languages and use integers to represent money everywhere.&lt;/p&gt;

&lt;p&gt;That’s why I decided to write my own and make it available on GitHub. You can check it out here: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/agentrisk"&gt;
        agentrisk
      &lt;/a&gt; / &lt;a href="https://github.com/agentrisk/agentrisk-money"&gt;
        agentrisk-money
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Python class for working with money, following Martin Fowler's money pattern
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
agentrisk-money&lt;/h1&gt;
&lt;p&gt;Python class for working with money, following &lt;a href="https://martinfowler.com/eaaCatalog/money.html" rel="nofollow"&gt;Martin Fowler's money pattern&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Influenced by &lt;a href="https://github.com/carlospalol/money"&gt;https://github.com/carlospalol/money&lt;/a&gt; and &lt;a href="https://github.com/luka-mladenovic/fowlers-money"&gt;https://github.com/luka-mladenovic/fowlers-money&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Currently only supports USD as currency.&lt;/p&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/agentrisk/agentrisk-money"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;It’s still in beta, but has decent test coverage. PRs welcome!&lt;/p&gt;

&lt;h1&gt;
  
  
  Thanks for reading!
&lt;/h1&gt;

&lt;p&gt;Hopefully this was useful to you, or at least a good refresher how floating point arithmetic works. If you want to nerd out further, I’d recommend going deep in this &lt;a href="https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html"&gt;classic article&lt;/a&gt; from ACM. Mind you, there are other issues one can run into when handling money, like &lt;a href="https://sarahdayan.github.io/dinero.js/module-Dinero.html#~allocate"&gt;allocation&lt;/a&gt; and calculating &lt;a href="https://sarahdayan.github.io/dinero.js/module-Dinero.html#~percentage"&gt;percentages&lt;/a&gt;. Both these will be added to &lt;code&gt;agentrisk-money&lt;/code&gt; library very soon.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article was originally posted on the &lt;a href="https://blog.agentrisk.com/you-better-work-in-cents-not-dollars-2edb52cdf308"&gt;AgentRisk blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>elixir</category>
    </item>
    <item>
      <title>Elixir’s with statement is fantastic</title>
      <dc:creator>Alex Loukissas</dc:creator>
      <pubDate>Wed, 19 Feb 2020 07:23:22 +0000</pubDate>
      <link>https://dev.to/aloukissas/elixir-s-with-statement-is-fantastic-3f2g</link>
      <guid>https://dev.to/aloukissas/elixir-s-with-statement-is-fantastic-3f2g</guid>
      <description>&lt;p&gt;I gotta be honest. It was not exactly love at first sight when I first encountered Elixir’s &lt;code&gt;with&lt;/code&gt; statement. But just like I learned to appreciate (and love) the whole non-defensive/let-it-crash approach, the same happened here as well.&lt;/p&gt;

&lt;p&gt;The result: I was able to rewrite a bunch of complicated functions with very hard-to-read nested &lt;code&gt;case&lt;/code&gt; and/or &lt;code&gt;cond&lt;/code&gt; statements in a very clean, and, more importantly, maintainable and extensible way using &lt;code&gt;with&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Basic usage
&lt;/h1&gt;

&lt;p&gt;The basic premise of &lt;code&gt;with&lt;/code&gt; is that it lets you chain together pattern matches and arriving at the positive result, in a very concise statement. Error handling (if any — remember, this is still let-it-crash land) is done in an optional &lt;code&gt;else&lt;/code&gt; clause, after we’re done with the positive codepath.&lt;/p&gt;

&lt;p&gt;Let’s look at a basic example. Suppose you’re working with the &lt;a href="https://github.com/code-corps/stripity_stripe"&gt;Elixir library for Stripe&lt;/a&gt; and you want to implement a function that creates a new &lt;a href="https://stripe.com/docs/api/subscriptions"&gt;subscription&lt;/a&gt; for a &lt;a href="https://stripe.com/docs/api/customers"&gt;customer&lt;/a&gt;. Here’s what this may have looked if we hadn’t used the &lt;code&gt;with&lt;/code&gt; statement:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;What’s wrong with the code above? Here’s a hint:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--udJQChCt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/7244/1%2AWP_eI3-8L-CAxGFq5PEz5Q.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--udJQChCt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/7244/1%2AWP_eI3-8L-CAxGFq5PEz5Q.jpeg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s try to write the same function using the &lt;code&gt;with&lt;/code&gt; statement:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;That’s a lot cleaner and easier to read, no?&lt;/p&gt;

&lt;h1&gt;
  
  
  Alas, it’s not all rosy
&lt;/h1&gt;

&lt;p&gt;But there’s a problem. In the second implementation, it’s really hard to infer which of the steps of the function calls failed the pattern matching, so that we can return a more useful error to the caller. It also makes it harder to debug.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So, did we trade readability for usability?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not quite.&lt;/p&gt;

&lt;h1&gt;
  
  
  We can do better!
&lt;/h1&gt;

&lt;p&gt;Fear not, reader! A really simple solution that we’ve been leveraging heavily in our codebase at &lt;a href="https://agentrisk.com"&gt;AgentRisk&lt;/a&gt; is to leverage pattern matching. Here’s how:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Each chained function call returns a tuple with an atom that helps us know exactly where things went wrong in the chain.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If we rewrite the previous code example like this, this is what we get:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In the example above, we are swallowing the error return values, but this was in favor of simplicity. The core idea here is that we tag each step with a unique tuple pattern, so that we can know exactly where the error occurred.&lt;/p&gt;

&lt;h1&gt;
  
  
  A final note
&lt;/h1&gt;

&lt;p&gt;Hopefully, this post clarified a few of the nuances of Elixir’s with statement. We have not found a better way to implement complex functions in our codebase, for readability, maintainability, and ease of debugging.&lt;/p&gt;

&lt;p&gt;I want to thank &lt;a href="https://twitter.com/carloslage"&gt;Carlos Brito Lage&lt;/a&gt; for introducing me to this pattern as well as editing an early version of this post.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This post was originally posted on the &lt;a href="https://blog.agentrisk.com/elixirs-with-statement-is-fantastic-1431bcbcde3"&gt;AgentRisk blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>functional</category>
    </item>
  </channel>
</rss>
