<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Aaron Lelevier</title>
  <link type="application/atom+xml" href="www.motivatedcoder.com/feed/atom.xml" rel="self"/>
  <updated>2024-09-07T19:15:03+00:00</updated>
  <author>
    <name>Aaron Lelevier</name>
  </author>
  <id>www.motivatedcoder.com</id>

  
    
      <entry>
        <title>How to calculate effective top tube length</title>
        <link href="http://www.motivatedcoder.com/how-to-calculate-effective-top-tube-length/"/>
        <updated>2024-03-30T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/how-to-calculate-effective-top-tube-length</id>
        <content type="html">&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/D0T1w64.png&quot; alt=&quot;Geometry Chart&quot; title=&quot;Geometry Chart&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Don’t just rely on mountain bike reach! Effective top tube(ETT) is also an important number for bike size fit. Recently, I was looking at &lt;a href=&quot;https://www.airdropbikes.com/&quot;&gt;Airdrop Bikes&lt;/a&gt; and became interested in the &lt;a href=&quot;https://www.airdropbikes.com/en-us/pages/airdrop-filter&quot;&gt;Airdrop Filter&lt;/a&gt;, but sizes were limited. This blog is my research on figuring out ETT and if an in stock size would fit.&lt;/p&gt;

&lt;p&gt;I have ridden a &lt;a href=&quot;https://geometrygeeks.bike/bike/commencal-meta-am-29-2019/&quot;&gt;Commencal Meta 29&lt;/a&gt; with a reach of 460 and seat tube angle(STA) of 76.5.&lt;/p&gt;

&lt;p&gt;I have ridden a &lt;a href=&quot;https://chromagbikes.com/products/stylus-2020&quot;&gt;Chromag Stylus&lt;/a&gt; with a reach of 465 and STA of 76.0.&lt;/p&gt;

&lt;p&gt;Question, will an &lt;a href=&quot;https://www.airdropbikes.com/en-us/pages/airdrop-filter&quot;&gt;Airdrop Filter&lt;/a&gt; with a reach of 475 and STA of 78.2 fit? (This is size large and medium is out of stock).&lt;/p&gt;

&lt;h2 id=&quot;geometry-numbers&quot;&gt;Geometry Numbers&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/aNHDcfn.png&quot; alt=&quot;Geometry Numbers&quot; title=&quot;Geometry Numbers&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;how-to-calculate&quot;&gt;How to calculate&lt;/h2&gt;

&lt;div class=&quot;language-erlang highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;% Functions
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DegreesToRadian&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Deg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;pi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;180&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Deg&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;Hypotenuse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;B&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Beta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;B&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DegreesToRadian&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Beta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;% Parameters
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Stack&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;614&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;HeightLow&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;STALow&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;78&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;HeightHigh&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;700&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;STAHigh&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;78&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;Reach&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;475&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;% seat tube angle(STA) difference
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;STADiff&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;STALow&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;STAHigh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;% percentage difference between high and low STA
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PercentHeightDiff&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;HeightLow&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Stack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;HeightLow&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;HeightHigh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;% Effective STA
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ESTA&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;STADiff&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;PercentHeightDiff&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;STALow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;% Answer - effective top tube(ETT)
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ETT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Hypotenuse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Stack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ESTA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DegreesToRadian&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ESTA&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Reach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;The Airdrop Filter ETT is shorter than expected. Comparing to a reach of 460 or 465, the 475 reach Filter has the shortest ETT of 603. This is due to the steep STA.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>What reading Distributed Algorithms by Nancy Lynch cover-to-cover meant to me</title>
        <link href="http://www.motivatedcoder.com/what-reading-distributed-algorithms-by-nancy-lynch-cover-to-cover-meant-to-me/"/>
        <updated>2023-06-19T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/what-reading-distributed-algorithms-by-nancy-lynch-cover-to-cover-meant-to-me</id>
        <content type="html">&lt;p&gt;Concurrency has always been of great personal interest to me. I purchased Java Concurrency in Practice by Goetz, the book with the trains on it, and would just look at the cover and think of when to start reading it…&lt;/p&gt;

&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;

&lt;p&gt;I remember reading the Erlang finite state machine (FSM) &lt;a href=&quot;https://www.erlang.org/doc/design_principles/statem.html&quot;&gt;statem module docs&lt;/a&gt; and seeing notation that looked like &lt;a href=&quot;https://lamport.azurewebsites.net/tla/tla.html&quot;&gt;TLA+&lt;/a&gt;. I owned Distributed Algorithms (DA) by Nancy Lynch for 3 years, and I read the first two chapters, and could understand the concept of an FSM for leader election in a ring, but I couldn’t understand the model notation or explanations of theorems, lemma, and so on. I use some concurrency in Python programming with threads, but mostly for fan-out-and-back.&lt;/p&gt;

&lt;h2 id=&quot;recently&quot;&gt;Recently&lt;/h2&gt;

&lt;p&gt;It is now June 2023. I was driving my kids to school, and the school year was ending, and I told my kids.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“I read Distributed Algorithms by Nancy Lynch and it took me from September (2022) to May (2023). The same as the school year for you guys. It took me a while, but I read the whole book.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;the-difference&quot;&gt;The difference&lt;/h2&gt;

&lt;p&gt;I later asked myself, what was the difference? How was I able to understand the book and also read it in its entirety? I think that the difference was learning to think on my own at a new level, and loooking up each concept whether it was math with set theory or graph theory, and being able to connect the concepts. It required doing this because the author assumes that you know these concepts. Also, trying to think in the shoes of the author, and what she was trying to tell me.&lt;/p&gt;

&lt;p&gt;I have been fortunate to have had a mentor for software engineering early in my career for about a year, but only one. After this time it has been largely through books and reading the learnings and thoughts of smart people that have helped me grow. It takes time to mentor somebody, so it is a special thing when it happens. Anyone can pick up a book though. The cost is relatively small, and it just takes time, and it is like listening to a senior engineer tell you everything they know. A truly special experience.&lt;/p&gt;

&lt;p&gt;Here are some of the concepts that the author assumed knowledge of. These lead to leisurly journeys on Google just looking up the concepts from multiple sources, re-reading them, writing them down in my own words, and trying to connect the dots.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;infimum, supremum, irreflexive partial ordering&lt;/li&gt;
  &lt;li&gt;agreement, k-agreement, approximate agreement, 1-valent, bi-valent, uni-valent&lt;/li&gt;
  &lt;li&gt;tree, spanning tree, forest, spanning forest, minimum spanning tree, strongly and weakly connected graphs&lt;/li&gt;
  &lt;li&gt;singleton set, multiset, superset, poweset&lt;/li&gt;
  &lt;li&gt;set union, difference, disjunction, symmetric difference&lt;/li&gt;
  &lt;li&gt;function domain, codomain, image, range, injective, surjective&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;impressions&quot;&gt;Impressions&lt;/h2&gt;

&lt;p&gt;The DA book is an academic book with so many concepts. If you are in the field of computer science or math, I highly recommend this book to you. I can say that I understood what safety and liveness were, but this book adds so many rich concepts to their understanding. For example, it explains low-level and high-level fairness in the context of mutual exclusion, where low-level is concerned with the user steps, and high-level is concerned with granting of the resource. High-level fairness can be guaranteed in some cases and not low-level fairness.&lt;/p&gt;

&lt;p&gt;Other important concepts are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;atomic objects and serialization points&lt;/li&gt;
  &lt;li&gt;composition of models, where each model is a component&lt;/li&gt;
  &lt;li&gt;simulation relation of a model A to B where a high-level model can be made to show low-level model properties using successive refinement&lt;/li&gt;
  &lt;li&gt;impossiblity results - e.g. asynchronous agreement with fault tolerance&lt;/li&gt;
  &lt;li&gt;upper and lower complexity for both time and messages&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;after&quot;&gt;After&lt;/h2&gt;

&lt;p&gt;After reading DA, I re-read &lt;a href=&quot;https://lamport.azurewebsites.net/pubs/time-clocks.pdf&quot;&gt;Lamport Time Clocks&lt;/a&gt; and the meaning was different. The LamportTime algorithm is covered in DA.&lt;/p&gt;

&lt;p&gt;I tried learning TLA+ before reading DA, and I couldn’t get to the point of writing my own TLA+ models. After reading DA, I now get it and can write models from DA in TLA+, which was one of my dreams. Here is the mutual exclusion Bakery algorithm for example: &lt;a href=&quot;https://github.com/aaronlelevier/tlaplus-aaron/blob/develop/specs/Bakery.tla&quot;&gt;Bakery.tla&lt;/a&gt;. I wanted to write this model spec in particular because we run a bakery at my work, and I just liked the name of the algorithm, but the bakery at work is for AWS AMI’s so a little different :)&lt;/p&gt;

&lt;h2 id=&quot;next&quot;&gt;Next&lt;/h2&gt;

&lt;p&gt;I am going to continue learning distributed systems. Whatever I learn can be distilled down and used for concrete cases in my AWS programming work.&lt;/p&gt;

&lt;p&gt;I found this &lt;a href=&quot;https://pdos.csail.mit.edu/6.824/schedule.html&quot;&gt;MIT course schedule&lt;/a&gt; for distributed systems with a lot of links to research papers. This may be a good next step. I may also read Reliable and Secure Distributed Programming by Cachin.&lt;/p&gt;

&lt;p&gt;I have been careful to not tell myself that “I finished the DA book”. I plan to keep referring back to it. Instead I tell myself, “I read the DA book”.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>The Fearless Mind by Dr. Craig Manning</title>
        <link href="http://www.motivatedcoder.com/The-Fearless-Mind-by-Dr-Craig-Manning/"/>
        <updated>2023-03-18T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/The-Fearless-Mind-by-Dr-Craig-Manning</id>
        <content type="html">&lt;p&gt;This blog is a summary of key points from &lt;a href=&quot;https://thefearlessmind.com/&quot;&gt;The Fearless Mind&lt;/a&gt; by Dr. Craig Manning. This book helped me in my daily personal and professional life, and I hope that sharing the following concepts helps you as well.&lt;/p&gt;

&lt;h2 id=&quot;the-fearless-mind&quot;&gt;&lt;strong&gt;The Fearless Mind&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;The Fearless Mind is a state of being where one is mentally positive, confident, and focused on the task at hand.&lt;/p&gt;

&lt;h2 id=&quot;components-of-a-fearless-mind&quot;&gt;&lt;strong&gt;Components of a Fearless Mind&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;First, being &lt;strong&gt;confident&lt;/strong&gt; is key. A confident person believes in their skills and does not let others affect their efforts. Confidence is increased by learning and developing core skills which improves performance on &lt;strong&gt;tasks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;task&lt;/strong&gt; is an activity required in competition, for example a backswing in tennis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Focus&lt;/strong&gt; on the present improves performance by not thinking about past or future outcomes and instead focusing on tasks. This requires &lt;strong&gt;concentration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Focus and concentration require &lt;strong&gt;decision making.&lt;/strong&gt; There are two ways to improve decision making. One is through &lt;em&gt;block practice&lt;/em&gt;, the practice of core skills in isolation. The other is &lt;em&gt;random-practice&lt;/em&gt;, which is practice that simulates competition.&lt;/p&gt;

&lt;p&gt;It is necessary to take calculated &lt;strong&gt;risk&lt;/strong&gt; because it improves focus, and can make the difference when other elements in competition are equal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Positive&lt;/strong&gt; thinking and self-talk is a key element because competition has highs and lows, so it is important to remain positive and not let swings affect performance.&lt;/p&gt;

&lt;h2 id=&quot;general-context-of-the-book&quot;&gt;&lt;strong&gt;General context of the book&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Dr. Manning replicated other top school’s physical training programs for his tennis team, but hit a plateau. He wanted to further improve his team’s performance, which led to him focus on the mental aspect of competiion. What he learned became The Fearless Mind.&lt;/p&gt;

&lt;h2 id=&quot;how-did-i-find-out-about-the-fearless-mind-book&quot;&gt;&lt;strong&gt;How did I find out about The Fearless Mind book&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;I found out about this book through watching the YouTube film&lt;a href=&quot;https://youtu.be/liFHsc8h0hc&quot;&gt; 8600FT&lt;/a&gt; by Canyon Bicycles. Dr. Manning is in the movie, and Braydon Bringhurst, the star of the film, who is attempting to climb 8600FT of the Whole Enchilada trail in Moab, was one of Dr. Manning’s students. Bringhurst uses the above strategies openly in the film, especially the positive self-talk strategy.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>How I came to read the first half of Distributed Algorithms by Nancy Lynch</title>
        <link href="http://www.motivatedcoder.com/How-I-came-to-read-the-first-half-of-Distributed-Algorithms-by-Nancy-Lynch/"/>
        <updated>2023-02-02T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/How-I-came-to-read-the-first-half-of-Distributed-Algorithms-by-Nancy-Lynch</id>
        <content type="html">&lt;p&gt;This blog is my story of how I came to read half of Distributed Algorithms by Nancy Lynch. This is a personal story, but also has ideas for how to learn and get unstuck.&lt;/p&gt;

&lt;h2 id=&quot;the-beginning&quot;&gt;The beginning&lt;/h2&gt;
&lt;p&gt;I first learned of the &lt;a href=&quot;http://groups.csail.mit.edu/tds/distalgs.html&quot;&gt;Distributed Algorithms&lt;/a&gt; book from watching the video &lt;a href=&quot;https://youtu.be/clYXrZtKhGs&quot;&gt;Distributed Systems Theory for Practical Engineers&lt;/a&gt;. In this video, the speaker references 4 books:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Distributed Algorithms by Nancy Lynch&lt;/li&gt;
  &lt;li&gt;Reliable and Secure Distributed Programming by Christian Cachin&lt;/li&gt;
  &lt;li&gt;Replication Theory and Practice by Bernadette Charon1.Bost&lt;/li&gt;
  &lt;li&gt;Guide to Reliable Distributed Systems by Kenneth Birman&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Lets refer to these books by number 1-4. The speaker calls book 1 “the bible”. Then says, “if you are going to read any book, read book 2. I went online and picked up the first two books.&lt;/p&gt;

&lt;h2 id=&quot;getting-stuck&quot;&gt;Getting stuck&lt;/h2&gt;
&lt;p&gt;Next followed a series of attempts to read book 1 with each time resulting in the concepts not sinking in:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Try to read book 1&lt;/li&gt;
  &lt;li&gt;Try to read book 2 before book 1&lt;/li&gt;
  &lt;li&gt;Learn Erlang by reading Programming Erlang by Joe Armstrong&lt;/li&gt;
  &lt;li&gt;Create an Erlang project with concurrency named &lt;a href=&quot;https://github.com/aaronlelevier/dta&quot;&gt;dta&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Use Erlang &lt;a href=&quot;https://www.erlang.org/doc/design_principles/statem.html&quot;&gt;gen_statem behavior&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Learned about TLA+ by this &lt;a href=&quot;https://www.youtube.com/live/uPNFcTAgw3E?feature=share&quot;&gt;video&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Learn more about TLA+ by doing the &lt;a href=&quot;https://lamport.azurewebsites.net/tla/tla.html&quot;&gt;video series&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Try to read book 1 again and covert book models to TLA specs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;then-came-motivation-and-a-good-environment&quot;&gt;Then came motivation and a good environment&lt;/h2&gt;
&lt;p&gt;None of the above attempts worked as far as enabling me to start reading book 1 and understand it. I did learn more concepts, but I was not quite there. Next came a series of things that pulled and pushed me in the right direction:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I had a soft tissue injury in my back and needed to take a break from mountain biking, so I had time to do other things&lt;/li&gt;
  &lt;li&gt;I started physical therapy for my back which made me optimistic&lt;/li&gt;
  &lt;li&gt;My manager told me “Aaron, you can code all day. What you need to do is learn the way things work”&lt;/li&gt;
  &lt;li&gt;I stopped drinking a beer or wine with dinner. Even this casual drinking was slowing me down and causing me to lose motivation&lt;/li&gt;
  &lt;li&gt;My youngest started school, so the mornings were now quiet&lt;/li&gt;
  &lt;li&gt;TLA+ motivated me, and I knew that I needed more backgound knowledge&lt;/li&gt;
  &lt;li&gt;I wanted to grow at work while working on my current projects&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;then-i-could-understand&quot;&gt;Then I could understand&lt;/h2&gt;
&lt;p&gt;September 4, 2023, which happened to be around the same time that my youngest started school, I started reading book 1. I took the time to understand the concepts and research what I didn’t know. I’ve been reading the book in the morning. I am a morning person, and it is a nice start to the day to get the new knowledge and consider things differently.&lt;/p&gt;

&lt;h2 id=&quot;now&quot;&gt;Now&lt;/h2&gt;
&lt;p&gt;It is now February 2, 2023, and I am on page 425 of 827 pages, so I am half way.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I think the difference was having enough reasons, enjoying what you are doing, and taking the time to learn.&lt;/p&gt;

&lt;h2 id=&quot;what-next&quot;&gt;What Next&lt;/h2&gt;
&lt;p&gt;I plan to continue reading book 1. I may take a break to write a TLA spec from a model in the book. I am thinking the Peterson2P algorithm, but I am going to wait and see. I don’t want to lose momentum.&lt;/p&gt;

&lt;h2 id=&quot;thank-you-to-the-authors&quot;&gt;Thank you to the authors&lt;/h2&gt;
&lt;p&gt;I am thankful to the authors for writing these books and sharing them with us. I have had three people in my career who I consider mentors. I learned a lot from them. When you read someone’s book, if it is the right book, it is like having a senior mentor teaching you.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Learning Golang and Network Programming</title>
        <link href="http://www.motivatedcoder.com/Learing-Golang-and-Network-Programming/"/>
        <updated>2022-03-06T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/Learing-Golang-and-Network-Programming</id>
        <content type="html">&lt;p&gt;This blog contains notes on mostly &lt;a href=&quot;http://www.ntp.org/&quot;&gt;NTP&lt;/a&gt; Learning in conjunction with reading the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ntpc.go&lt;/code&gt; module in this Github repo &lt;a href=&quot;https://github.com/vladimirvivien/go-networking&quot;&gt;vladimirvivien/go-networking&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;intro&quot;&gt;Intro&lt;/h2&gt;

&lt;p&gt;I have been starting to learn Golang and wanted to start learning why Golang is good for Network Programming. After searching, I found this repo &lt;a href=&quot;https://github.com/vladimirvivien/go-networking&quot;&gt;vladimirvivien/go-networking&lt;/a&gt;. Here are my notes from reading the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ntpc.go&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ntps.go&lt;/code&gt; modules, mostly the former, in this repo.&lt;/p&gt;

&lt;h2 id=&quot;ntpcgo&quot;&gt;ntpc.go&lt;/h2&gt;

&lt;p&gt;First, the Packt book is no longer available, so I thought to read &lt;a href=&quot;https://github.com/vladimirvivien/go-networking/blob/master/udp/ntpc/ntpc.go&quot;&gt;ntpc.go&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Learning about Go, this module starts with:&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;host&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StringVar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;e&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;us.pool.ntp.org:123&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;NTP host&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here &lt;a href=&quot;https://pkg.go.dev/flag#StringVar&quot;&gt;flag.StringVar&lt;/a&gt; is intialized to the address of a pointer, with the default &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;value&lt;/code&gt; of the 3rd arg, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;func StringVar(p *string, name string, value string, usage string)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Usage:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// uses default
go run ntpc.go

// uses ntp server from ntps.go
go run ntps.go
go run ntpc.go &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; localhost:1123
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;golang-net-pkg&quot;&gt;Golang net pkg&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;https://pkg.go.dev/net&quot;&gt;net&lt;/a&gt; pkg is used to create a UDP object, establish a connect then send a request and response. I looked up the us.pool.ntp.org IP information to compare to the Golang objects:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;nslookup us.pool.ntp.org
Server:		192.168.1.1
Address:	192.168.1.1#53

Non-authoritative answer:
Name:	us.pool.ntp.org
Address: 70.35.196.28
Name:	us.pool.ntp.org
Address: 168.61.215.74
Name:	us.pool.ntp.org
Address: 216.229.4.69
Name:	us.pool.ntp.org

Address: 66.151.147.38
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The first Server address is our private network DNS address with th&lt;/p&gt;

&lt;p&gt;192.168.0.0/16
Address for private networks (intranets). Such addresses never appear on the public Internet.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;p&gt;https://timetoolsltd.com/ntp/ntp-client/&lt;/p&gt;

</content>
      </entry>
     
  
    
      <entry>
        <title>How Import to an IAM Role into Cloudformation</title>
        <link href="http://www.motivatedcoder.com/How-to-Import-an-IAM-Role-into-Cloudformation/"/>
        <updated>2022-01-30T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/How-to-Import-an-IAM-Role-into-Cloudformation</id>
        <content type="html">&lt;p&gt;This is a blog about importing an existing IAM Role into Cloudformation(CFN). An IAM Role is one of the &lt;a href=&quot;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resource-import-supported-resources.html&quot;&gt;supported resource types&lt;/a&gt; that can be imported into CFN. The use case for doing this is that you may have resources that were created via the AWS Console, and you want to move them to version control.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Here are the docs on how importing resources work in AWS: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resource-import-new-stack.html#resource-import-new-stack-cli&lt;/p&gt;

&lt;p&gt;And here are the docs for an example of how to import a resource: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resource-import.html&lt;/p&gt;

&lt;p&gt;I created an example Github repo with working code that follows this process using the &lt;a href=&quot;https://aws.amazon.com/sdk-for-python/&quot;&gt;boto3&lt;/a&gt;. Please refer to this repo for example templates on the process. There is also a Jupyter notebook with documentation on how the created CFN template and IAM Role resource in AWS are updated at different steps of the process: https://github.com/aaronlelevier/import-iam-to-cfn&lt;/p&gt;

&lt;p&gt;At the end of this test, I tried deleting the Role via the CFN stack, and the Role in AWS was not deleted and had to be deleted outside of the CFN stack.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>One Month of TLA+ Learning Adventure</title>
        <link href="http://www.motivatedcoder.com/One-Month-of-TLAPlus-Learning-Adventure/"/>
        <updated>2022-01-23T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/One-Month-of-TLAPlus-Learning-Adventure</id>
        <content type="html">&lt;p&gt;In this blog, I share my experience from learning TLA+ for one month. This blog does not teach TLA+. Instead, I link to resources for those who are interested in learning TLA+. All resources are free as of this blog.&lt;/p&gt;

&lt;h2 id=&quot;what-is-tla&quot;&gt;What is TLA+&lt;/h2&gt;

&lt;p&gt;TLA+ is a specification language, where you write a specification(spec) of a finite state machine(FSM). You denfine the inputs(CONSTANTS), mutable state(VARIABLES), and transitions from one state to another(action expressions). The TLC model checker is then used to run the spec and will investigate all possible actions for all states. One key point is that you write “what can happen”, not “how it happens”. This is why TLA+ is a specification language and not a programming language.&lt;/p&gt;

&lt;p&gt;TLA+ is created by &lt;a href=&quot;https://en.wikipedia.org/wiki/Leslie_Lamport&quot;&gt;Leslie Lamport&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;how-did-i-find-out-about-tla&quot;&gt;How did I find out about TLA+&lt;/h2&gt;

&lt;p&gt;I discussed this in my previous blog &lt;a href=&quot;2022-01-08-2021-EOY-Blog.md##The-adventure-of-learning-TLA+&quot;&gt;2021 EOY Blog - The adventure of learning TLA+&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;where-i-started&quot;&gt;Where I started&lt;/h2&gt;

&lt;p&gt;I started learning TLA+ by watching &lt;a href=&quot;https://lamport.azurewebsites.net/video/videos.html&quot;&gt;The TLA+ Video Course&lt;/a&gt;. Here are 3 highlights that really grabbed me.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The &lt;a href=&quot;https://lamport.azurewebsites.net/video/intro.html&quot;&gt;Introduction to TLA+ video&lt;/a&gt;. Here Leslie Lamport says, “now is not the time to be modest”, and he goes on to say what he has achieved and why you should listen to him and learn TLA+. He also states how AWS has used TLA+ since 2013 to prove their internal services, and how AWS senior management believes in TLA+.&lt;/li&gt;
  &lt;li&gt;The &lt;a href=&quot;https://lamport.azurewebsites.net/video/video7.html&quot;&gt;Paxos Commit&lt;/a&gt; video at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;12:30&lt;/code&gt; in the video, Leslie Lamport shows &lt;a href=&quot;https://lamport.azurewebsites.net/video/video7-script.pdf&quot;&gt;slide 126&lt;/a&gt;, and he says, “I don’t know how to write a clearer precise description of this step of the algorithm.” At first, I could not understand this code, but then going back and rereading it later, I understood it, and thought, “wow this is the most concise and elegant way to state the behaivor of this algorithm in TLA+.”&lt;/li&gt;
  &lt;li&gt;The &lt;a href=&quot;https://lamport.azurewebsites.net/video/video10b.html&quot;&gt;final video&lt;/a&gt; of The TLA+ Video Course. Leslie Lamport closes the video with this quote, “As you go forward, remember to take the time to stop and think. I
hope what you’ve learned here will help you do that.”&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;where-am-i-at-now&quot;&gt;Where am I at now&lt;/h2&gt;

&lt;p&gt;I am currently reading the &lt;a href=&quot;https://lamport.azurewebsites.net/tla/book.html&quot;&gt;Specifying Systems&lt;/a&gt; TLA+ book, and am on page 80. I think that watching the videos first has made the book easier to understand.&lt;/p&gt;

&lt;p&gt;I have written my 2nd TLA+ spec &lt;a href=&quot;https://gist.github.com/aaronlelevier/75ec48f7de1878fb55d7604e3bcdacc3&quot;&gt;RTOP.tla&lt;/a&gt;.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/aaronlelevier/75ec48f7de1878fb55d7604e3bcdacc3.js&quot;&gt;&lt;/script&gt;

&lt;h3 id=&quot;rtop-explained&quot;&gt;RTOP explained&lt;/h3&gt;

&lt;p&gt;RTOP stands for R-to-P and is a spec that shows a mapping of many-to-many &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R&lt;/code&gt; and the inverse.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CONSTANT&lt;/code&gt; defines a set of P and a set of R. Everything in TLA+ is a set. These are inputs to the spec.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VARIABLE&lt;/code&gt; declares the mutable state of the spec. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptor&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rtop&lt;/code&gt; are mappings from “P to R” and “R to P”, which is the inverse.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TypeOK&lt;/code&gt; declares our type invariants, which states what are the allowed types of our mutable state. Here we define &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptor&lt;/code&gt; to be a mapping for the domain &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P&lt;/code&gt;, where the value always a subset of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R&lt;/code&gt;. The inverse is true for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rtop&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Init&lt;/code&gt; initializes the spec. Here we initialize the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ptor&lt;/code&gt; mapping for all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p&lt;/code&gt; in the set of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;P&lt;/code&gt; to a value in the subset of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R&lt;/code&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rtop&lt;/code&gt; is initialized to the inverse.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PAddR(p, r)&lt;/code&gt; defines a single Action where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;r&lt;/code&gt; is added to the mapping for a given &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Next&lt;/code&gt; declares that in each transition(step) of the FSM that there should exist some &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p&lt;/code&gt; and some &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;r&lt;/code&gt; such that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;r&lt;/code&gt; can be added to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;p&lt;/code&gt;’s mapping.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Spec&lt;/code&gt; declares what is run by the TLC model checker. We first initialize our state with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Init&lt;/code&gt; and then we run the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Next&lt;/code&gt; Action where all state variables &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vars&lt;/code&gt; are subject to change. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[]Next&lt;/code&gt; means that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Next&lt;/code&gt; runs continuously until all states are reached.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;THEOREM&lt;/code&gt; states that our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Spec&lt;/code&gt; requires &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[]TypeOK&lt;/code&gt; to always be true, so in all states, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Init&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Next&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;how-can-i-run-this-code&quot;&gt;How can I run this code&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RTOP.tla&lt;/code&gt; can be run using the &lt;a href=&quot;https://lamport.azurewebsites.net/tla/toolbox.html&quot;&gt;TLA+ Toolbox&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-i-learned&quot;&gt;What I learned&lt;/h2&gt;

&lt;p&gt;Leslie Lamport is 100% correct in the fact that TLA+ will help you think about problems differently. He talks about how creating abstractions is difficult, and you have to learn it over time. TLA+ forces you to think about the abstraction and at what level you want to create it. There are tradeoffs to coarse of fine grained abstractions.&lt;/p&gt;

&lt;p&gt;When going back to a programming language, thinking about the design separately from the implementation has helped. The design must be correct, or the implementation has to try and make up for it and will struggle. Getting the design right is a must, which then simplifies the implementation. TLA+ is the design, and that is why already I can tell that TLA+ is super valuable.&lt;/p&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s Next&lt;/h2&gt;

&lt;p&gt;I plan to keep reading &lt;a href=&quot;https://lamport.azurewebsites.net/tla/book.html&quot;&gt;Specifying Systems&lt;/a&gt;. I also want to continue reading &lt;a href=&quot;https://dl.acm.org/doi/book/10.5555/2821576&quot;&gt;Distributed Algorithms&lt;/a&gt; by Nancy Lynch at the same time and implement the algorithms from the book in TLA+ to get more practice.&lt;/p&gt;

&lt;h2 id=&quot;tla-references&quot;&gt;TLA+ References&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://lamport.azurewebsites.net/tla/tla.html&quot;&gt;TLA+ Website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://lamport.azurewebsites.net/tla/summary-standalone.pdf&quot;&gt;TLA+ Cheatsheet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://lamport.azurewebsites.net/tla/newmodule.html&quot;&gt;TLA+ syntax&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://learntla.com/introduction/&quot;&gt;Unofficial Learn TLA+ website&lt;/a&gt;&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>2021 EOY Blog</title>
        <link href="http://www.motivatedcoder.com/2021-EOY-Blog/"/>
        <updated>2022-01-08T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/2021-EOY-Blog</id>
        <content type="html">&lt;p&gt;The year of the learning adventure.&lt;/p&gt;

&lt;h2 id=&quot;the-adventure-of-reading-tcp-illustrated&quot;&gt;The adventure of reading TCP Illustrated&lt;/h2&gt;

&lt;p&gt;I started reading &lt;a href=&quot;https://en.wikipedia.org/wiki/TCP/IP_Illustrated&quot;&gt;TCP Illustrated&lt;/a&gt; out of curiosity. I got to page 100 and thought, “this is pretty good.” Then I got to page 200 and thought, “wow, I can’t believe that I made it to page 200.” Then, I had to decide to read the whole book or not. The book is 922 pages. It was a challenge, and I had to pace myself to read 40-50 pages a week, but I did it. The benefits from reading this book weren’t really planned, but I started seeing them right away.&lt;/p&gt;

&lt;h2 id=&quot;the-adventure-of-learning-tla&quot;&gt;The adventure of learning TLA+&lt;/h2&gt;

&lt;p&gt;I somehow stumbled upon TLA+ through watching a series of YouTube videos. I first watched &lt;a href=&quot;https://youtu.be/KDZPBzA3yFw&quot;&gt;Trust but Isolate The future of software&lt;/a&gt; which talked about the language &lt;a href=&quot;https://isabelle.in.tum.de/overview.html&quot;&gt;Isabelle&lt;/a&gt; for formal methods. I did some research and saw a few languages mentioned and some pros/cons of different languages, one of which was TLA+, so I decided to next check this language.&lt;/p&gt;

&lt;p&gt;I then watched the video &lt;a href=&quot;https://youtu.be/wjsI0lTSjIo&quot;&gt;SREcon20 Americas - Weeks of Debugging Can Save You Hours of TLA+&lt;/a&gt; which in my mind connected programming to a specification language for formal methods and was the perfect next step to learning TLA+.&lt;/p&gt;

&lt;p&gt;From here, I researched TLA+ and found the website and watched the &lt;a href=&quot;https://lamport.azurewebsites.net/video/intro.html&quot;&gt;TLA+&lt;/a&gt; intro videos. I watched all videos, and am now checking out the &lt;a href=&quot;https://github.com/tlaplus/Examples&quot;&gt;Examples&lt;/a&gt; and &lt;a href=&quot;http://lamport.azurewebsites.net/tla/book.html?back-link=learning.html#book&quot;&gt;TLA+ Specifying Systems&lt;/a&gt; book.&lt;/p&gt;

&lt;h2 id=&quot;some-other-highlights&quot;&gt;Some other highlights&lt;/h2&gt;

&lt;p&gt;Tried out &lt;a href=&quot;https://github.com/features/actions&quot;&gt;Github Actions&lt;/a&gt;. They &lt;a href=&quot;https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services&quot;&gt;work&lt;/a&gt; nicely with &lt;a href=&quot;https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html&quot;&gt;AWS OIDC&lt;/a&gt; auth.&lt;/p&gt;

&lt;p&gt;Coded with my son and daughter for the first time. This was quite funny. My daughter was giggling because she was having so much fun. My son hung in there for a while, but then got bored and said, “this is boring. How do you turn this off.”&lt;/p&gt;

&lt;h2 id=&quot;whats-next-for-2022&quot;&gt;What’s next for 2022&lt;/h2&gt;

&lt;p&gt;I am continuing to learn TLA+. I’m currently reading the &lt;a href=&quot;http://lamport.azurewebsites.net/tla/book.html?back-link=learning.html#book&quot;&gt;TLA+ Specifying Systems&lt;/a&gt; book. I also started reading &lt;a href=&quot;https://dl.acm.org/doi/book/10.5555/2821576&quot;&gt;Distributed Algorithms&lt;/a&gt; by Nancy Lynch again. This has new meaning after watching the TLA+ videos. I plan to read both at the same time.&lt;/p&gt;

&lt;p&gt;I still want to learn Golang, but I don’t want to pivot just yet.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Thoughts on the InfoQ talk Netflix Networking Beating the Speed of Light with Intelligent Request Routing</title>
        <link href="http://www.motivatedcoder.com/Thoughts-on-the-InfoQ-Talk-Netflix-Networking-Beating-the-Speed-of-Light-with-Intelligent-Request-Routing/"/>
        <updated>2021-10-31T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/Thoughts-on-the-InfoQ-Talk-Netflix-Networking-Beating-the-Speed-of-Light-with-Intelligent-Request-Routing</id>
        <content type="html">&lt;p&gt;This blog is about my thoughts on the InfoQ talk:
&lt;em&gt;Netflix Networking: Beating the Speed of Light with Intelligent Request Routing&lt;/em&gt;&lt;sub&gt;1&lt;/sub&gt;. This is a top notch talk. Even if you are not into networking, you can learn something from the methodologies discussed in this talk. After listening to this talk, I was like “wow!”, and so I just want to share some thoughts on the talk as they relate to myself and other learning.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;The talk is 38 minutes long including Q&amp;amp;A, so let me first summarize the talk. The talk is about improving Netflix streaming speeds using networking by intelligently either connecting to the Cloud or a CDN endpoint. This is done by using an agent installed on Netflix clients to measure and compare DNS Resolver response times, and then this data is aggregated and analyzed, and DNS is updated to direct the client to either the Cloud or CDN, whichever is faster.&lt;/p&gt;

&lt;h2 id=&quot;thoughts&quot;&gt;Thoughts&lt;/h2&gt;

&lt;p&gt;I listened to this talk while driving, and did not see all the diagrams, so my summary may be overly vague for certain points. With that said, what really impressed me about this talk is that the speakers used their knowledge of networking and the empirical process to make hypotheses, prototype, analyze results, and then repeat.&lt;/p&gt;

&lt;p&gt;I am currently reading the book &lt;em&gt;TCP Illustrated&lt;/em&gt;&lt;sub&gt;2&lt;/sub&gt; and am about two thirds done. Having some of the networking knowledge from the book, I was impressed how they use Anycast addresses&lt;sub&gt;3&lt;/sub&gt; networking for the CDN to provide the best service based upon location.&lt;/p&gt;

&lt;p&gt;They also discussed how they have about 200k DNS Resolver&lt;sub&gt;4&lt;/sub&gt; IPs that they store when they build the DNS map that is used for the intelligent routing, and this data pipeline refreshes every 10 minutes. This was a pretty interesting statistic after reading the DNS chapter in &lt;em&gt;TCP Illustrated&lt;/em&gt;&lt;sub&gt;2&lt;/sub&gt;, also because Internet routes change over time, so the mapping must be updated on some interval.&lt;/p&gt;

&lt;p&gt;Building in a failure mode to the service. This was a particularly interesting point that the service will fall back to the default if it fails. They noted how this is critical for the service to be resilient and make the change on such a large scale.&lt;/p&gt;

&lt;h2 id=&quot;beyond-networking&quot;&gt;Beyond Networking&lt;/h2&gt;

&lt;p&gt;The part in the talk about time to integrate their service and make it to production was also super interesting. They did experiments in production to analyze traffic before their service went live, then did Canary tests, A/B tests, and progressive rollouts.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I recommend this talk. Even the Q&amp;amp;A was really good.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;p&gt;[1] - &lt;a href=&quot;https://youtu.be/7AO4t7G8Bmk&quot;&gt;Netflix Networking: Beating the Speed of Light with Intelligent Request Routing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2] - &lt;a href=&quot;https://en.wikipedia.org/wiki/TCP/IP_Illustrated&quot;&gt;TCP Illustrated&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[3] - &lt;a href=&quot;https://en.wikipedia.org/wiki/Anycast&quot;&gt;Anycast Address Networking&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[4] - &lt;a href=&quot;https://en.wikipedia.org/wiki/Domain_Name_System#DNS_resolvers&quot;&gt;DNS Resolver&lt;/a&gt;&lt;/p&gt;

</content>
      </entry>
     
  
    
      <entry>
        <title>What I Learned from 1 Year of AWS Custom Resource</title>
        <link href="http://www.motivatedcoder.com/What-I-Learned-from-1-Year-of-AWS-Custom-Resource/"/>
        <updated>2021-10-24T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/What-I-Learned-from-1-Year-of-AWS-Custom-Resource</id>
        <content type="html">&lt;p&gt;The title of this article could have also been, &lt;em&gt;“Using AWS Custom Resource’s.”&lt;/em&gt; or maybe &lt;em&gt;“AWS Custom Resource Gotchas and how to avoid them.”&lt;/em&gt;   Either way, the goal of this article is to talk about usage and gotchas. With that said, this article is meant to be in addition to the AWS Official Documentation, linked below the &lt;a href=&quot;#References&quot;&gt;References&lt;/a&gt;. I will highlight a few important aspects of AWS Custom Resources with the way that they work.&lt;/p&gt;

&lt;h2 id=&quot;what-is-an-acr&quot;&gt;What is an ACR&lt;/h2&gt;

&lt;p&gt;An AWS Custom Resource&lt;sub&gt;1&lt;/sub&gt; (ACR) is a mechanism in AWS Cloudformation (CFN) that allows an arbitray payload to be sent to a compute function.&lt;/p&gt;

&lt;p&gt;There are two ACR types:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;AWS Lambda - sync - must always return a response (pass or fail)&lt;/li&gt;
  &lt;li&gt;AWS SQS Queue - async&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article covers AWS Lambda as this is the common case.&lt;/p&gt;

&lt;p&gt;ACRs have a Request&lt;sub&gt;2&lt;/sub&gt; and Response&lt;sub&gt;3&lt;/sub&gt; structure.&lt;/p&gt;

&lt;h2 id=&quot;the-first-thing-you-learn&quot;&gt;The first thing you learn&lt;/h2&gt;

&lt;p&gt;The first major lesson of AWS Lambda ACRs is that they must always return a Response. If an ACR errors and fails to send a Response, the CloudFormation (CFN) parent stack invoking the ACR will spin for 1 hour, and eventually timeout, and fail.&lt;/p&gt;

&lt;h4 id=&quot;the-acr-error-kernel&quot;&gt;The ACR Error Kernel&lt;/h4&gt;

&lt;p&gt;The ACR always sending a Response could be descibed as the “Error Kernel”, which is a concept that  Joe Armstrong&lt;sub&gt;11&lt;/sub&gt; introduces in his talk &lt;em&gt;“The Do’s and Don’ts of Error Handling”&lt;/em&gt;&lt;sub&gt;12&lt;/sub&gt;&lt;/p&gt;

&lt;h2 id=&quot;how-to-always-send-a-response&quot;&gt;How to always send a Response&lt;/h2&gt;

&lt;p&gt;In order to achieve always sending a Response, you should wrap the invocation of your code in a top level &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;try/catch&lt;/code&gt; where all errors be caught and send a ACR Response of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fail&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You could wrap your code in the following:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;fail&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;long-responses&quot;&gt;Long Responses&lt;/h3&gt;

&lt;p&gt;There may be some cases where a long response is generated by your code. You must truncate your response to a max size of 4096 bytes per the current docs, or else the CFN stack will fail with “Custom Resource Response Too Long”, and your CFN stack deploy will fail with no valuable error message from the custom resource.&lt;/p&gt;

&lt;h3 id=&quot;success-case&quot;&gt;Success case&lt;/h3&gt;

&lt;p&gt;In the success case, ACR Response data can be returned, which can be an arbitrary single level &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;key/value&lt;/code&gt; map.&lt;/p&gt;

&lt;p&gt;This data is then referenceable using the CFN intrisic function: ``Fn::Getatt`&lt;sub&gt;8&lt;/sub&gt;&lt;/p&gt;

&lt;h3 id=&quot;fail-case&quot;&gt;Fail case&lt;/h3&gt;

&lt;p&gt;In the failure case, an Error Reason and Error Message can be sent.&lt;/p&gt;

&lt;p&gt;This will result in a ROLLBACK by your parent CFN stack.&lt;/p&gt;

&lt;h2 id=&quot;acr-request&quot;&gt;ACR Request&lt;/h2&gt;

&lt;p&gt;An ACR Request consists of the ACR endpoint, e.g. the AWS Lambda ARN, optional key/value arguments, and metadata.&lt;/p&gt;

&lt;h3 id=&quot;the-lambda-arn&quot;&gt;The Lambda ARN&lt;/h3&gt;

&lt;p&gt;This payload will be sent as an Event to the Lambda ARN.&lt;/p&gt;

&lt;h3 id=&quot;optional-keyvalue-arguments&quot;&gt;Optional Key/Value arguments&lt;/h3&gt;

&lt;p&gt;These arguments will appear as top level key/value arguments in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResourceProperties&lt;/code&gt; section of the Lambda Event.&lt;/p&gt;

&lt;p&gt;The value of these arguments can be a nested data structure.&lt;/p&gt;

&lt;h3 id=&quot;metadata&quot;&gt;Metadata&lt;/h3&gt;

&lt;p&gt;AWS metadata is also sent in the ACR Request. This will include the parent CFN Stack Id, PhysicalResourceId, and so on.&lt;/p&gt;

&lt;h3 id=&quot;the-physicalresourceid&quot;&gt;The PhysicalResourceId&lt;/h3&gt;

&lt;p&gt;This value can be updated in order to trigger certain desired behavior.  First CFN will process a RequestType of UPDATE, based on the &lt;strong&gt;new&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PhysicalResourceId&lt;/code&gt; in the Event. Then CFN sends an Event with a RequestType of DELETE with the &lt;strong&gt;old&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PhysicalResourceId&lt;/code&gt; and previous Event. This is sent after the UPDATE has succeded during the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UPDATE_COMPLETE_CLEANUP_IN_PROGRESS&lt;/code&gt; phase.&lt;/p&gt;

&lt;h2 id=&quot;acr-requesttype&quot;&gt;ACR RequestType&lt;/h2&gt;

&lt;p&gt;There are 3 request types, and these match based on what the parent CFN stack is doing:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;CREATE&lt;/li&gt;
  &lt;li&gt;UPDATE&lt;/li&gt;
  &lt;li&gt;DELETE&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;deploy-it&quot;&gt;Deploy it&lt;/h2&gt;

&lt;p&gt;An ACR, like any other AWS Resource can be deployed with CFN&lt;sub&gt;4&lt;/sub&gt;, AWS SAM&lt;sub&gt;5&lt;/sub&gt;, or some other deployment method.&lt;/p&gt;

&lt;h3 id=&quot;replace-an-acr&quot;&gt;Replace an ACR&lt;/h3&gt;

&lt;p&gt;An ACR can NOT be replaced via tearing down and rebuilding if it is referenced in another CFN Stack, regardless of referencing the ACR directly or as  variable using an SSM Parameter&lt;sub&gt;9&lt;/sub&gt; or CFN ImportValue&lt;sub&gt;10&lt;/sub&gt;. You must solve for this.&lt;/p&gt;

&lt;h2 id=&quot;rollback&quot;&gt;Rollback&lt;/h2&gt;

&lt;p&gt;Rollback by default will use the same AWS Lambda code. This will be a problem if the Lambda suffers a bad update, e.g. a coding error, as the ACR will fail, then on rollback, if the same code path is used, rollback will also fail. You must solve for this as well.&lt;/p&gt;

&lt;p&gt;Some strategies for this could be to use a stable version of the Lambda on rollback, or to always roll forward, and so on.&lt;/p&gt;

&lt;h2 id=&quot;finally&quot;&gt;Finally&lt;/h2&gt;

&lt;p&gt;Okay, now that I know everything about ACRs, can I go write some code?&lt;/p&gt;

&lt;p&gt;Yes!&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;p&gt;[1] - &lt;a href=&quot;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html&quot;&gt;AWS Custom Resource&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2] - &lt;a href=&quot;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref-requests.html&quot;&gt;AWS Custom resource request objects&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[3] - &lt;a href=&quot;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref-responses.html&quot;&gt;AWS Custom resource response objects&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[4]  - &lt;a href=&quot;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cfn-customresource.html&quot;&gt;AWS::CloudFormation::CustomResource&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[5] - &lt;a href=&quot;https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html&quot;&gt;AWS Serverless Application Model (SAM)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[6] - &lt;a href=&quot;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html&quot;&gt;AWS::Lambda::Function&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[7] - &lt;a href=&quot;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-layerversion.html&quot;&gt;AWS::Lambda::LayerVersion&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[8] - &lt;a href=&quot;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html&quot;&gt;Fn::GetAtt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[9] - &lt;a href=&quot;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-parameter.html&quot;&gt;AWS::SSM::Parameter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[10] - &lt;a href=&quot;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html&quot;&gt;Fn::ImportValue&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[11] - &lt;a href=&quot;https://en.wikipedia.org/wiki/Joe_Armstrong_(programmer)&quot;&gt;Joe Armstrong&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[12] - &lt;a href=&quot;https://youtu.be/TTM_b7EJg5E&quot;&gt;The Do’s and Don’ts of Error Handling&lt;/a&gt;&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>How to create Golang code snippets in VSCode</title>
        <link href="http://www.motivatedcoder.com/how-to-create-golang-code-snippets-in-vscode/"/>
        <updated>2021-09-06T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/how-to-create-golang-code-snippets-in-vscode</id>
        <content type="html">&lt;p&gt;Here is how to create Golang code snippets in VSCode.&lt;/p&gt;

&lt;p&gt;Steps&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Go to &lt;strong&gt;Preferences &amp;gt; User Snippets&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Select &lt;strong&gt;New Global Snippets File&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Name the file &lt;strong&gt;go.json&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Start with existing snippets like: &lt;a href=&quot;https://github.com/aaronlelevier/vscode-snippets/blob/master/go.json&quot;&gt;go.json&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now validate&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Test one of the existing snippets&lt;/li&gt;
  &lt;li&gt;Add a new snippet&lt;/li&gt;
  &lt;li&gt;Test new snippet&lt;/li&gt;
&lt;/ul&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Value Objects</title>
        <link href="http://www.motivatedcoder.com/Value-Objects/"/>
        <updated>2021-07-10T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/Value-Objects</id>
        <content type="html">&lt;p&gt;Hello! This blog discusses the pattern of value objects as I use them, why they are useful, and some real world use cases.&lt;/p&gt;

&lt;p&gt;Hello, my name is Aaron Lelevier, and I hope that you enjoy the blog and come away with a new tool (design pattern) in your tool chest.&lt;/p&gt;

&lt;h2 id=&quot;what-is-a-value-object&quot;&gt;What is a Value Object&lt;/h2&gt;

&lt;p&gt;Let’s start with a definition. A value object (VO) is an object that stores some data that is logically grouped together. It can have data attributes but not behavior.&lt;/p&gt;

&lt;p&gt;The VO can represent an object in the business domain, concept, or rule(s).&lt;/p&gt;

&lt;p&gt;The VO should be properly constructed, so it recieves all arguments when it is initialized and does not call separate methods at a later time to mutate itself.&lt;/p&gt;

&lt;p&gt;The VO should be read only. It can potentially make API reads to load data, possibly lazy load, and this should be idempotent.&lt;/p&gt;

&lt;p&gt;The VO can read by other objects that understand its type (interface).&lt;/p&gt;

&lt;p&gt;The VO should not have methods for API write calls or writing to a database. After all, it is a value.&lt;/p&gt;

&lt;h2 id=&quot;proper-construction&quot;&gt;Proper Construction&lt;/h2&gt;

&lt;p&gt;The Proper Construction concept is powerful because it allows an object to be immediately useful upon initialization. I have worked in codebases where objects have to call 2 or 3 methods before they have all of their data. Proper Construction removes that.&lt;/p&gt;

&lt;p&gt;Some programming languages, use immutable objects, for example &lt;a href=&quot;https://erlang.org/doc/apps/erts/users_guide.html&quot;&gt;Erlang&lt;/a&gt;. In these languages the new object needs to be assigned to a different variable. Immutability removes the mental overhead of needing to confirm if an object has been mutated, or worse reassigned.&lt;/p&gt;

&lt;h2 id=&quot;value-objects-are-for-reading&quot;&gt;Value Objects are for Reading&lt;/h2&gt;

&lt;p&gt;The VO can be a business object, a concept, rule, etc… but it should be a noun. The VO can then be read by other objects in the system, like those that do API writes.&lt;/p&gt;

&lt;h2 id=&quot;program-to-an-interface-not-an-implementation&quot;&gt;Program to an interface not an implementation&lt;/h2&gt;

&lt;p&gt;The VO should have a Type (Interface). This will allow creation of an object with the same interface in different circumstances that are then understood by other objects in the system.&lt;/p&gt;

&lt;h2 id=&quot;value-objects-and-eliminators&quot;&gt;Value Objects and Eliminators&lt;/h2&gt;

&lt;p&gt;An Eliminator, from the book &lt;a href=&quot;https://thelittletyper.com/&quot;&gt;The Little Typer&lt;/a&gt;, is a function that takes a value as an argument. An Eliminator then must understand the value’s type. This pattern scales well if the VO’s complies to an interface, and then the Eliminator can be programmed to work with that interface.&lt;/p&gt;

&lt;h2 id=&quot;cqrs&quot;&gt;CQRS&lt;/h2&gt;

&lt;p&gt;VO’s and Eliminators also natrually reinforce &lt;a href=&quot;https://martinfowler.com/bliki/CQRS.html&quot;&gt;CQRS&lt;/a&gt; or Command Query Resource Separation, which is the pattern of separating code for reading and writing. The VO’s should only read data and the Eliminators, not all but some, are then used for API writes.&lt;/p&gt;

&lt;h2 id=&quot;real-world-use-case-for-value-objects&quot;&gt;Real World use case for Value Objects&lt;/h2&gt;

&lt;p&gt;Here is a real world example. Let’s say we have a HR system that is responsible for storing employee information.&lt;/p&gt;

&lt;p&gt;The first time an employee is hired, the VO in the system requires all their information to be properly constructed. The VO’s type is Employee. The Empolyee VO is then passed to an Eliminator that handles database writes, and the new employee is added to the HR system. We have followed CQRS.&lt;/p&gt;

&lt;p&gt;Then, the employee is granted access &lt;a href=&quot;https://aws.amazon.com/&quot;&gt;AWS&lt;/a&gt;. We will need their info to grant them access in AWS. Since all of their information is in the HR system, we only need a unique identifier, like their work email, and we can construct an Employee VO of the same type by querying the database. The Employee VO is then used to create as a User in AWS and is provisioned via &lt;a href=&quot;https://aws.amazon.com/cloudformation/&quot;&gt;Cloudformation&lt;/a&gt;, which handles writing and updating resources in AWS. We have followed CQRS again, and this time the API writes were done by Cloudformation.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Thank you for reading. I hope that you can find the value object pattern as useful as I have. Cheers!&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>One Year of Hobby Coding Erlang</title>
        <link href="http://www.motivatedcoder.com/one-year-of-hobby-coding-erlang/"/>
        <updated>2020-05-17T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/one-year-of-hobby-coding-erlang</id>
        <content type="html">&lt;p&gt;I am Celebrating 1 year of hobby coding Erlang as of May 15, 2020. I was talking with my wife and a couple of things stood out about reaching this milestone. There’s some important things that I learned, and some of these have been outside of programming. There are also some bridges that I have yet to cross and next steps that I’d like to list.&lt;/p&gt;

&lt;h2 id=&quot;how-erlang-compares-to-other-languages-that-ive-surveyed&quot;&gt;How Erlang compares to other languages that I’ve surveyed&lt;/h2&gt;

&lt;p&gt;The language that I code in every day is Python, but I try to make a point to learn other languages. Besides SQL, which is the first language that I learned, and used at work for 3 years before getting into Python, I have used a few other languages, but I have never crossed the 1 year mark.&lt;/p&gt;

&lt;h3 id=&quot;java&quot;&gt;Java&lt;/h3&gt;

&lt;p&gt;I used for 10 months with Android, and eventually quit when I realized that I’d have to do UI design if I wanted to build an app. I quit around the time that Android announced support for Kotlin. I think what first got me into Java was reading &lt;em&gt;Test Driven Development&lt;/em&gt; by Kent Beck, which is in Java, and then coding up the examples, and I wanted to then learn the language.&lt;/p&gt;

&lt;h3 id=&quot;swift&quot;&gt;Swift&lt;/h3&gt;

&lt;p&gt;Prior to learning Java, I spent 8 months using Swift. I mostly did online courses, and never really made anything other than the demo apps, and one simple &lt;a href=&quot;https://developer.apple.com/spritekit/&quot;&gt;SpriteKit&lt;/a&gt; game that my daughter was the only one that played. It was about a bunny that hopped to collect coins, and I purchased the images from &lt;a href=&quot;https://graphicriver.net/&quot;&gt;GraphicRiver&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;c&quot;&gt;C++&lt;/h3&gt;

&lt;p&gt;My wife laughed when I told her about this one. I spent 2 weeks learning C++. I bought the book &lt;em&gt;Accelerated C++&lt;/em&gt;, and was driven to learn C++ because machine learning frameworks use C++ under the hood, and the developer API is in Python, so I thought that I should learn it, but, it only lasted 2 weeks.&lt;/p&gt;

&lt;h3 id=&quot;objective-c&quot;&gt;Objective-C&lt;/h3&gt;

&lt;p&gt;This predates all the above languages, and was after I learned Python. I think  that I spent 2 months with Objective-C, and did one book, but forgot all of it.&lt;/p&gt;

&lt;h3 id=&quot;erlang&quot;&gt;Erlang&lt;/h3&gt;

&lt;p&gt;Now Erlang. I had bought Joe Armstrong’s book, &lt;em&gt;Programming Erlang 2nd ed&lt;/em&gt;. because I wanted to learn Erlang for a while, but then held onto the book for 6 months and didn’t read it. Then in May of 2019, I learned about Joe Armstrong’s unexpected passing, and felt compelled to read his book.&lt;/p&gt;

&lt;p&gt;The book is really good. It covers the whole language and Erlang OTP. One of my favorite parts of the book is in the chapter on Maps. I tried to code up the examples, and the code wouldn’t compile. I started googling to see what I did wrong, and I guess Joe had included experimental syntax in the book, that didn’t  get accepted by the Erlang language board. I could feel Joe’s personality when I read the book.&lt;/p&gt;

&lt;p&gt;So then what happened?&lt;/p&gt;

&lt;h2 id=&quot;more-than-just-one-erlang-book&quot;&gt;More than just one Erlang book&lt;/h2&gt;

&lt;p&gt;In July of 2019, I had the pleasure of attending Code Elixir LDN 2019. This was the first time that I had been exposed to the Erlang/Elixir community.&lt;/p&gt;

&lt;p&gt;Some of the ideas were very different. At the conference, I listened to some of the best talks that I have ever heard, fresh with ideas that were new to me.&lt;/p&gt;

&lt;p&gt;I attended the happy hour after and got to hang out with the speakers. Then the founder of &lt;a href=&quot;https://www.erlang-solutions.com/home.html&quot;&gt;Erlang Solutions&lt;/a&gt;, Francesco Cesarini, approached me and asked me how I liked the conference. I told him about my Erlang journey, and how I was half way through the &lt;em&gt;Programming Erlang&lt;/em&gt; book. Francesco said:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;That’s good. You’re reading Joe’s book. After your done with his book, you should read my book.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I listened to what he said, but let me get to that in a minute.&lt;/p&gt;

&lt;p&gt;So in November/December 2019, I finished the &lt;em&gt;Programming Erlang&lt;/em&gt; book and thought that I was ready to build software using Erlang. I started a project using &lt;a href=&quot;https://github.com/ninenines/cowboy&quot;&gt;Erlang Cowboy&lt;/a&gt;, a “Small, fast, modern HTTP server for Erlang/OTP”, and got stuck, so I contacted the creator of Cowboy, Loïc Hoguin, for consulting. I booked 1 hour, and thought that it would be worth it if I could make this software idea that I had. We ended up working together for 30 minutes, and it was pretty obvious to me that I wasn’t ready. We exchanged a few emails after that, and I told Loïc that I wasn’t sure if I needed the other 30 minutes of consulting because I needed to learn Erlang first. He told me:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Glad you’re still enjoying Erlang! It is indeed pretty pretty big.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After that, I quit the software project and started reading Francesco’s book &lt;em&gt;Erlang Programming&lt;/em&gt;. This time taking my time to let the language and concepts soak in, and not force myself to learn it with the goal of building something, as I did with the first book.&lt;/p&gt;

&lt;h2 id=&quot;where-am-i-at-today&quot;&gt;Where am I at today&lt;/h2&gt;

&lt;p&gt;As of today, I’m on pg. 290, ch-12 of &lt;em&gt;Erlang Programming&lt;/em&gt;, and have gotten back to Erlang OTP. I am taking my time to learn more about Erlang, distributed programming and functional programming.&lt;/p&gt;

&lt;p&gt;I have mostly been coding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gen_server&lt;/code&gt;’s at this point, and some one or two &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gen_statem&lt;/code&gt;. I am about to add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;supervisor&lt;/code&gt;’s to the mix.&lt;/p&gt;

&lt;p&gt;I started reading the book &lt;em&gt;Distributed Algorithms&lt;/em&gt; by Nancy Lynch in conjunction with &lt;em&gt;Erlang Programming&lt;/em&gt; by Francesco Cesarini. Today, I finished coding the Leader Election LCR algorithm in Erlang. &lt;a href=&quot;https://github.com/aaronlelevier/syncnet/tree/lcr&quot;&gt;Here&lt;/a&gt; is the commit tag, so I know what happened later!&lt;/p&gt;

&lt;p&gt;I am also reading &lt;em&gt;The Litter Typer&lt;/em&gt;. This book is about dependent types. It was recommended by one of the speakers at Code Elixir LDN 2019. I’m enjoying it so far, and it should be valuable to go along with the other learning.&lt;/p&gt;

&lt;p&gt;I am learning more about functional programming (FP). After using Erlang OTP more, and some of the behaviors, I plan to spend more time on FP.&lt;/p&gt;

&lt;h2 id=&quot;what-has-been-really-cool&quot;&gt;What has been really cool&lt;/h2&gt;

&lt;p&gt;Erlang and FP in general makes you think differently.&lt;/p&gt;

&lt;p&gt;I was explaining Erlang to a friend and relating it to Python and Object Oriented Programming (OOP), and I said:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In Erlang each process is like an object instance, but those objects are all running processes, and they communicate concurrently.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If that’s not cool, I don’t know what is.&lt;/p&gt;

&lt;p&gt;When coding in Erlang, you have to think about concurrency, and if something is timing related. I have written code with tests, where the test needs to wait for a “done” message from a certain process before proceeding. What you end up with is a partially synchronous system, which makes up most systems.&lt;/p&gt;

&lt;p&gt;Erlang has all of the primitives for a highly concurrent fault tolerant system, and being able to build stuff with these primitives is a lot of fun.&lt;/p&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s next&lt;/h2&gt;

&lt;p&gt;Finish Francesco Cesarini’s book, &lt;em&gt;Erlang Programming&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Fully learn Erlang OTP and all the behaviors.&lt;/p&gt;

&lt;p&gt;Write a simple Erlang App using OTP.&lt;/p&gt;

&lt;p&gt;I want to learn how to use the Erlang debugger, and not just log statements.&lt;/p&gt;

&lt;p&gt;Ourside of Erlang, I want to continue to read the &lt;em&gt;Distributed Algorithms&lt;/em&gt;’s book. I first put “finish”, but this is a big book!&lt;/p&gt;

&lt;p&gt;For FP, I want to learn more &lt;a href=&quot;https://degoes.net/articles/fp-glossary&quot;&gt;concepts&lt;/a&gt; and about &lt;a href=&quot;https://www.ibm.com/developerworks/library/j-ft10/index.html&quot;&gt;functional design patterns&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I am definitely not where I thought that I would be. I thought that I would be building full fledged Erlang applications by now, but I am okay with that. I am still having fun, and don’t plan to on changing hobby languages quite yet. For a minute, the thought entered my mind, “how about trying Haskell.” But, then I thought about all of the time that I’ve spent with Erlang learning the primitives, and it’s better to stick with it.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>A RDBMS for AWS using Django and Erlang</title>
        <link href="http://www.motivatedcoder.com/djangoaws-a-rdbms-for-aws-using-django/"/>
        <updated>2019-12-01T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/djangoaws-a-rdbms-for-aws-using-django</id>
        <content type="html">&lt;p&gt;I have a dream for a tech stack where Python and Erlang live together. I feel like I took the first step towards that today. Here is an overview of a code spike for creating a Postgres DB with data from AWS and reading from the same Postgres DB using Erlang.&lt;/p&gt;

&lt;h1 id=&quot;the-stack&quot;&gt;The Stack&lt;/h1&gt;

&lt;p&gt;The stack consists of technologies that I currently use or have used in the past. It’s familiar. So far, the stack consists of:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Python3&lt;/li&gt;
  &lt;li&gt;Django&lt;/li&gt;
  &lt;li&gt;PostgerSQL&lt;/li&gt;
  &lt;li&gt;Erlang&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;lets-see-it&quot;&gt;Let’s see it&lt;/h1&gt;

&lt;p&gt;This is best demostrated by examples, so I’m going to refer to the Github Repo’s and READMEs.&lt;/p&gt;

&lt;h3 id=&quot;djangopython&quot;&gt;Django/Python&lt;/h3&gt;

&lt;p&gt;Here is the Django/Python README: &lt;a href=&quot;https://github.com/aaronlelevier/djangoaws&quot;&gt;https://github.com/aaronlelevier/djangoaws&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This code can be used to create a PostgreSQL database, migrate the schema, and populate it with data from AWS EC2.&lt;/p&gt;

&lt;h3 id=&quot;erlang&quot;&gt;Erlang&lt;/h3&gt;

&lt;p&gt;Then here is example code for connecting to the same database setup and populated by Django, but reading from it using Erlang: &lt;a href=&quot;https://github.com/aaronlelevier/motivatedcoder&quot;&gt;https://github.com/aaronlelevier/motivatedcoder&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;This is a code spike. The code could be extend for more AWS resources, or connected to other parts of tech stack.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Code Elixir LDN 2019</title>
        <link href="http://www.motivatedcoder.com/code-elixir-ldn-2019/"/>
        <updated>2019-07-21T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/code-elixir-ldn-2019</id>
        <content type="html">&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/NgTGu8u.jpg&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Interesting thing. Do you know that if you go to the conference website, this blog uses the same slug? Here’s the link. Or you can trust that the link is the same as the href text below. &lt;a href=&quot;https://codesync.global/conferences/code-elixir-ldn-2019/&quot;&gt;https://codesync.global/conferences/code-elixir-ldn-2019/&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;code-elixir-london&quot;&gt;Code Elixir London&lt;/h1&gt;

&lt;p&gt;This blog post is from my conference notes. I took 10 pages of notes. The notes however got soaked by rain inside my backpack because it was raining so hard the next day and I cycled to Richmond Park. They have since dried up pretty good though. Here are notes. They are not in exact cronological order of the speeches because when I dried out the pages the order was messed up.&lt;/p&gt;

&lt;p&gt;Annotated notes may be part 2. For now it was just a lot to copy 10 pages of notes, fixing spelling and typos errors and so on.&lt;/p&gt;

&lt;h1 id=&quot;conference-notes&quot;&gt;Conference Notes&lt;/h1&gt;

&lt;p&gt;Here we go :)&lt;/p&gt;

&lt;h2 id=&quot;keynote&quot;&gt;Keynote&lt;/h2&gt;

&lt;p&gt;understand the team level&lt;/p&gt;

&lt;p&gt;review project - understand level&lt;/p&gt;

&lt;p&gt;flash cards - improves recall&lt;/p&gt;

&lt;p&gt;pair programming (for 3 hours) others can view but don’t interupt&lt;/p&gt;

&lt;p&gt;teaching - ask for understanding first, listen, then add, not the other way around&lt;/p&gt;

&lt;p&gt;flashcards&lt;/p&gt;

&lt;p&gt;why? options&lt;/p&gt;

&lt;p&gt;positive reinforcement&lt;/p&gt;

&lt;p&gt;pair programming - be writing code or code challenge, to understand how to help&lt;/p&gt;

&lt;p&gt;mentor - focus on teaching concepts&lt;/p&gt;

&lt;h2 id=&quot;performant-string-processing-in-elixir---work-at-castle&quot;&gt;Performant String Processing in Elixir - work at Castle&lt;/h2&gt;

&lt;p&gt;Erlang Term Storage (ets) - like Redis for Erlang. read/writes in constant time. Replace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ets:table&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://hexdocs.pm/elixir/Stream.html&quot;&gt;streams&lt;/a&gt; - read data as a stream and only split 1x&lt;/p&gt;

&lt;p&gt;iolists - can call print 1x instead of per line. List of strings vs. list of references&lt;/p&gt;

&lt;p&gt;Thought Process&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;confirm problem&lt;/li&gt;
  &lt;li&gt;set goal&lt;/li&gt;
  &lt;li&gt;create benchmark&lt;/li&gt;
  &lt;li&gt;iterate on changes&lt;/li&gt;
  &lt;li&gt;consider tradeoffs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;can’t pass a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ets:table&lt;/code&gt; between processes&lt;/p&gt;

&lt;p&gt;can pass a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; between processes&lt;/p&gt;

&lt;p&gt;binary compile pattern - for pattern matching strings&lt;/p&gt;

&lt;p&gt;Unix Interface Design Patterns - book&lt;/p&gt;

&lt;p&gt;dtrace - to fully trace system calls&lt;/p&gt;

&lt;p&gt;nible csv - csv paring library&lt;/p&gt;

&lt;h2 id=&quot;elixir-for-iot-by-james&quot;&gt;Elixir for IoT by James&lt;/h2&gt;

&lt;p&gt;everything that is a physical IoT thing is a process&lt;/p&gt;

&lt;p&gt;have a durable message store&lt;/p&gt;

&lt;p&gt;John Hughes - Lambda Days talk Feb 2019 - also IoT related&lt;/p&gt;

&lt;p&gt;communication is all using binary&lt;/p&gt;

&lt;p&gt;Gattling - load testing for Users&lt;/p&gt;

&lt;p&gt;Mocks - testing devices - use mocks for send / receive to IoT device&lt;/p&gt;

&lt;p&gt;Basher&lt;/p&gt;

&lt;p&gt;Akka - other async language&lt;/p&gt;

&lt;p&gt;The Little Typer - book&lt;/p&gt;

&lt;p&gt;Nerves - for embedded devices&lt;/p&gt;

&lt;p&gt;IoT &amp;lt;—&amp;gt; Cloud &amp;lt;—&amp;gt; Demand Response Predictor&lt;/p&gt;

&lt;p&gt;1984 - by George Orwell - book&lt;/p&gt;

&lt;h2 id=&quot;type-classes-and-programming-vocabulary---erlang-solutions-michael&quot;&gt;Type Classes and Programming Vocabulary - Erlang Solutions, Michael&lt;/h2&gt;

&lt;p&gt;productive / inspiring - did a venn diagram of the two potentially overlapping but said lets think of then not overlapping&lt;/p&gt;

&lt;p&gt;Vocabulary&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Semigroupoid&lt;/li&gt;
  &lt;li&gt;Contravarient&lt;/li&gt;
  &lt;li&gt;Monad&lt;/li&gt;
  &lt;li&gt;Comonad&lt;/li&gt;
  &lt;li&gt;Traversible&lt;/li&gt;
  &lt;li&gt;Monoid&lt;/li&gt;
  &lt;li&gt;endofactors&lt;/li&gt;
  &lt;li&gt;functor&lt;/li&gt;
  &lt;li&gt;Applicative&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Type Class - is the interface&lt;/p&gt;

&lt;p&gt;Functor - an iterable that a func can be applied to. Should return the same number of items. Traversible&lt;/p&gt;

&lt;p&gt;Brookly Zelentak @ espede Elixir&lt;/p&gt;

&lt;p&gt;Words&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;GenServer&lt;/li&gt;
  &lt;li&gt;Supervisor&lt;/li&gt;
  &lt;li&gt;Process&lt;/li&gt;
  &lt;li&gt;Actor&lt;/li&gt;
  &lt;li&gt;Enum&lt;/li&gt;
  &lt;li&gt;Stream&lt;/li&gt;
  &lt;li&gt;Task&lt;/li&gt;
  &lt;li&gt;GenStage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;design patterns&lt;/p&gt;

&lt;p&gt;put all impure functions in a module called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;effects&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;learn the concepts and words then apply them&lt;/p&gt;

&lt;h2 id=&quot;resisting-object-oriented-programming---works-at-mailchimp&quot;&gt;Resisting object Oriented Programming - works at MailChimp&lt;/h2&gt;

&lt;p&gt;hegemony - vocab word - means someone dominating - can be physical or by concept&lt;/p&gt;

&lt;p&gt;Gang of Four - design patterns&lt;/p&gt;

&lt;p&gt;LU Cache - least recently used Cache&lt;/p&gt;

&lt;p&gt;Factories - there are faults&lt;/p&gt;

&lt;h2 id=&quot;hold-my-state&quot;&gt;Hold My State&lt;/h2&gt;

&lt;p&gt;always initialize with a default state&lt;/p&gt;

&lt;p&gt;Calling&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;process calculates and returns a value each time before accepting another message&lt;/li&gt;
  &lt;li&gt;provides psuedo back pressure - if process has to answer back before accepting more work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Casting&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;send messages + don’t wait for reply&lt;/li&gt;
  &lt;li&gt;request values whenever&lt;/li&gt;
  &lt;li&gt;kill process + clan up if don’t respond after 10 sec for example&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Workers&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;(I missed this part of the talk)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;event-sourcing-in-elixir&quot;&gt;Event Sourcing in Elixir&lt;/h2&gt;

&lt;p&gt;Everything that occurs is recorded as a Domain Event and saved in Event Store&lt;/p&gt;

&lt;p&gt;Process can subscribe to the Event Store&lt;/p&gt;

&lt;p&gt;Read Stores - can be created to organize data for use by API, UI, etc…&lt;/p&gt;

&lt;p&gt;Language for Producing Types&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Coq&quot;&gt;Coq&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Agda_(programming_language)&quot;&gt;Agda&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;design&quot;&gt;Design&lt;/h2&gt;

&lt;p&gt;Pure Func - maintainable, can run in parallel&lt;/p&gt;

&lt;p&gt;Keyword List - Elixir type, Erlang record type?&lt;/p&gt;

&lt;p&gt;Types&lt;/p&gt;

&lt;p&gt;umbrella application - allow for plug + play, dependency injection, ubiquitous language, releases, delete ability&lt;/p&gt;

&lt;p&gt;Why not umbrella? - if project is small, start with monolith, avoid circular dependencies until business domain is known&lt;/p&gt;

&lt;p&gt;Interface programming&lt;/p&gt;

&lt;p&gt;Struct for create - structs give compile time guarantee, type checking&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Interface&lt;/th&gt;
      &lt;th&gt;Business Logic&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;impure functions&lt;/td&gt;
      &lt;td&gt;pure functions&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;create -&amp;gt;&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt; &lt;/td&gt;
      &lt;td&gt;&amp;lt;- struct&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;struct -&amp;gt;&lt;/td&gt;
      &lt;td&gt;-0&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;GenServer&lt;/p&gt;

&lt;p&gt;Phoenix&lt;/p&gt;

&lt;p&gt;Ecto&lt;/p&gt;

&lt;p&gt;Debuggging&lt;/p&gt;

&lt;h2 id=&quot;ui-testing-with-hound---by-vanessa-lee-from-interactive-vacations&quot;&gt;UI Testing with Hound - by Vanessa Lee from Interactive Vacations&lt;/h2&gt;

&lt;p&gt;to do Selenium tests using Elixir&lt;/p&gt;

&lt;p&gt;target elements, xpath&lt;/p&gt;

&lt;p&gt;use execute scripts - to call Javascript to input text in to a form&lt;/p&gt;

&lt;p&gt;take screenshot, move mouse, keystroke&lt;/p&gt;

&lt;p&gt;Property Based Testing - book&lt;/p&gt;

&lt;p&gt;Can do this testing for checking various different inputs to the same form, func etc…&lt;/p&gt;

&lt;h2 id=&quot;the-alchemists-code&quot;&gt;The Alchemists Code&lt;/h2&gt;

&lt;p&gt;3-7 years to become a senior engineer&lt;/p&gt;

&lt;p&gt;Painting Analogy&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;work in teams&lt;/li&gt;
  &lt;li&gt;use templates - frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Phoenix&lt;/p&gt;

&lt;p&gt;Absinthe&lt;/p&gt;

&lt;p&gt;Separate a Project by Context&lt;/p&gt;

&lt;p&gt;Contexts are like a microservice, have their own domain and should be isolated from other Context&lt;/p&gt;

&lt;p&gt;Can draw a dependency graph between models&lt;/p&gt;

&lt;p&gt;model is aware of another module by importing, sharing a struct, then that’s a dependency&lt;/p&gt;

&lt;p&gt;context - could also be though by directory&lt;/p&gt;

&lt;p&gt;Should be NO cross context communication&lt;/p&gt;

&lt;p&gt;Service -&amp;gt; Model&lt;/p&gt;

&lt;p&gt;Service -&amp;gt; IO -&amp;gt; Model&lt;/p&gt;

&lt;p&gt;Pyramid, from top down could be thought of:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Service&lt;/li&gt;
  &lt;li&gt;IO&lt;/li&gt;
  &lt;li&gt;Model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example path pattern to use:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mylib/*/(model|io|service)/*&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Model - Actors, pure functions&lt;/p&gt;

&lt;p&gt;IO - for impure functions, calling anything external&lt;/p&gt;

&lt;p&gt;Service - all business logic&lt;/p&gt;

&lt;p&gt;Domain Modeling Made Functional - book&lt;/p&gt;

&lt;p&gt;Restart GenServer w/ new State&lt;/p&gt;

&lt;p&gt;state -&amp;gt; perform -&amp;gt; new state&lt;/p&gt;

&lt;p&gt;move impure functions to boundry. This is the:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;interface&lt;/li&gt;
  &lt;li&gt;most public functions&lt;/li&gt;
  &lt;li&gt;1st function called that calls other functions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;purity&lt;/p&gt;

&lt;p&gt;types&lt;/p&gt;

&lt;p&gt;organization&lt;/p&gt;

&lt;p&gt;architecture - event based architecture - all requests sent to broker and distributed from there&lt;/p&gt;

&lt;p&gt;aka Brokered approach&lt;/p&gt;

&lt;p&gt;confident code&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;unit test&lt;/li&gt;
  &lt;li&gt;integration test (don’t mock db)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;libs&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;credo&lt;/li&gt;
  &lt;li&gt;formatter&lt;/li&gt;
  &lt;li&gt;dialyzer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;smoke tests - selenium&lt;/p&gt;

&lt;p&gt;test coverage&lt;/p&gt;

&lt;p&gt;property test&lt;/p&gt;

&lt;p&gt;debug&lt;/p&gt;

&lt;p&gt;tracing&lt;/p&gt;

&lt;p&gt;discuss concepts&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;what - question&lt;/li&gt;
  &lt;li&gt;why&lt;/li&gt;
  &lt;li&gt;how&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;error-free-elixir&quot;&gt;Error Free Elixir&lt;/h2&gt;

&lt;p&gt;design code w/ error handling in minde&lt;/p&gt;

&lt;p&gt;source of errors&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;users&lt;/li&gt;
  &lt;li&gt;other services&lt;/li&gt;
  &lt;li&gt;infrastructure&lt;/li&gt;
  &lt;li&gt;developers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;let it crash&lt;/p&gt;

&lt;p&gt;error tuples&lt;/p&gt;

&lt;p&gt;Heuristics&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;reasonable defaults&lt;/li&gt;
  &lt;li&gt;declarative operations&lt;/li&gt;
  &lt;li&gt;don’t fight the real word&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;think idempotent - if get cancel command 2x let the 2nd one pass because the goal to cancel has been achieved so it’s not an error&lt;/p&gt;

&lt;p&gt;handle the error correctly for what it is&lt;/p&gt;

&lt;p&gt;understand if it is an error, why did it happen&lt;/p&gt;

&lt;p&gt;can we recover from the error&lt;/p&gt;

&lt;p&gt;A Philosophy of Software Design - John Ousterhout - book&lt;/p&gt;

&lt;p&gt;The Art of Destroying Software - Greg Young - talk&lt;/p&gt;

&lt;p&gt;Understand real use cases of the application in order to reduce error handling + understand what reall is an error or not&lt;/p&gt;

&lt;h2 id=&quot;build-a-cli-in-elixir&quot;&gt;Build a CLI in Elixir&lt;/h2&gt;

&lt;p&gt;Why CLI&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;light weight&lt;/li&gt;
  &lt;li&gt;can utilize OS&lt;/li&gt;
  &lt;li&gt;infrastructure level features&lt;/li&gt;
  &lt;li&gt;reproduceability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;run app, output data to JSON, can then run JSON as an event command, etc…&lt;/p&gt;

&lt;p&gt;Developer Experience - robust, speedy, visually intuitive&lt;/p&gt;

&lt;p&gt;Option Parser - Elixir argument parsing module&lt;/p&gt;

&lt;p&gt;use colored text in terminal&lt;/p&gt;

&lt;p&gt;whne debugging - can reference same script + call with arguments reference secrets for environment variables in prod&lt;/p&gt;

&lt;p&gt;don’t reinvent language - use standard commands&lt;/p&gt;

&lt;p&gt;stdout / stderror - be able to easily customize logging&lt;/p&gt;

&lt;p&gt;Exit Codes - don’t use 0/1 - have an error code per failure type&lt;/p&gt;

&lt;p&gt;fail fast&lt;/p&gt;

&lt;h2 id=&quot;lightening-talks&quot;&gt;lightening talks&lt;/h2&gt;

&lt;p&gt;exercism.io - structured series of programming exercises&lt;/p&gt;

&lt;p&gt;community - social platform for sharing thinking&lt;/p&gt;

&lt;p&gt;stackshare.io - share software stack&lt;/p&gt;

&lt;p&gt;portmidi - Elixir midi music player that uses LiveView for SVG UI&lt;/p&gt;

&lt;p&gt;umbrella application with a single port&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;don’t do it in test&lt;/li&gt;
  &lt;li&gt;initialize at compile time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PubSub in Postres&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;LISTEN channel;
NOTIFY chanel;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Can have an Elixir process listening for Postgres Notifications&lt;/p&gt;

&lt;p&gt;Ecto-sandbox - use to proxy to the database when locally testing a frontend app&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;creates a separate DB for testing&lt;/li&gt;
  &lt;li&gt;data API requests can be sent form App to DB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ex_machina&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;natterbox&lt;/li&gt;
  &lt;li&gt;red matter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;kubernetes&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Telemetry&lt;/li&gt;
  &lt;li&gt;Prometheus&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;closing-keynote&quot;&gt;closing keynote&lt;/h2&gt;

&lt;p&gt;The River by Bruce Tate from grox.io&lt;/p&gt;

&lt;p&gt;author&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;programming phoenix&lt;/li&gt;
  &lt;li&gt;dsesigning elixir otp systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;organization&lt;/p&gt;

&lt;p&gt;lifecycle - get failover for free; turn off + on again&lt;/p&gt;

&lt;p&gt;concurrency - modeling real life objects&lt;/p&gt;

&lt;p&gt;Platformatec, Bleacher Report, Dockyard - Chris, Le Tote, Erlang Solutions&lt;/p&gt;

&lt;p&gt;Erlang Ecosystem Foundation - way to get involved&lt;/p&gt;

&lt;p&gt;Garden Bot - IoT Elixir bot for watering garden&lt;/p&gt;

&lt;p&gt;Texas Whitewater - by Steve Daniel - book&lt;/p&gt;

&lt;p&gt;Stewardship Made Practical - by Stewart ? - talk&lt;/p&gt;

&lt;p&gt;Outside Magazine - has a contest for the best places to live Outdoors&lt;/p&gt;

&lt;p&gt;Regents Canal - places to go&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Elixir is done” - Jose Valim&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Syntax is stable&lt;/p&gt;

&lt;p&gt;libs&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;LiveView&lt;/li&gt;
  &lt;li&gt;Scene&lt;/li&gt;
  &lt;li&gt;Nerves&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;vote with your values, dollars, time, companionship&lt;/p&gt;

&lt;h1 id=&quot;speaking-with-the-people&quot;&gt;Speaking with the people&lt;/h1&gt;

&lt;p&gt;I am kind of bad with names. I started talking to someone about cycling. He recommended that I go to Richmond Park the following day. That’s what I ended up doing, and it was amazing. There’s deer with giant antlers, 2 lakes. It was great.&lt;/p&gt;

&lt;p&gt;Everyone was so nice. Herb, it was great to talk with you, your friend, James, and the others.&lt;/p&gt;

&lt;p&gt;We talked about the how the infix operator isn’t efficient for appending to the tail of a list. It is also the case for removing items from the tail of a list and the complexity is N square.&lt;/p&gt;

&lt;p&gt;Everyone was so kind and welcoming.&lt;/p&gt;

&lt;h2 id=&quot;advice-i-got&quot;&gt;Advice I got&lt;/h2&gt;

&lt;p&gt;Francesco, it was great to meet you. Thank you for some road map advice to consider after I’m done with Programming Erlang 2nd Ed., Joe Arstrong’s book.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Erlang Programming: A Concurrent Approach to Software Development&lt;/li&gt;
  &lt;li&gt;Defining Scalability for OTP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First learn concurrency, a process can only change it’s own state&lt;/p&gt;

&lt;p&gt;Next, processes are an event handler, finite state machine. Client server, supervisor, worker, and so on&lt;/p&gt;

&lt;p&gt;Glamorous Toolkit - editor&lt;/p&gt;

&lt;p&gt;Purely functional data structures&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;The conference was a very unique oppurtunity and I appreciate it a lot. I hope to go to Code Mesh SF in March 2020. Or maybe the RabbitMQ conference.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Erlang and Python Codejam</title>
        <link href="http://www.motivatedcoder.com/erlang-and-python-codejam/"/>
        <updated>2019-07-03T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/erlang-and-python-codejam</id>
        <content type="html">&lt;p&gt;If you can read this Erlang code jam, the syntax is kind of insane. Just think about it. This is how to manipulate primitive types in Erlang. But not just that. After that is a Python codejam. Python is my main language. It will be fun to compare.&lt;/p&gt;

&lt;p&gt;Here are list, tuple, and zip two lists in both languages. But, first, a short background.&lt;/p&gt;

&lt;h1 id=&quot;my-story&quot;&gt;My Story&lt;/h1&gt;

&lt;p&gt;I’m new to Erlang. I’m on page 110 of &lt;a href=&quot;Joe Armstrong (programmer) - Wikipedia
https://en.wikipedia.org/wiki/Joe_Armstrong_(programmer)&quot;&gt;Joe Armstrong&lt;/a&gt;’s book, &lt;a href=&quot;https://gangrel.files.wordpress.com/2015/08/programming-erlang-2nd-edition.pdf&quot;&gt;Programming in Erlang, 2nd&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Erlang is an interesting language. The first time that I tried to learn Erlang, about 1 year ago, a good friend said, “wait until you see pattern matching.” I was reading this exact same book, and was to about page 70, and I still hadn’t seen pattern matching.&lt;/p&gt;

&lt;p&gt;My interests changed, and I gave up reading the book. I had gotten so stuck on &lt;a href=&quot;https://www.tensorflow.org/tfx/serving/serving_basic&quot;&gt;Tensorflow Extended (TFX)&lt;/a&gt; and had paused any project coding because I was so frustrated. 2 months ago, I started reading the book after hearing in May 2019 of Joe Armstrong’s untimely death.&lt;/p&gt;

&lt;p&gt;TFX had promised me an end-to-end pipeline. There are about 9 steps. When I got two thirds of the way through to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;transform&lt;/code&gt; step, I got so frustrated with the objects involed and their api. Whatever I was trying to do wasn’t working. I gave up.&lt;/p&gt;

&lt;p&gt;In May, I stated reading “Erlang Programming 2nd Ed.” by Joe Armstrong. So, if I do the math, in 60 days I have read 110 pages, so 2 pages a day. Ouch. Okay, that’s kind of bad. Either way, here is my progress. Maybe I only got serious in the last month, and I’m being hard on myself. Enjoy.&lt;/p&gt;

&lt;h1 id=&quot;python-and-erlang&quot;&gt;Python and Erlang&lt;/h1&gt;

&lt;p&gt;Let’s do Erlang first. I’ll build myself up for Python. Python is my main language, so I’ll show that last.&lt;/p&gt;

&lt;h2 id=&quot;erlang&quot;&gt;Erlang&lt;/h2&gt;

&lt;p&gt;Map, List, Tuple, Zip Code Example&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/aaronlelevier/ae9de743265ffe6c23ddc9f513062c4b.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;And from there, I could get back to where I eventually was.&lt;/p&gt;

&lt;h2 id=&quot;python&quot;&gt;Python&lt;/h2&gt;

&lt;p&gt;Map, List, Tuple, Zip Code Example. Here is the Python codejam. Enjoy.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/aaronlelevier/61051608160d530f0b375e43fff66102.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;Wow, that was a world tour of Python. The slicing here involved lists, where the Erlang slicing used Binaries. Both were slicing of data structures.&lt;/p&gt;

&lt;h1 id=&quot;verdict&quot;&gt;Verdict&lt;/h1&gt;

&lt;p&gt;Okay, hands on the keyboard verdict. Both were amazing! Okay, until next time. Thanks for reading.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Learn How to Code with a Code Challenge</title>
        <link href="http://www.motivatedcoder.com/learn-how-to-code-with-a-code-challenge/"/>
        <updated>2019-06-15T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/learn-how-to-code-with-a-code-challenge</id>
        <content type="html">&lt;p&gt;The theme this week is to do a code challenge in a new language. For this week I will suggest a code challenge and solve it. I challenge you the reader to attempt the same challenge, or make another one up and solve it in a language that you are trying to get better at.&lt;/p&gt;

&lt;h1 id=&quot;background&quot;&gt;Background&lt;/h1&gt;

&lt;p&gt;For me, I have had success by reading books on computer languages or frameworks, and then implementing them in a personal project. This has helped solidify the concepts, syntax of a language, standard library knowledge, and so on.&lt;/p&gt;

&lt;h1 id=&quot;set-the-scene&quot;&gt;Set the Scene&lt;/h1&gt;

&lt;p&gt;Code challenges are like code katas, or working out. You have to flex that muscle to stay fit. And push yourself to new limits in order to grow. That’s the goal of the code challenge.&lt;/p&gt;

&lt;h1 id=&quot;code-challenge&quot;&gt;Code Challenge&lt;/h1&gt;

&lt;p&gt;Here is the challenge to solve. This is an actual problem of mine that I wanted to solve in code. I have a book that I’m reading. I want to know what the date is when I will finish reading this book if I read N number of pages per day. There are a few things that go into this situation that I considered:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;how many pages are in the book&lt;/li&gt;
  &lt;li&gt;what page am I on&lt;/li&gt;
  &lt;li&gt;how many pages will I read per day&lt;/li&gt;
  &lt;li&gt;what is the current date&lt;/li&gt;
  &lt;li&gt;do I have any vacation days where I won’t be reading&lt;/li&gt;
  &lt;li&gt;how may days a week am I resting and not reading&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;optional&quot;&gt;(Optional)&lt;/h2&gt;

&lt;p&gt;Optional challenge to test your code&lt;/p&gt;

&lt;p&gt;Optional challenge to document your code&lt;/p&gt;

&lt;h1 id=&quot;my-code-challenge-attempt&quot;&gt;My Code Challenge Attempt&lt;/h1&gt;

&lt;p&gt;Given the above details, I attempted this using &lt;a href=&quot;http://erlang.org/doc/index.html&quot;&gt;Erlang&lt;/a&gt;. I hadn’t done date arithmetic before, so I would be learning something new. The above code challenge is an actual real problem for me that I wanted to solve. I am reading &lt;a href=&quot;https://gangrel.files.wordpress.com/2015/08/programming-erlang-2nd-edition.pdf&quot;&gt;Programming Erlang 2nd Edition&lt;/a&gt;. Here is my data for the above questions:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;510 = &quot;how many pages are in the book&quot;
63 = &quot;what page am I on&quot;
5 = &quot;how many pages will I read per day&quot;
{2019, 6, 15} = &quot;what is the current date&quot;
17 = &quot;how many vacation days when I won&apos;t be reading&quot;
14 = &quot;how may days a week am I resting and not reading&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here is my code in Erlang:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/aaronlelevier/c2d192fa3e83d7e0cddd9f87282216bc.js&quot;&gt;&lt;/script&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;I enjoyed the code challenge. It gave me a goal to test my current understanding where I wasn’t purely copying book code with small tweaks. I now feel like I understand the language more and am ready to continue reading next week.&lt;/p&gt;

&lt;p&gt;If you are an Erlang developer, I know that the code is really bad. It’s part of the learning process. Don’t worry if your code challenge isn’t pretty. The goal is to solve the problem, and code can always be made prettier or more concise.&lt;/p&gt;

&lt;h1 id=&quot;code-challenge-solutions&quot;&gt;Code Challenge Solutions&lt;/h1&gt;

&lt;p&gt;If you solved the code challenge in another language, please send me a pull request for this blog with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gist&lt;/code&gt; of the code and I can see about adding it to the blog. Thanks.&lt;/p&gt;

&lt;p&gt;Thank you for reading :)&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Test Driven Development with Python</title>
        <link href="http://www.motivatedcoder.com/test-driven-development-with-python/"/>
        <updated>2019-06-09T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/test-driven-development-with-python</id>
        <content type="html">&lt;p&gt;For this blog, I’m going to code up an example project in Python with unit tests. I’ll discuss unit testing while building doing the project. This blog could have been a precursor to &lt;a href=&quot;https://aaronlelevier.github.io/unit-testing-concepts-with-python/&quot;&gt;Unit Testing Concepts with Python&lt;/a&gt;, which discusses more concepts then application. Okay, I hope that you enjoy. Let’s get started.&lt;/p&gt;

&lt;h1 id=&quot;project-overview&quot;&gt;Project Overview&lt;/h1&gt;

&lt;p&gt;For this project, let’s create in Python objects AWS IAM Roles and Policies. Policies can be inline to a single Role, so only that Role can be use that Policy, or a Policy can be attached to a Role, and then the Policy can be also used with other Roles. Let’s start with these initial objects. We can add more detail later.&lt;/p&gt;

&lt;h1 id=&quot;design-first-before-writing-code-and-tests&quot;&gt;Design first before writing code and tests&lt;/h1&gt;

&lt;p&gt;Okay, at this point, I thought that I was ready to start coding up an initial file and tests. Then, I looked up the AWS IAM documentation and some IAM Roles to see what properties they define to make sure that this blog is as accurate as possible uses the same naming.&lt;/p&gt;

&lt;p&gt;I first thought that we will need a single parent class for the Policy and Role objects. Then I looked at the ARN of a single Role. A lot of data is present here. Here is an example ARN and a description of the data it contains:&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;arn:aws:iam::123456789:role/rds-monitoring-role
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It contains this data:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Service - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iam&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;AccountId - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;123456789&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;ResourceType - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;role&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Role Name - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rds-monitoring-role&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, a lot more objects have come forward. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Policy&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Role&lt;/code&gt; are both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResourceType&lt;/code&gt;’s. There is also an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Account&lt;/code&gt; and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Service&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At this point, I have written 2 designs. Here are the 2 designs. The first is in blue pen, the second in pencil. I forgot my rule, always diagram in pencil!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/b4ZvE73.jpg&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We can use them in the future. But first, let’s make sure that our objects can satisfy a simple requirement. They should be able to generate an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ARN&lt;/code&gt; from the composite data that we have identified.&lt;/p&gt;

&lt;h1 id=&quot;our-first-test&quot;&gt;Our first test&lt;/h1&gt;

&lt;p&gt;Let’s ignore the design for now and write our first test. We don’t know how the production (prod) code will be implemented. We do know what it should be able to do though. We want a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Role&lt;/code&gt; to be able to tell us its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ARN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;All of this code lives in &lt;a href=&quot;https://github.com/aaronlelevier/python-unit-testing-examples&quot;&gt;python-unit-testing-examples&lt;/a&gt;. Follow the &lt;a href=&quot;https://github.com/aaronlelevier/python-unit-testing-examples#project-setup&quot;&gt;Project Setup&lt;/a&gt; instructions in the README to install the project and code along with this blog.&lt;/p&gt;

&lt;p&gt;Here’s the test:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;unittest&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;iam&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Role&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RoleTests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unittest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_arn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;rds-monitoring-role&apos;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;role&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arn&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;arn:aws:iam::123456789:role/rds-monitoring-role&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;py.test&lt;/code&gt; from the project home directory to run the test suite.&lt;/p&gt;

&lt;p&gt;There’s no prod code written at this point. Running the above test only with no prod code, will result in this error:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Traceback:
tests/test_iam.py:3: in &amp;lt;module&amp;gt;
    from iam import Role
E   ImportError: cannot import name &apos;Role&apos; from &apos;iam&apos; (/Users/aaron/Documents/github/testing_example/iam/__init__.py)
=================================== 1 error in 0.15 seconds ===================================
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s add some initial prod code and see what happens. Let’s add this code:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;arn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And re-run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;py.test&lt;/code&gt;. This results in the error:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    def test_arn(self):
        name = &apos;rds-monitoring-role&apos;
&amp;gt;       role = Role(name=name)
E       TypeError: Role() takes no arguments

tests/test_iam.py:10: TypeError
================================== 1 failed in 0.16 seconds ===================================
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is because we did correctly add a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Role&lt;/code&gt; class in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iam/__init__.py&lt;/code&gt; file. But, classes have a default empty constructor of: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;def __init__(self):pass&lt;/code&gt; that accepts no arguments, but our test passed in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt; argument. Let’s add a constructor to accept the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt;. Our goal of the test here is to test the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ARN&lt;/code&gt;. Let’s update our code to:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;arn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Re-run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;py.test&lt;/code&gt; and we now get the error:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;self = &amp;lt;test_iam.RoleTests testMethod=test_arn&amp;gt;

    def test_arn(self):
        name = &apos;rds-monitoring-role&apos;
        role = Role(name=name)

        ret = role.arn

&amp;gt;       assert ret == &apos;arn:aws:iam::123456789:role/rds-monitoring-role&apos;
E       AssertionError: assert None == &apos;arn:aws:iam::123456789:role/rds-monitoring-role&apos;

tests/test_iam.py:14: AssertionError
================================== 1 failed in 0.09 seconds ===================================
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is good! All of our previous test fails were due to &lt;strong&gt;test setup errors&lt;/strong&gt;. This is an important concept.&lt;/p&gt;

&lt;h2 id=&quot;test-setup-errors&quot;&gt;Test Setup Errors&lt;/h2&gt;

&lt;p&gt;A test setup error is different then a prod code error. This is an error like we just saw. Maybe it’s a missing import or an undefined variable in the test code. Either way, it’s a problem with the test code and can be solved by setting up the test correctly and only changing test code.&lt;/p&gt;

&lt;p&gt;To fix the first test setup error, we did what is known as &lt;strong&gt;method stubbing&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;method-stubbing&quot;&gt;Method Stubbing&lt;/h2&gt;

&lt;p&gt;Method stubbing is important. We do this so we can call our prod code correctly and know that everything is connected, but not returning the value that we want to test for. For compiled languages like Java, this has to be done, or else the code won’t compile. Methods must be stubbed in order to run initial tests before implementing the method body.&lt;/p&gt;

&lt;p&gt;Python is more forgiving because of dynamic typing, but it is just as important to stub methods when testing. This tells us that we correctly called or prod code from the test.&lt;/p&gt;

&lt;p&gt;After our two test setup errors were fixed, we got what is known as a &lt;strong&gt;graceful test failure&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;graceful-test-failure&quot;&gt;Graceful Test Failure&lt;/h2&gt;

&lt;p&gt;A graceful test failure is when the test finally fails on an assertion. We have set up the test and called our prod code correctly, and now the only thing wrong is that the value that we are supposed to get back. Now we can implement the prod method.&lt;/p&gt;

&lt;p&gt;Let’s now define an initial implementation for the prod method.&lt;/p&gt;

&lt;h2 id=&quot;initial-implementation&quot;&gt;Initial Implementation&lt;/h2&gt;

&lt;p&gt;There are a lot of things wrong with this implementation, but let’s ignore that for a second and see if this allows our test to pass. Here’s the updated method:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;arn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;arn:aws:iam::123456789:role/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;py.test&lt;/code&gt; and now we get:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;tests/test_iam.py .                                                                     [100%]

================================== 1 passed in 0.05 seconds ===================================
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Commit!&lt;/em&gt; Our tests have now passed. We don’t have to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git commit&lt;/code&gt;, that’s just a joke. Or test have passed though for the first time. We succeeded here in a couple of ways:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;we used the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;self.name&lt;/code&gt; attribute defined on the class&lt;/li&gt;
  &lt;li&gt;we &lt;em&gt;failed first&lt;/em&gt;. By failing first, when the test passed later, we know it’s the code that we added that caused it to pass&lt;/li&gt;
  &lt;li&gt;we &lt;em&gt;failed fast&lt;/em&gt;, a favorite tech cliche! The change was quick, and we got to see the test pass&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There’s still a lot to be desired though. Thinking about our initial design and the objects that we identified, and the method body of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arn&lt;/code&gt; property, here are some thoughts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AccountId&lt;/code&gt; shouldn’t be hardcoded in a single method body for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Role.arn&lt;/code&gt;. What about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Policy.arn&lt;/code&gt; when we implement that.&lt;/li&gt;
  &lt;li&gt;same for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;role&lt;/code&gt;. This is hardcoded. We know that this is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ResourceType&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;same for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iam&lt;/code&gt;. This is hardcoded and this is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Service&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before going on to the next section, I did &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git commit&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git tag&lt;/code&gt; at this point for the example code repo. You can check out to the git tag to this point by running:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git checkout first-test-pass
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;improving-the-implementation&quot;&gt;Improving the Implementation&lt;/h1&gt;

&lt;p&gt;Our test is already defined at this point. We can make prod code changes to improve the implementation. This will make the prod code better.&lt;/p&gt;

&lt;p&gt;From our design, we might consider our class as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Resource&lt;/code&gt;, and it should have a required &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resource_type&lt;/code&gt; attribute, equal to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;role&apos;&lt;/code&gt; in this case. We can use the Python &lt;a href=&quot;https://docs.python.org/3/library/abc.html&quot;&gt;abc&lt;/a&gt; module to require a property on a class. Let’s update the code:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;abc&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AbstractResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ABC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abstractproperty&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resource_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AbstractResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;arn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;arn:aws:iam::123456789:role/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;py.test&lt;/code&gt; and get this error:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;self = &amp;lt;test_iam.RoleTests testMethod=test_arn&amp;gt;

    def test_arn(self):
        name = &apos;rds-monitoring-role&apos;
&amp;gt;       role = Role(name=name)
E       TypeError: Can&apos;t instantiate abstract class Role with abstract methods resource_type

tests/test_iam.py:10: TypeError
================================== 1 failed in 0.07 seconds ===================================
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is the error that we want. We are using the &lt;strong&gt;test feedback loop&lt;/strong&gt; here.&lt;/p&gt;

&lt;h2 id=&quot;test-feedback-loop&quot;&gt;Test Feedback Loop&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/sms9k2H.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The test feedback loop means using the development workflow of changing code, run tests, make changes, test, write new test, prod code change, etc… It is:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;the feedback in between writing test and prod code that let’s us know that the code is doing what we want&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The test feedback loop &lt;em&gt;exists in manual testing!&lt;/em&gt;. It is more time consuming to do manual testing though, so if this can be done as much as possible through automated testing, and unit testing because these are the cheapest tests to run, then this is the goal.&lt;/p&gt;

&lt;p&gt;Let’s update the prod code:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;abc&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AbstractResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ABC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abstractproperty&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resource_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AbstractResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resource_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;role&apos;&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;arn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;arn:aws:iam::123456789:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resource_type&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The test should now pass again.&lt;/p&gt;

&lt;h1 id=&quot;move-out-the-rest-of-the-data&quot;&gt;Move out the rest of the data&lt;/h1&gt;

&lt;p&gt;Let’s move out the rest of the data in the method that probably doesn’t belong there. We have lots of choices on how to add configuration to our project. It will vary in complexity. Here’s a way to keep it hardcoded in code, but improve the variable scoping:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;abc&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ACCOUNT_ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;123456789&apos;&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AbstractResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ABC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abstractproperty&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resource_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IamResourceMixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;iam&apos;&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IamResourceMixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AbstractResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resource_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;role&apos;&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;arn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;arn:aws:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ACCOUNT_ID&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resource_type&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here we have made &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ACCOUNT_ID&lt;/code&gt; a global. This could also be loaded as an environment variable or dynamically, but the point is that it’s scope is larger than the initial method.&lt;/p&gt;

&lt;p&gt;We created a mixin class &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IamResourceMixin&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;service&lt;/code&gt; is defined here. This pattern is the &lt;strong&gt;composition pattern&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;composition-pattern&quot;&gt;Composition Pattern&lt;/h2&gt;

&lt;p&gt;The composition pattern combines pieces of functionality in order to make a fully functional class. The classes used to build the concete class may not have all of the functionality to exist on their own, and this is okay. Piecies of functionality can be defined separately, then shared by the classes that need them.&lt;/p&gt;

&lt;p&gt;This pattern is used a lot in &lt;a href=&quot;https://github.com/encode/django-rest-framework/blob/master/rest_framework/viewsets.py&quot;&gt;django-rest-framework&lt;/a&gt; to define API endpoints as classes that support different HTTP request types, where a single HTTP request type is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mixin&lt;/code&gt;.&lt;/p&gt;

&lt;h1 id=&quot;maybe-change-the-implementation-to-this&quot;&gt;Maybe change the implementation to this&lt;/h1&gt;

&lt;p&gt;We could further change our working code example to:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;abc&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ACCOUNT_ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;123456789&apos;&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AbstractResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ABC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abstractproperty&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resource_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IamResourceMixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;iam&apos;&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AbstractIamResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IamResourceMixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AbstractResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AbstractIamResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resource_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;role&apos;&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;arn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;arn:aws:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ACCOUNT_ID&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resource_type&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here, we put the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mixin&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Abstract&lt;/code&gt; class in a single class, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Role&lt;/code&gt; inherits from that class. This might be a nice change, so when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Policy&lt;/code&gt; is added, it can inherit from a single class, instead of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IamResourceMixin&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbstractResource&lt;/code&gt; class, which Policy will need both, since it also defines an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;iam&apos;&lt;/code&gt; service with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resource_type&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I did a code commit here. To git checkout to this point, run:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git checkout first-mixin-added
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;challenge&quot;&gt;Challenge&lt;/h1&gt;

&lt;p&gt;Okay, now, here’s the &lt;em&gt;challenge!&lt;/em&gt; Implement a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Policy&lt;/code&gt; class with a test for it’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arn&lt;/code&gt; attribute. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arn&lt;/code&gt; should equal:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&apos;arn:aws:iam::123456789:policy/DenyIAMAccess&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;How did that go?&lt;/p&gt;

&lt;h2 id=&quot;policy-class-with-tests-and-refactored&quot;&gt;Policy class with tests and refactored&lt;/h2&gt;

&lt;p&gt;I implemented the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Policy&lt;/code&gt; class and also refactored. To see the new code, run:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git checkout add-policy-class
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There’s been lots of code blocks, so at this point, I did a few changes at once. First, the test code:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PolicyTests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unittest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_arn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;DenyIAMAccess&apos;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;role&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Policy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arn&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;arn:aws:iam::123456789:policy/DenyIAMAccess&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Very similar to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RoleTests.test_arn&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;For the prod code:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;abc&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ACCOUNT_ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;123456789&apos;&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AbstractResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ABC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abstractproperty&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abstractproperty&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resource_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;arn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;arn:aws:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ACCOUNT_ID&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;resource_type&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AbstractIamResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AbstractResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;iam&apos;&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AbstractIamResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resource_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;role&apos;&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Policy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AbstractIamResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;property&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resource_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;policy&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So, I had the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PolicyTests&lt;/code&gt; code in place. I got it to pass by basically copying the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Role&lt;/code&gt; class and renaming the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resource_type&lt;/code&gt;. There was a fair amount of duplication though. I started moving things around, and came up with the above code. I think this is better for a few reasons:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arn&lt;/code&gt; property exists on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbstractResource&lt;/code&gt; class. This is better. All AWS Resources have ARNs, so it makes sense for this to be defined on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbstractResource &lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;service&lt;/code&gt; is now an abstract property. This is better because Services should have to define what kind of Service that they are.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Abstract&lt;/strong&gt; is an important concept here.&lt;/p&gt;

&lt;h2 id=&quot;abstract-and-concrete-classes&quot;&gt;Abstract and Concrete Classes&lt;/h2&gt;

&lt;p&gt;Abstract classes can’t be instantiated from. They are meant to be inherited from. In the above example, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arn&lt;/code&gt; property is being accessed, and this property references a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resource_type&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt; attribute. These are defined on the concrete classes, Role and Policy.&lt;/p&gt;

&lt;p&gt;If we were to instantiate a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AbstractIamResource&lt;/code&gt; and access it’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arn&lt;/code&gt; we would get an error.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;This blog may have been better named:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;scenic stroll through testing and code design&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I kind of took some side trips away from just testing, but I hope that you enjoyed it and they made sense in the context of testing and added value.&lt;/p&gt;

&lt;p&gt;In this blog we learned how to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;write test code first&lt;/li&gt;
  &lt;li&gt;test setup error&lt;/li&gt;
  &lt;li&gt;test stub&lt;/li&gt;
  &lt;li&gt;graceful test fail&lt;/li&gt;
  &lt;li&gt;test feedback loop&lt;/li&gt;
  &lt;li&gt;composition pattern&lt;/li&gt;
  &lt;li&gt;code challenge&lt;/li&gt;
  &lt;li&gt;abstract class&lt;/li&gt;
  &lt;li&gt;concrete class&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;next&quot;&gt;Next&lt;/h1&gt;

&lt;p&gt;We didn’t quite get to inline vs. attach Policies. There are more testing concepts to cover next as well. I will extend upon this example and cover more concepts in the next blog.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Unit Testing Concepts with Python</title>
        <link href="http://www.motivatedcoder.com/unit-testing-concepts-with-python/"/>
        <updated>2019-06-01T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/unit-testing-concepts-with-python</id>
        <content type="html">&lt;p&gt;In this blog I am going to discuss some concepts of Unit Testing. I will give some background about my experience and how I got started on unit testing. Then some thoughts and concepts on unit testing in order to best apply it. I will then show a code example in Python and discuss different unit testing concepts used.&lt;/p&gt;

&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;/h1&gt;

&lt;p&gt;Let me start out by introducing myself and the person that got me started on testing.  Hi, my name is Aaron Lelevier. I’ve been using Python for 6 years, 5 years professionally. Prior to that and with some overlap, I did MsSQL for 3 years.&lt;/p&gt;

&lt;p&gt;The person that got me started on unit testing was &lt;a href=&quot;https://twitter.com/toranb&quot;&gt;Toran Billups&lt;/a&gt;. This was 4 years ago. I was hired on at Big Sky Technologies as a backend Python Django Developer on a team of 3, myself, &lt;a href=&quot;https://twitter.com/puekey&quot;&gt;Scott Newcomer&lt;/a&gt;, who did frontend EmberJs, and Toran Billups, who’s background is in Javascript and Test Driven Development (TDD), as Tech Lead. I didn’t know this at the time, but Toran had only agreed to come on the team as Tech Lead if the team embraced testing.&lt;/p&gt;

&lt;p&gt;Toran made a big impact on me. I’d like to share some of his quotes, and give examples with how they apply.&lt;/p&gt;

&lt;h1 id=&quot;quotes-from-toran&quot;&gt;Quotes from Toran&lt;/h1&gt;

&lt;p&gt;Let me start off with a funnier quote. We had been into our project for about 3 months. I was asking Toran about his thoughts on testing for some concept or topic. Then, Toran says to me:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“You know, discussing testing is like discussing religion.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is pretty interesting. I have come across this thought a lot. Some people are against testing and they will fight it. Other people are on the reverse side, and are testing pedantics, and brutally enforce every little thing be tested. Our team was growing while I was at Big Sky, and we wanted to keep our culture of TDD, and people that we discussed this with said “good luck”. It is hard to keep testing a first priority.&lt;/p&gt;

&lt;p&gt;Another quote from Toran was:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Test first or test last. I don’t know about you, but once I’m done writing my code, I don’t want to write tests. I want to go and do the next thing, that’s why I write my tests first.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is true, but also for other reasons. After a feature is considered working, writing tests for it seems laborious. The other reason to test first though, and the real reason I would argue, is to see if the functionality currently exists. If you can write a test that something should occur, and it doesn’t, then when you write the production (prod) code for this, and the test passes. Then you know that it was the code you added that made it work, whereas before it didn’t. The testing cycle proves that.&lt;/p&gt;

&lt;h1 id=&quot;is-this-a-tdd-blog&quot;&gt;Is this a TDD blog?&lt;/h1&gt;

&lt;p&gt;No, it is not. I bring it up as part of the previous quotes, and from some of what Toran taught me. Test First has its place. It is not the only way to test though.&lt;/p&gt;

&lt;p&gt;Sometimes what you are doing is too unknown, so writing tests for something you’ve never done before is too slow, or simply doesn’t work. An example of this is learning a new programming language or framework. It’s much easier to learn by writing code to do the thing then to write tests. For machine learning, this is also true. Some parts of machine learning like data transformations are good places for heavy testing and even TDD. Making a model with layers and iterating on that model may not be.&lt;/p&gt;

&lt;p&gt;There is the concept of Defect Driven Testing (DDT). This is when a defect is discovered, then a test can be written to capture that defect (or bug), so it won’t resurface. Here, the testing scenario isn’t known ahead of time, or else the bug wouldn’t have existed, so TDD doesn’t apply.&lt;/p&gt;

&lt;p&gt;Okay, so what is the goal of testing?&lt;/p&gt;

&lt;h1 id=&quot;goal-of-testing&quot;&gt;Goal of Testing&lt;/h1&gt;

&lt;p&gt;This is best said by this quote from Toran:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“You don’t know if something works unless you have a test that says it does.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This could be an automated test, whether it’s a unit or integration test. It could be a manual test by someone on the QA team or it could be your customers testing in Prod by using your product. Ideally, it’s some sort of automated test though because these are the cheapest test to run, and we don’t want our customers to be the first to test and discover bugs, then have to report them and wait for them to be fixed!&lt;/p&gt;

&lt;p&gt;Let’s start with an overview of unit testing and see a simple application of it in Python for this first blog.&lt;/p&gt;

&lt;h1 id=&quot;unit-testing-overview&quot;&gt;Unit testing overview&lt;/h1&gt;

&lt;p&gt;What is a unit test?&lt;/p&gt;

&lt;p&gt;A unit test is a test for a single piece of functionality in your code. It would be a test for a single function that tests a single code path. If this function, for example, has an if/else block, you would want a unit test for the “if” code path in the function, and a separate unit test for the “else” code path in the function.&lt;/p&gt;

&lt;p&gt;Unit tests are cheap. They are the quickest tests to write and fastests tests to run. They won’t prove that your whole application works. They prove that pieces of the application work in isolation with certain inputs and then verify the outputs.&lt;/p&gt;

&lt;p&gt;Here is the famous Test Pyramid.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/RhOhPqg.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;unit-tests&quot;&gt;Unit Tests&lt;/h2&gt;

&lt;p&gt;Unit tests are at the bottom. This should make up the bulk of your test suite. At Google, they use this ratio, and unit tests make up 70% of their total tests. I heard about this from a Google I/O talk.&lt;/p&gt;

&lt;h2 id=&quot;integration-tests&quot;&gt;Integration Tests&lt;/h2&gt;

&lt;p&gt;These tests start to connect functions and bodies of code together. They don’t stand up the whole application and test though. They are above unit tests for individual pieces and below whole application automated testing.&lt;/p&gt;

&lt;h2 id=&quot;ui-tests-functional-tests&quot;&gt;UI Tests (Functional Tests)&lt;/h2&gt;

&lt;p&gt;UI Tests, or Functional Tests if there is no UI, are automated tests of the whole application. This would be &lt;a href=&quot;https://www.seleniumhq.org/projects/webdriver/&quot;&gt;Selenium&lt;/a&gt; for automated UI testing of a web site, &lt;a href=&quot;http://appium.io/&quot;&gt;Appium&lt;/a&gt; for mobile apps, and so on.&lt;/p&gt;

&lt;h2 id=&quot;level-of-tests-as-a-concept-vary-by-situation&quot;&gt;Level of Tests as a Concept Vary by Situation&lt;/h2&gt;

&lt;p&gt;This is a very good talk on how to test infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=jiWRTuF4yXk&quot;&gt;&lt;img src=&quot;https://i.imgur.com/OKmmbZ2.jpg&quot; alt=&quot;Imgur&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this talk, the speaker discusses how infrastructure can only be fully tested by deploying it. In this testing paradigm, Unit Tests are then single pieces of infrastructure deployed in isolation with the minimal number of dependencies. Integration Tests starts to connect infrastructure, and Functional Tests test the infrastructure as a whole.&lt;/p&gt;

&lt;h1 id=&quot;unit-test-in-python&quot;&gt;Unit test in Python&lt;/h1&gt;

&lt;p&gt;Here is the prod and unit test code from one of my Python project on converting &lt;a href=&quot;https://github.com/wkentaro/labelme&quot;&gt;Labelme&lt;/a&gt; annotations to COCO dataset annotations project called &lt;a href=&quot;https://github.com/aaronlelevier/mlearning&quot;&gt;mlearning&lt;/a&gt;. Let’s take a look at this code and discuss it.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/aaronlelevier/e53fceeaed8323b76212dbcc8c7079ec.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;There are two unit tests for the example class and it’s single method. One tests the scenario that all image files in a directory are ordered by name. The other tests the scenario that they aren’t ordered by name and what the outputs of the method would then be.&lt;/p&gt;

&lt;p&gt;I’m going to discuss a couple of concepts and mechanics from this example code.&lt;/p&gt;

&lt;h1 id=&quot;concepts&quot;&gt;Concepts&lt;/h1&gt;

&lt;p&gt;Unit tests are calling prod code to make assertions about the inputs and outputs. A simple example would be if a function multiplies an input value by two, then the unit test would assert if 1 goes in, 2 comes out, if 3 goes in, 6 is returned, etc…&lt;/p&gt;

&lt;p&gt;Inputs may vary. Sometimes functions have defaults or varying number of arguments. In this case, you would want multiple tests to assert the behavior of that function. The above code is an example of this. The prod code only has a single argument, but two situations are being tested.&lt;/p&gt;

&lt;h1 id=&quot;mechanics-of-unit-testing-in-python&quot;&gt;Mechanics of Unit Testing in Python&lt;/h1&gt;

&lt;p&gt;If you go to the Github repo linked in the description of the gist, or you may be able to derive most of this information from the gist. Here are a few things going on.&lt;/p&gt;

&lt;h2 id=&quot;the-test-runner&quot;&gt;The Test Runner&lt;/h2&gt;

&lt;p&gt;To run unit tests, Python’s unittest test runner needs to be able to discover them.&lt;/p&gt;

&lt;p&gt;I like to put my tests in a directory called “tests” at the project directory level. This is a known pattern. &lt;a href=&quot;https://github.com/encode/django-rest-framework/tree/master&quot;&gt;django-rest-framework&lt;/a&gt; uses this pattern. Another pattern is to put the tests in the same directory as the prod code file and append “_test” to the name. &lt;a href=&quot;https://github.com/tensorflow/tfx&quot;&gt;TensorFlow Extended&lt;/a&gt; uses this pattern. I prefer the former because it separates test code from prod code.&lt;/p&gt;

&lt;p&gt;The test runner will find each Python file that starts with “test_”. I like to name the test file names with the “test_” prefix, so they are discovered by the test runner, and then use the same name as the prod test file. This makes them easier to keep track of.&lt;/p&gt;

&lt;p&gt;The test class should subclass unittest.TestCase. This is because there are setUp and tearDown hooks in the class that can be used.&lt;/p&gt;

&lt;p&gt;Each test method in the class should start with “test_”. The test runner will call these test methods and report success or failure. Test classes are just Python classes. They can have other methods for test helpers, etc… and then these would not start with “test_” because they are a helper, not a test method.&lt;/p&gt;

&lt;h2 id=&quot;pytest&quot;&gt;Pytest&lt;/h2&gt;

&lt;p&gt;The example code is using &lt;a href=&quot;https://docs.pytest.org/en/latest/&quot;&gt;pytest&lt;/a&gt;. I prefer the test syntax of pytest to the standard library unittest methods. Also, pytest gives nice red/green colored highlighting on test output. There is a table in the unittest &lt;a href=&quot;https://docs.python.org/3/library/unittest.html&quot;&gt;documentation&lt;/a&gt; for the different assertion methods. The testing semantics are the same, just with different syntax.&lt;/p&gt;

&lt;p&gt;In the example code, the Python assert keyword can be used to assert if something is truthy or falsy. Assert if equal or not equal, etc…&lt;/p&gt;

&lt;h2 id=&quot;test-class-names&quot;&gt;Test Class Names&lt;/h2&gt;

&lt;p&gt;I like to name the test class the same as the prod class, and then add “Tests” to the end. This makes the test method class easy to search for and identify which prod code the test class relates to.&lt;/p&gt;

&lt;h2 id=&quot;test-method-names&quot;&gt;Test Method Names&lt;/h2&gt;

&lt;p&gt;Test methods have to start with “test_”. For their actual name, I like to have the name of the prod method that I’m testing in the test method name. This makes it easier when searching for tests for a given method.&lt;/p&gt;

&lt;p&gt;A co-worker of mine, &lt;a href=&quot;https://www.linkedin.com/in/vgrato/&quot;&gt;Vince Grato&lt;/a&gt;, said to me once, I use rspec for naming tests. He was calling me out because I had named my test methods based on the prod methods and then with a suffix like “true” or “false”, which would be the output that they test for, but the test method name didn’t say anything about what the test actually did. Over time, and now currently, this is how I name my tests. I still like to have the prod method name in the test method name, and then append a description of what the test is doing.&lt;/p&gt;

&lt;p&gt;Another co-worker of mine, &lt;a href=&quot;https://twitter.com/pixelhandler?lang=en&quot;&gt;Bill Heaton&lt;/a&gt;, said something similar. He said that when he wants to know how some code or library works, he first runs the test suite, and then reads the method names output by the test run to see what the code is doing. This follows along with what Vince said.&lt;/p&gt;

&lt;h2 id=&quot;format-of-the-test-method-body&quot;&gt;Format of the Test Method Body&lt;/h2&gt;

&lt;p&gt;For the test method body, I like to follow the format of:&lt;/p&gt;

&lt;p&gt;Test setup - linespace - code being tested - linespace - assertions&lt;/p&gt;

&lt;p&gt;This is the format of the test method bodies of the example test code above. This makes it easier to follow and separate initial setup that the prod code needs before being called. Then actual code being called, and finally the assertions for that code.&lt;/p&gt;

&lt;p&gt;I believe that I got this from Kent Beck’s book, &lt;a href=&quot;https://www.eecs.yorku.ca/course_archive/2003-04/W/3311/sectionM/case_studies/money/KentBeck_TDD_byexample.pdf&quot;&gt;TDD by Example&lt;/a&gt;, but I am not sure. Either way linespaces can be used to denote meaning in code, and this is a good place for them.&lt;/p&gt;

&lt;h2 id=&quot;test-method-ordering&quot;&gt;Test Method Ordering&lt;/h2&gt;

&lt;p&gt;I prefer to put the test methods in the same order as the prod methods. This makes it easier to relate the prod code to the test code if they follow the same method declaration ordering.&lt;/p&gt;

&lt;p&gt;The above code example is only for a single prod method, but if there were a second method, then the test method would be ordered below the current test methods.&lt;/p&gt;

&lt;h2 id=&quot;test-code-doesnt-look-like-prod-code&quot;&gt;Test Code Doesn’t Look Like Prod Code&lt;/h2&gt;

&lt;p&gt;When I worked with Toran, he said this to me one time:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Where are all the assertions here. There’s all kinds of missing assertions.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Toran is really nice. I asked him for constructive feedback one time when we were having reviews, and he only told me positive things, but I could also glean some things that I could improve on even though he was so positive.&lt;/p&gt;

&lt;p&gt;That said, the above quote means that I had missed a lot in the test coverage. This stemmed from me thinking that code looks like code and test code looks like prod code. It’s object oriented, has arguments, etc…&lt;/p&gt;

&lt;p&gt;The test in question was asserting return values of an API endpoint. The API endpoint was returning 10-15 fields with data, but my test was only testing that 2-3 came back. The prod code could have half of it’s fields removed for example. Maybe it’s a cut/paste error, and it’s not seen in code review. If so, the test would never catch this because it doesn’t assert the full behavior of the API endpoint. This leads to another quote:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Test the things that you care about.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can’t test everything. There is a limit. But, we should do our best to test the things that we care about. And, if this API endpoint is something that we care about, we should fully test it’s behavior.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;I wrote out 1 ½ pages of bullet points on testing over the last few weeks as I thought about different aspects of testing and things that I’d like to discuss. The above is ⅕ of those bullet points. This is a really good start though I think. Thank you for reading. I hope that you enjoyed and this blog added value for you.&lt;/p&gt;

&lt;h1 id=&quot;next&quot;&gt;Next&lt;/h1&gt;

&lt;p&gt;Next blog I will discuss more mechanics for testing, and I will show code examples for different testing concepts and build upon what I discussed in this blog.&lt;/p&gt;

&lt;p&gt;Any feedback is more than welcome. Drop me an email or comment below.&lt;/p&gt;

&lt;p&gt;Thank you.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>My Current Scenic Stroll Through TFX</title>
        <link href="http://www.motivatedcoder.com/my-current-scenic-stroll-through-tfx/"/>
        <updated>2019-04-30T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/my-current-scenic-stroll-through-tfx</id>
        <content type="html">&lt;p&gt;This is a blog is about my current an ongoing stroll through the &lt;a href=&quot;https://github.com/tensorflow/tfx&quot;&gt;TFX&lt;/a&gt; library.&lt;/p&gt;

&lt;h2 id=&quot;why-tfx&quot;&gt;Why TFX?&lt;/h2&gt;

&lt;p&gt;The opening line of the TFX &lt;a href=&quot;https://github.com/tensorflow/tfx/blob/master/README.md&quot;&gt;README&lt;/a&gt; says it all. It says:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;TensorFlow Extended (TFX) is a Google-production-scale machine learning platform based on TensorFlow. It provides a configuration framework to express ML pipelines consisting of TFX components.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is so compelling. The README also says, it’s a:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;framework for building end-to-end ML Pipelines&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, I plan to discuss and document what I’ve seen with TFX so far.&lt;/p&gt;

&lt;p&gt;Ok, let’s go.&lt;/p&gt;

&lt;h2 id=&quot;my-goal&quot;&gt;My Goal&lt;/h2&gt;

&lt;p&gt;My goal and strategy when doing this scenic stroll is to build my own TFX Pipeline for the &lt;a href=&quot;https://en.wikipedia.org/wiki/MNIST_database&quot;&gt;MNIST&lt;/a&gt; dataset and ML models.  The example TFX Pipeline uses the Chicaco Taxi Cab dataset and CSV flat files. By building a slightly more complicated Pipeline, it is forcing me to learn the TFX Framework.&lt;/p&gt;

&lt;h2 id=&quot;the-start&quot;&gt;The Start&lt;/h2&gt;

&lt;p&gt;When I first started, I though, I’ll just plug in MNIST data at the correct file path, and everything will just work. But, it didn’t…&lt;/p&gt;

&lt;p&gt;I next thought, okay, let me tweak a little bit of code. I started to read the source code, and try to do this, but I didn’t understand the source code.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://airflow.apache.org/&quot;&gt;Apache Airflow&lt;/a&gt;, then &lt;a href=&quot;https://beam.apache.org/&quot;&gt;Apache Beam&lt;/a&gt;, what are these things? These are the first 3rd party libraries that you run into when reading the TFX source.&lt;/p&gt;

&lt;h3 id=&quot;apache-airflow&quot;&gt;Apache Airflow&lt;/h3&gt;

&lt;p&gt;Airflow is for creating workflow pipelines as &lt;a href=&quot;https://en.wikipedia.org/wiki/Directed_acyclic_graph&quot;&gt;directed acyclic graphs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I did a separate blog post of Airflow &lt;a href=&quot;https://aaronlelevier.github.io/what-i-know-about-apache-airflow-so-far/&quot;&gt;here&lt;/a&gt; detailing learnings.&lt;/p&gt;

&lt;h3 id=&quot;apache-beam&quot;&gt;Apache Beam&lt;/h3&gt;

&lt;p&gt;Beam is for implementing batch or streaming jobs with a single programming model that uses &lt;a href=&quot;https://en.wikipedia.org/wiki/MapReduce&quot;&gt;MapReduce&lt;/a&gt; with windows and triggers.&lt;/p&gt;

&lt;p&gt;For Beam, the &lt;a href=&quot;https://beam.apache.org/documentation/programming-guide/#core-beam-transforms&quot;&gt;core-overview&lt;/a&gt; in the official documentation was really good.&lt;/p&gt;

&lt;p&gt;This YouTube video, &lt;a href=&quot;https://youtu.be/buXqe0YQjMY&quot;&gt;A Whirlwind Overview of Apache Beam&lt;/a&gt; was also really good for helping to understand Beam.&lt;/p&gt;

&lt;p&gt;Then coding along and doing the core transforms helped make them real before trying to do Beam transforms in TFX. Repo link here: &lt;a href=&quot;https://github.com/aaronlelevier/apache_beam_examples&quot;&gt;aaronlelevier/apache_beam_examples&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, here’s the steps that I’ve gone through of TFX so far.&lt;/p&gt;

&lt;h2 id=&quot;details-on-tfx-pipeline-steps-1-4&quot;&gt;Details on TFX Pipeline Steps 1-4&lt;/h2&gt;

&lt;p&gt;I have been tweaking my work flow for trying to run each Pipeline Airflow Operator.&lt;/p&gt;

&lt;p&gt;The first thing that helped me was to symlink the Airflow pipeline file &lt;a href=&quot;https://github.com/aaronlelevier/tfx/blob/statistics_gen/tfx/examples/mnist/mnist_pipeline_simple.py&quot;&gt;mnist_pipeline_simple.py&lt;/a&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/airflow/dags/mnist/mnist_pipeline_simple.py&lt;/code&gt; where Airflow expects to find it.&lt;/p&gt;

&lt;p&gt;For debugging Airflow, the steps in a blog post that I did, for &lt;em&gt;“What I know about Apache Airflow so Far”&lt;/em&gt;, in this section have worked well:
 &lt;a href=&quot;https://aaronlelevier.github.io/what-i-know-about-apache-airflow-so-far/&quot;&gt;Iterate on developing a DAG in Airflow&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For refreshing the local DBs, I created a helper script: &lt;a href=&quot;https://github.com/aaronlelevier/apache_beam_examples/blob/master/scripts/refresh_mnist_pipeline.sh&quot;&gt;refresh_mnist_pipeline.sh&lt;/a&gt; This way any changes to the Pipeline wont cause a fail due to stale Database schema, data, etc..&lt;/p&gt;

&lt;h3 id=&quot;examplesgen&quot;&gt;ExamplesGen&lt;/h3&gt;

&lt;p&gt;Here, going through the Apache Beam &lt;a href=&quot;https://beam.apache.org/documentation/programming-guide/#core-beam-transforms&quot;&gt;core-transforms&lt;/a&gt; was important to know what’s possible.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://beam.apache.org/documentation/programming-guide/#cogroupbykey&quot;&gt;CoGroupByKey&lt;/a&gt; is needed here to combine 2 files in the case of MNIST, where the image data and labels are in separage Gzip files. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CoGroupByKey&lt;/code&gt; is used to combine 2 or more Beam &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PCollection&lt;/code&gt;’s, then the single &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PCollection&lt;/code&gt; can be output to a TFRecord with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;beam.io.WriteToTFRecord&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;statisticsgen&quot;&gt;StatisticsGen&lt;/h3&gt;

&lt;p&gt;This step is for running &lt;a href=&quot;https://www.tensorflow.org/tfx/data_validation/get_started&quot;&gt;Tensorflow Data Validation&lt;/a&gt; (TFDV) on the dataset to generate statistics.&lt;/p&gt;

&lt;p&gt;In order to do this and visualize the statistics, &lt;a href=&quot;https://docs.bazel.build/versions/master/install.html&quot;&gt;Bazel&lt;/a&gt; must be installed. On Mac OSX, I first installed Bazel using Homebrew, but that didn’t work, so I installed from source, and it worked. I had created an issue with &lt;a href=&quot;https://github.com/tensorflow/data-validation/issues/59&quot;&gt;tensorflow/data-validation&lt;/a&gt; but I then closed it once I realized the issue.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/tensorflow/tfx/blob/master/docs/tutorials/data_validation/chicago_taxi.ipynb&quot;&gt;This&lt;/a&gt; TFDV example Jupyter Notebook was super helpful for figuring out how to call TFDV.&lt;/p&gt;

&lt;h3 id=&quot;schemagen&quot;&gt;SchemaGen&lt;/h3&gt;

&lt;p&gt;This step uses TFDV to generate a Schema, which is the features, labels, and their types for a given dataset.&lt;/p&gt;

&lt;h3 id=&quot;examplevalidator&quot;&gt;ExampleValidator&lt;/h3&gt;

&lt;p&gt;This step then uses TFDV to then compare the statistics generated by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;StatisticsGen&lt;/code&gt; and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Schema&lt;/code&gt; generated by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SchemaGen&lt;/code&gt;. TFDV will look for any anomalies between the &lt;strong&gt;train&lt;/strong&gt; and &lt;strong&gt;eval&lt;/strong&gt; dataset splits, and write them to a file.&lt;/p&gt;

&lt;p&gt;TFDV can also be used to fix these anomalies.&lt;/p&gt;

&lt;h2 id=&quot;next&quot;&gt;Next&lt;/h2&gt;

&lt;p&gt;There’s 4 more steps, then &lt;a href=&quot;https://www.tensorflow.org/tfx/guide/serving&quot;&gt;Tensorflow Serving&lt;/a&gt; can be used to serve the model.&lt;/p&gt;

&lt;p&gt;I will report back soon!&lt;/p&gt;

&lt;p&gt;Thanks for reading :)&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>What I know about Apache Airflow so Far</title>
        <link href="http://www.motivatedcoder.com/what-i-know-about-apache-airflow-so-far/"/>
        <updated>2019-04-07T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/what-i-know-about-apache-airflow-so-far</id>
        <content type="html">&lt;p&gt;This is a blog recording what I know about Apache Airflow so far, and a few lessons learned. This blog is in no means exhuastive on all Airflow can do. Maybe the main point of interest for the reader is the workflow section on how to iterate on adding tasks and testing them.&lt;/p&gt;

&lt;h2 id=&quot;details&quot;&gt;Details&lt;/h2&gt;

&lt;p&gt;I started Apache Airflow with the &lt;a href=&quot;https://airflow.apache.org/start.html&quot;&gt;Quickstart&lt;/a&gt; and &lt;a href=&quot;https://airflow.apache.org/tutorial.html&quot;&gt;Tutorial&lt;/a&gt; and everything seemed pretty straight forward, but when I tried to do some of my own &lt;a href=&quot;https://en.wikipedia.org/wiki/Directed_acyclic_graph&quot;&gt;DAG&lt;/a&gt; ideas and learn some other concepts in Airflow, I got stuck. My DAGs weren’t registering, and I wasn’t sure what was wrong. My DAGs were taking too long to run, too long of a feedback loop. Some of it was because they were in the wrong directory, or had Python Errors.&lt;/p&gt;

&lt;p&gt;I learned to eventually follow this workflow. Okay, here’s it is, but first some vocabulary.&lt;/p&gt;

&lt;h3 id=&quot;airflow-vocabulary&quot;&gt;Airflow Vocabulary&lt;/h3&gt;

&lt;p&gt;Some Airflow vocabulary and concepts that will be used in this blog.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DAG&lt;/code&gt; - directed acyclic graph - in Airflow, a description of the work to take place&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Operator&lt;/code&gt; - a class that acts as a template for a Task. This can be a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BashOperator&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PythonOperator&lt;/code&gt;, etc…&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task&lt;/code&gt; - an instance of an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Operator&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task instance&lt;/code&gt; - a task instance is a Task in a DAG that was run at a certain point in time with a given configuration&lt;/p&gt;

&lt;p&gt;Okay, &lt;em&gt;workflow&lt;/em&gt; time!&lt;/p&gt;

&lt;h3 id=&quot;my-airflow-workflow&quot;&gt;My Airflow Workflow&lt;/h3&gt;

&lt;p&gt;First, Airflow DAGS need to be registered in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AIRFLOW_HOME&lt;/code&gt; directory. This is set as an environment variable. By convention, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;export AIRFLOW_HOME=~/airflow&lt;/code&gt;. Other things in this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dir&lt;/code&gt; are:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;airflow.cfg   airflow.db    dags          logs          unittests.cfg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;But, the DAGs that the developer works on are in a Project directory somewhere. To isolate my Project &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dir&lt;/code&gt; and where Airflow resources &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;live&lt;/code&gt; and get my DAGs discovered, I symlinked them from the Project dir to the Airflow dir.&lt;/p&gt;

&lt;p&gt;Next, to test a DAG, starting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;airflow scheduler&lt;/code&gt; and running the full DAG isn’t ideal. The feedback loop is too long. It could take 5 minutes for a DAG to run, and it will run all steps. Here are the steps that I learned to use to iterate on developing a DAG in Airflow:&lt;/p&gt;

&lt;h4 id=&quot;iterate-on-developing-a-dag-in-airflow&quot;&gt;Iterate on developing a DAG in Airflow&lt;/h4&gt;

&lt;p&gt;First, call it as a Python script to see if there’s any errors:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ python my_dag.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Second, try seeing if the DAG is registered:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ airflow list_dags
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Third, output the Tasks for a DAG. This lets you know what Tasks are configured for the DAG&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ airflow list_tasks my_dag
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, a Task can be tested in isolation. A date param is required.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ airflow test my_dag my_task 2019-04-07
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Depending on the situation, and if we’re ready to run the DAG, then the DAG can be run by starting these two processes:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# terminal 1 - DAGs are turned on an run here
airflow webserver

# terminal 2 - crawls the directory structure to discover and register DAGs
airflow scheduler
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When running a full DAG, I was looking in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$AIRFLOW_HOME/logs&lt;/code&gt; to check output. Logs are by DAG name, task, and date. It’s reachable, but it can be easier found in the Airflow webserver UI.&lt;/p&gt;

&lt;h4 id=&quot;python-debugging&quot;&gt;Python Debugging&lt;/h4&gt;

&lt;p&gt;I couldn’t get &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pdb&lt;/code&gt; to work when running the full DAG. This is because the Tasks are run as subprocesses, so they won’t hit the debugger, but when running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;airflow test&lt;/code&gt; though, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pdb&lt;/code&gt; works!&lt;/p&gt;

&lt;h4 id=&quot;pythonoperatorpython_callable&quot;&gt;PythonOperator.python_callable&lt;/h4&gt;

&lt;p&gt;Python functions can be tested outside of Airflow, and this is ideal. I unit tested a couple, and in a real application, I would do this extensively and outside of Airflow. This is also what Matt Davis recommends in the video and notes linked below.&lt;/p&gt;

&lt;h4 id=&quot;heres-how-to-hide-example-dags&quot;&gt;Here’s how to Hide example DAGs&lt;/h4&gt;

&lt;p&gt;This can be done in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$AIRFLOW_HOME/airflow.cfg&lt;/code&gt; by setting: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;load_examples = False&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;some-airflow-features&quot;&gt;Some Airflow Features&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PythonOperator&lt;/code&gt; - are used to call a Python function. They can be passed positional arguments with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;op_args&lt;/code&gt;, keyword arguments with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;op_kwargs&lt;/code&gt;, and Airflow context, such as the Task instance, and datetime info with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;provide_context=True&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BranchPythonOperator&lt;/code&gt; - are used for doing conditional branching in a DAG&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SubDagOperator&lt;/code&gt; - can be used for setting repeatable steps for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Tasks&lt;/code&gt; at different points in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DAG&lt;/code&gt;. &lt;a href=&quot;https://github.com/tensorflow/tfx&quot;&gt;Tensorflow Extended&lt;/a&gt; uses these for common steps in each &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task&lt;/code&gt; to first check the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cache&lt;/code&gt;, and then decide to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execute&lt;/code&gt; if needed.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://airflow.apache.org/concepts.html?highlight=xcom&quot;&gt;XCom&lt;/a&gt; - is for passing key/value primitive data from one Task to another. This can be:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the return value of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PythonOperator&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;any value using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xcom_push&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xcom_pull&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a note, this can be used for a Task to get a reference to the previouse Task instance that just run in it’s context: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;context[&apos;task_instance&apos;]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the example Github repo in the next section, I noticed that I only did &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xcom_push&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xcom_pull&lt;/code&gt; for Tasks that ran sequentially.&lt;/p&gt;

&lt;h2 id=&quot;github-repo-for-learning&quot;&gt;Github Repo for learning&lt;/h2&gt;

&lt;p&gt;I created this repo for learning Airflow and trying out the above features:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/aaronlelevier/apache_airflow_examples&quot;&gt;https://github.com/aaronlelevier/apache_airflow_examples&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;notes-from-youtube-video-a-practical-intro-to-airflow&quot;&gt;Notes from YouTube video “&lt;a href=&quot;https://youtu.be/cHATHSB_450&quot;&gt;A Practical Intro to Airflow&lt;/a&gt;”&lt;/h2&gt;

&lt;p&gt;These are my notes from Matt Davis’ talk at PyData SF 2016.&lt;/p&gt;

&lt;p&gt;This video was super helpful in filling in the gaps in conceptually understanding Airflow in combination with the Airflow documentation.&lt;/p&gt;

&lt;h3 id=&quot;airflow-concepts&quot;&gt;Airflow Concepts&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;metadata db&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;sqlite&lt;/p&gt;

&lt;p&gt;mysql&lt;/p&gt;

&lt;p&gt;postgres&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;webserver&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;flask&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;scheduler&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;nothing can run without this&lt;/p&gt;

&lt;p&gt;crawls the configured dir’s to find DAGs&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;celery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;tasks are sent from the scheduler to run on Celery workers&lt;/p&gt;

&lt;p&gt;would use &lt;em&gt;rabbitmq&lt;/em&gt; or &lt;em&gt;redis&lt;/em&gt; for Celery Queue&lt;/p&gt;

&lt;h3 id=&quot;airflow-objects&quot;&gt;Airflow objects&lt;/h3&gt;

&lt;p&gt;Tasks&lt;/p&gt;

&lt;p&gt;Executors (workers)&lt;/p&gt;

&lt;h3 id=&quot;code&quot;&gt;Code&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Useful DAG Arguments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start_date&lt;/code&gt; - will say when to start, if in the past, Airflow will backfill the tasks to that date based on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;schedule_interval&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;can put the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start_date&lt;/code&gt; for the future, if we don’t want it to run yet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;schedule_interval&lt;/code&gt; - cron config&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;max interval to run should be at fractions of hour, not per minute, because Airflow kicks off tasks every 30 seconds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;default_args&lt;/code&gt; - arguments supplied to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DAG&lt;/code&gt;, but get passed to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Operators&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;max_active_runs&lt;/code&gt; - can set globally or per Pipeline how may parallel pipelines to run at the same time&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;concurrency&lt;/code&gt; - max number of tasks run in a single Pipeline to run at a sinble time&lt;/p&gt;

&lt;p&gt;can retry tasks&lt;/p&gt;

&lt;p&gt;can put timeouts in Pipeline for when tasks start&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Useful Task Arguments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;retries&lt;/code&gt; -how many times to retry&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pool&lt;/code&gt; - a worker pool - can limit slots here&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;queue&lt;/code&gt; - named Celery Queues - and assign certain Workers to a Queue based upon the type of Worker if biefy, lightweight, etc..&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;execution_timeout&lt;/code&gt; - set a max time for a Task to run&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;trigger_rule&lt;/code&gt; - default is “all upstream tasks are successful. Can change to things like&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“all upstream tasks failed”&lt;/li&gt;
  &lt;li&gt;“all upstream tasks are done” - either success or fail&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;args for python&lt;/p&gt;

&lt;p&gt;env vars&lt;/p&gt;

&lt;p&gt;template vars&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;provide_context&lt;/code&gt; - supplies a dict of Task arguments, like “execution date”, from Airflow context&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;op_args&lt;/code&gt; - positional arguments for the Task&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;op_kwargs&lt;/code&gt; - kwarg arguments supplied to the Task&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Executors&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CeleryExecutor&lt;/code&gt; - for prod, puts exec request on a queue and sends it to a Celery Worker&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SequentialExecutor&lt;/code&gt; - good for debugging, will stop scheduling to run Tasks&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LocalExecutor&lt;/code&gt; - uses Python’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;multiprocess&lt;/code&gt; module to run in a diff process, so Scheduler can continue scheduling things&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;used in Prod for some companies - if don’t want a distributed worker queue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MesosExecutor&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local debugging&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pdb&lt;/code&gt;, use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SequentialExecutor&lt;/code&gt;, and run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;airflow test&lt;/code&gt; to hit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pdb&lt;/code&gt; debugger&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local Pipeline testing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start_date&lt;/code&gt; - should be some date in the past&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;schedule_interval=&apos;@once&apos;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;can delete a DAG using the UI, in order to re-run this Local Pipeline for testing&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Separate Business Logic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;develop code first, then integrate with Airflow&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploying new code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;to get new Python code, we have to restart the process, so new code is imported. to do this with Airflow, we can do&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;airflow scheduler --num_runs&lt;/code&gt; - this will stop the scheduler after &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;num_runs&lt;/code&gt; has occurred. You need a separate mechanism to restart the scheduler. Speaker uses a bash script&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CELERYD_MAX_TASKS_PER_CHILD&lt;/code&gt; - will configure Celery workers to restart after the “max tasks”&lt;/p&gt;

&lt;p&gt;speaker sets the above to 1 max, so each run, always gets new deployed code&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;So far, so good. By no means is this all Airflow can do, and is the above blog exhaustive. Thanks for reading!&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Tensorflow Dev Summit 2019</title>
        <link href="http://www.motivatedcoder.com/tensorflow-dev-summit-2019/"/>
        <updated>2019-03-09T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/tensorflow-dev-summit-2019</id>
        <content type="html">&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/Y2avwJV.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is my blog post summary of the &lt;a href=&quot;https://www.tensorflow.org/dev-summit&quot;&gt;Tensorflow Dev Summit 2019&lt;/a&gt;. I applied to go to the conference, but wasn’t accepted. Google sent me an email saying that I could still attend via the live stream, so I took off to watch the live stream and learn.&lt;/p&gt;

&lt;p&gt;I attended the last Pytorch Dev Con in Octoboer 2018. I’ve been pretty active in following machine learning and learning more about it and experimenting in my free time for about 1.5 years. My full time job is as a Python Developer working on internal tools.&lt;/p&gt;

&lt;p&gt;Okay, to the conference.&lt;/p&gt;

&lt;h2 id=&quot;the-conference&quot;&gt;The conference&lt;/h2&gt;

&lt;p&gt;The conference started out with an overview of the current Machine Learning landscape. Recent advances &lt;a href=&quot;https://github.com/google-research/bert&quot;&gt;BERT&lt;/a&gt; for NLP, and Open AI’s &lt;a href=&quot;https://blog.openai.com/better-language-models/&quot;&gt;GPT-2&lt;/a&gt; model for NLP were discussed.&lt;/p&gt;

&lt;p&gt;Models have been built like &lt;a href=&quot;https://medium.com/tensorflow/air-cognizer-predicting-air-quality-with-tensorflow-lite-942466b3d02e&quot;&gt;Aircognizer&lt;/a&gt; that predicts air quality based on computer vision. There’s a &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.bvpiee.com.airmirror&amp;amp;hl=en_US&quot;&gt;Google Play app&lt;/a&gt; for this.&lt;/p&gt;

&lt;p&gt;There’s break throughs all the time in open datasets such as the &lt;a href=&quot;https://storage.googleapis.com/openimages/web/index.html&quot;&gt;open images dataset&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’m going to include a library section below. So may libraries were released or now have new versions and features. The big release is Tensorflow 2.0.&lt;/p&gt;

&lt;h2 id=&quot;tensorflow-20&quot;&gt;Tensorflow 2.0&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.tensorflow.org/alpha&quot;&gt;Tensorflow 2.0&lt;/a&gt; was released.&lt;/p&gt;

&lt;p&gt;Keras API is now the recommended way to express TF models.&lt;/p&gt;

&lt;p&gt;Eager execution is the default.&lt;/p&gt;

&lt;p&gt;Functions with dynamic control flows can now be decorated with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@tf.function&lt;/code&gt; and be used in TF, just like &lt;a href=&quot;https://pytorch.org/docs/stable/jit.html&quot;&gt;PyTorch&lt;/a&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@torch.jit.script&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Saved models use the same format in development and prod, so the same exported model can be used in both places, and doesn’t have to be converted.&lt;/p&gt;

&lt;p&gt;Tensorboard can be used in Google Colab. Here is a &lt;a href=&quot;https://colab.research.google.com/github/google/dopamine/blob/master/dopamine/colab/tensorboard.ipynb#scrollTo=KS3rXKgsjiiY&quot;&gt;link&lt;/a&gt; to an example. I just ran the example and it uses &lt;a href=&quot;https://ngrok.com/&quot;&gt;ngrok&lt;/a&gt;. Way to ngrok, that’s awesome!&lt;/p&gt;

&lt;h3 id=&quot;orchestration&quot;&gt;Orchestration&lt;/h3&gt;

&lt;p&gt;TF has chose to standardize on Orchestration for what everyone is already using instead of providing their own solution. Supported Orchestration frameworks are &lt;a href=&quot;https://airflow.apache.org/&quot;&gt;Apache Airflow&lt;/a&gt; and &lt;a href=&quot;https://www.kubeflow.org/&quot;&gt;Kubeflow&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;online-courses&quot;&gt;Online courses&lt;/h3&gt;

&lt;p&gt;Both Udacity and Deeplearning.ai are going to have online courses&lt;/p&gt;

&lt;h3 id=&quot;hackathons&quot;&gt;Hackathons&lt;/h3&gt;

&lt;p&gt;There’s a &lt;a href=&quot;https://tensorflow.devpost.com/&quot;&gt;Devpost&lt;/a&gt; Hackathon with $150k in prizes. Wow!&lt;/p&gt;

&lt;h3 id=&quot;interface-programming&quot;&gt;Interface programming&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf.raw_ops&lt;/code&gt; exists for using the same ops that TF uses&lt;/p&gt;

&lt;p&gt;There’s a set of base components for checkpoints, layers, etc… and these base components can be extended to write your own components.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf_upgrade_v2&lt;/code&gt; to upgrade TF 1.x code to TF 2.0&lt;/p&gt;

&lt;h2 id=&quot;tensorflowjs&quot;&gt;Tensorflow.js&lt;/h2&gt;

&lt;p&gt;Now supports Electron apps&lt;/p&gt;

&lt;p&gt;There are off the shelf models for use&lt;/p&gt;

&lt;h2 id=&quot;tensorflow-swift&quot;&gt;Tensorflow Swift&lt;/h2&gt;

&lt;p&gt;There’s going to be a new &lt;a href=&quot;https://www.fast.ai/2019/03/06/fastai-swift/&quot;&gt;fast.ai tensorflow swift&lt;/a&gt; class. Jeremy Howard, I a little bit couldn’t believe it, if you are reading this! I’m excited to take a look at the class though. I love Jeremy Howards teaching style and the way he explains things. If I can get time and the class aligns with other goals, etc… I am pretty interested.&lt;/p&gt;

&lt;h2 id=&quot;tensorflow-special-interest-groups-sigs&quot;&gt;Tensorflow Special Interest Groups (SIGs)&lt;/h2&gt;

&lt;p&gt;There are special interest groups within Tensorflow for different parts of the community. There’s a SIG for Rust.&lt;/p&gt;

&lt;h2 id=&quot;tensorflow-extended-tfx&quot;&gt;Tensorflow Extended (TFX)&lt;/h2&gt;

&lt;p&gt;Tensorflow Extended is an end-to-end ML solution. As of now, all components have been open sourced by Google. This and TF 2.0 were the #1 things that blew me away.&lt;/p&gt;

&lt;p&gt;Here’s a couple of screen shots from the talks that overview what goes into a production ML workflow and the components involved.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/XzpYIF5.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/hnWCK6x.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I went through the &lt;a href=&quot;https://www.tensorflow.org/tfx&quot;&gt;Tensorflow Extended&lt;/a&gt; tutorial for example Chicago Taxi Cab model. Everything worked amazing. It uses Apache Airflow, all parts of TFX, gRPC to send requests to TF Serving.&lt;/p&gt;

&lt;h2 id=&quot;libraries&quot;&gt;Libraries&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.tensorflow.org/hub&quot;&gt;Tensorflow Hub&lt;/a&gt; - TensorFlow Hub is a library for reusable machine learning modules.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/tensorflow/tensorboard&quot;&gt;Tensorboard&lt;/a&gt; - TensorFlow’s Visualization Toolkit&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;has a ton new features, and is also now natively supported in Jupyter Notebook and Google Colab&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/tensorflow/model-analysis&quot;&gt;Tensorflow Model Analysis&lt;/a&gt; - Model analysis tools for TensorFlow&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/tensorflow/probability&quot;&gt;Tensorflow Probability&lt;/a&gt; - Probabilistic reasoning and statistical analysis in TensorFlow&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/tensorflow/agents&quot;&gt;Tensorflow Agents&lt;/a&gt; - TF-Agents is a library for Reinforcement Learning in TensorFlow&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/tensorflow/tensor2tensor&quot;&gt;Tensorflow Tensor2Tensor&lt;/a&gt; - Library of deep learning models and datasets designed to make deep learning more accessible and accelerate ML research.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.tensorflow.org/federated&quot;&gt;Tensorflow Federated&lt;/a&gt; - TensorFlow Federated: Machine Learning on Decentralized Data&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/tensorflow/privacy&quot;&gt;Tensorflow Privacy&lt;/a&gt; - Library for training machine learning models with privacy for training data&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.tensorflow.org/tfx&quot;&gt;Tensorflow Extended&lt;/a&gt; - TensorFlow Extended (TFX) is an end-to-end platform for deploying production ML pipelines&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.tensorflow.org/lite&quot;&gt;Tensorflow Lite&lt;/a&gt; - TensorFlow Lite is a lightweight solution for mobile and embedded devices&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.tensorflow.org/js&quot;&gt;Tensorflow.js&lt;/a&gt; - A WebGL accelerated, browser based JavaScript library for training and deploying ML models.&lt;/p&gt;

&lt;h3 id=&quot;talks-reference&quot;&gt;Talks Reference&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PLQY2H8rRoyvzoUYI26kHmKSJBedn3SQuB&quot;&gt;All talks from Tensorflow Dev Summit 2019&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I’m running out of time for the day. This isn’t everything, but it covers a lot. I hope you enjoyed readying and found some useful references. Thanks.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Personal recap of this week</title>
        <link href="http://www.motivatedcoder.com/personal-recap-of-this-week/"/>
        <updated>2019-03-03T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/personal-recap-of-this-week</id>
        <content type="html">&lt;p&gt;This is a personal blog of how this week went. &lt;strong&gt;Warning&lt;/strong&gt; this blog isn’t meant as boasting. The week went really good. I’m not sure why. I need to find out. If I could have more weeks like this, well then wow! I could only hope. I’m recording this week for myself because it’s been pretty special.&lt;/p&gt;

&lt;h2 id=&quot;details&quot;&gt;Details&lt;/h2&gt;

&lt;p&gt;Each section is called out in order of how it happened. No order of importance.&lt;/p&gt;

&lt;h2 id=&quot;work&quot;&gt;Work&lt;/h2&gt;

&lt;p&gt;On Thursday, I gave a presentation to the architects at my work. This was amazing and particulary humbling. At this point, I am a contractor. I work hard and stay focused on my goals at my workplace, and am focused on where I want this to go. For me to give a presentation to the architects, not to get too nervous, and to be able to answer most all their questions was particulary special. I appreciate this opportunity.&lt;/p&gt;

&lt;h3 id=&quot;python-coding&quot;&gt;Python coding&lt;/h3&gt;

&lt;p&gt;I wrote proxy logic for calling any method in a foreing class in &lt;a href=&quot;https://www.python.org/&quot;&gt;Python&lt;/a&gt; and being able to hook into that method and make calls before or after the method is called. This could be equated to a &lt;strong&gt;vistor decorator&lt;/strong&gt;. I am proud of this because I had no idea of how to do it, but I believed that it was possible, and it was. My particular use case was to properly bust the cache. But, doing logging, or any other use case, where a before or after &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boto2.client(&apos;ec2&apos;)&lt;/code&gt; for example out of one of the may remote client visitor calls, well this pattern can be used a lot, needless to say.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/aaronlelevier/5f46d02d09cc4e0e5d6f562fa8816ed6.js&quot;&gt;&lt;/script&gt;

&lt;h2 id=&quot;personal&quot;&gt;Personal&lt;/h2&gt;

&lt;p&gt;Read 1 chapter of &lt;a href=&quot;http://libertar.io/lab/wp-content/uploads/2017/03/Andrew-Koening-and-Barbara-E.-Moo-Accelerated-C-.pdf&quot;&gt;Accelerated C++&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Got my C++ environment with &lt;a href=&quot;https://pytorch.org/cppdocs/&quot;&gt;libtortch&lt;/a&gt; working and contributed to a &lt;a href=&quot;https://github.com/facebookresearch/maskrcnn-benchmark/pull/138&quot;&gt;torch.jit&lt;/a&gt; feature branch&lt;/p&gt;

&lt;p&gt;Most intense mountain bike ride yet… yes, I’m still on a Trek DS2&lt;/p&gt;

&lt;p&gt;First code review with a senior site reliablity engineer, SRE. It was great feedback. I need to fix up my PR now :)&lt;/p&gt;

&lt;p&gt;Passed a code challenge.&lt;/p&gt;

&lt;p&gt;I went to a &lt;a href=&quot;https://www.yelp.com/biz/high-country-barbershop-san-diego-2?utm_campaign=www_business_share_popup&amp;amp;utm_medium=copy_link&amp;amp;utm_source=(direct)&quot;&gt;barber shop&lt;/a&gt; and he didn’t trim my hair as I asked and I asked him multiple times to correct it until he got it right. I’m proud of this because I stuck up for myself to get the right haircut that I wanted.&lt;/p&gt;

&lt;h2 id=&quot;family&quot;&gt;Family&lt;/h2&gt;

&lt;p&gt;Went to mount Palomar and played in the snow with my family.&lt;/p&gt;

&lt;p&gt;My neighbors opened up to me about being able to buy their oldest son eye glasses for seeing in color because he’s color blind. They said God bless, because these glasses are expensive, and they don’t come from a lot. I look up to them for doing this for thier son.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;God bless. Thank you. This isn’t something that I talk about a lot. I am just so thankful for my current situation, myself and my family for being in such good health. I am so thankful for all that I have. It’s obviously something that you can’t take for granted. Thank you.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Convert a PyTorch model to C++ - using maskedrcnn-benchmark and torch.jit - Part 1</title>
        <link href="http://www.motivatedcoder.com/maskedrcnn-benchmark-and-torch-jit/"/>
        <updated>2019-02-16T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/maskedrcnn-benchmark-and-torch-jit</id>
        <content type="html">&lt;p&gt;The next step in my project for putting a machine learning model in production is to put an initial model in production! So…, I’m somewhere towards the first full iteration. Obviously, a production machine learning model will need to be accessed, a data pipeline, etc…, and I haven’t done that yet, but first let’s convert a &lt;a href=&quot;https://pytorch.org&quot;&gt;PyTorch&lt;/a&gt; model into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C++&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;goal&quot;&gt;Goal&lt;/h2&gt;

&lt;p&gt;Convert the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maskedrcnn-benchmark&lt;/code&gt; PyTorch Python model to a C++ model using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;torch.jit&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;story&quot;&gt;Story&lt;/h2&gt;

&lt;p&gt;I’m using the &lt;a href=&quot;https://github.com/facebookresearch/maskrcnn-benchmark&quot;&gt;maskedrcnn-benchmark&lt;/a&gt; Github library.&lt;/p&gt;

&lt;p&gt;There’s an &lt;a href=&quot;https://github.com/facebookresearch/maskrcnn-benchmark/pull/138&quot;&gt;open PR&lt;/a&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;torch.jit&lt;/code&gt; support.&lt;/p&gt;

&lt;p&gt;I pulled down the PR branch, and tried building to see if I can assist.&lt;/p&gt;

&lt;p&gt;I first synced up with the &lt;em&gt;master&lt;/em&gt; branch. (maybe I should have built and run the PR branch first, not sure….)&lt;/p&gt;

&lt;p&gt;Ok, now I’m trying to install the additional dependencies of the PR branch. So far, it looks like it requires OpenCV and Pytorch in C++ as dependencies.&lt;/p&gt;

&lt;p&gt;When I run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;demo/Mask_R-CNN_demo.ipynb&lt;/code&gt; because getting error:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;error: could not create &apos;maskrcnn_benchmark/lib/custom_ops.cpython-36m-x86_64-linux-gnu.so&apos;: No such file or directory
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So, I think I need to compile and correctly link &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;custom_ops.cpp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When I run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmake CMakeLists.txt&lt;/code&gt;, like below, here’s the output.&lt;/p&gt;

&lt;p&gt;command line:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;(venv) aaron@ubuntu-desktop:~/github/maskedrcnn-benchmark/maskrcnn_benchmark/csrc/custom_ops$ cmake CMakeLists.txt 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With error:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;CMake Error at CMakeLists.txt:11 (find_package):
  Could not find a package configuration file provided by &quot;Torch&quot; with any of
  the following names:

    TorchConfig.cmake
    torch-config.cmake

  Add the installation prefix of &quot;Torch&quot; to CMAKE_PREFIX_PATH or set
  &quot;Torch_DIR&quot; to a directory containing one of the above files.  If &quot;Torch&quot;
  provides a separate development package or SDK, be sure it has been
  installed.


-- Configuring incomplete, errors occurred!
See also &quot;/home/aaron/github/maskedrcnn-benchmark/maskrcnn_benchmark/csrc/custom_ops/CMakeFiles/CMakeOutput.log&quot;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Okay, I will try to install LibTorch C++ version&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd ~/Downloads
wget -bqc https://download.pytorch.org/libtorch/nightly/cu100/libtorch-shared-with-deps-latest.zip
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’m going to wait for this to download and then build. It’s a big downlaod, so did it in the background using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wget -bqc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part 1&lt;/strong&gt; done. To be continued.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Learning Erlang</title>
        <link href="http://www.motivatedcoder.com/learning-erlang/"/>
        <updated>2019-02-10T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/learning-erlang</id>
        <content type="html">&lt;p&gt;Let me tell you how &lt;strong&gt;Learing&lt;/strong&gt; is. By this, I mean coding. The blog that you are about to read is written towards people who have mildly thought about coding. It’s not that hard, and you can get yourself into it fairly easy and it pays well. A lot of people might stop because of the learning curve, but you really just have to progress at you own rate. If you’re getting stuck, and this is an actual quote from &lt;a href=&quot;https://en.wikipedia.org/wiki/Joe_Armstrong_(programmer)&quot;&gt;Joe Armstrong&lt;/a&gt;,&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If a process fails, what should it do? Well, it should try to do something simpler.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I love that quote. Learning is very much the same way. I’m taking some of my time to write this, but hopefully it benefits all the readers more than my small amount of time. If you enjoy the article, please let me know.&lt;/p&gt;

&lt;h2 id=&quot;the-learning-process&quot;&gt;The Learning Process&lt;/h2&gt;

&lt;p&gt;This is how I learn. Some learn by listening, reading or doing, but all actually progress towards doing. I learn by doing all 3 at the same time.&lt;/p&gt;

&lt;p&gt;I am learning Erlang. I know nothing about Erlang. I’m terrible at it. I am on page 67 of &lt;a href=&quot;https://en.wikipedia.org/wiki/Joe_Armstrong_(programmer)&quot;&gt;Joe Simpson’s&lt;/a&gt; great book &lt;a href=&quot;https://www.oreilly.com/library/view/programming-erlang-2nd/9781941222454/&quot;&gt;“Programming Erlang - 2nd Edition”&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Okay, well let’s start at the max code that I can think of. Let’s code in Intellij and write a whole program. Okay, here’s how far I got. I was going to write a program about me and some other objects on a Sunday, and have them interact. I started a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aaron.erl&lt;/code&gt; module, that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sunday.erl&lt;/code&gt; module was supposed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spawn&lt;/code&gt;. Here’s the first code I wrote:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/aaronlelevier/c25bf1a849739d87beeb78985d8a8bdc.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;Then I progressed to the colsole, I wasn’t ready for a file. Doing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c(module_name).&lt;/code&gt; each time to compile changes for Erlang files is tough.&lt;/p&gt;

&lt;p&gt;So, I went to the console. Here’s some code I next wrote:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/aaronlelevier/a408795caa255448ac415a4820743564.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;Then I next tried codewars. They didn’t have a lot of Erlang. I tried the Erlang 7kyu &lt;a href=&quot;https://www.codewars.com/kata/7x7-skyscrapers/train/erlang&quot;&gt;7x7 Skyscrapers Problem&lt;/a&gt;, I could probably solve this in Python. Erlang, I didn’t stand a chance!&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;That’s what &lt;strong&gt;learning&lt;/strong&gt; is.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;It’s try, succeed or fail, try again.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you enjoy something, then sometimes losing is the next best thing to winning. So, if you win or lose, you enjoy it and keep going, and eventually find out how to win because winning is better than losing!&lt;/p&gt;

&lt;p&gt;If you start to not enjoy it. Then &lt;em&gt;pivot&lt;/em&gt; your learning towards a direction that you like more, and &lt;strong&gt;keep learning&lt;/strong&gt;.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Training the maskrcnn-benchmark on my own hardware</title>
        <link href="http://www.motivatedcoder.com/training-the-maskrcnn-benchmark-on-my-own-hardware/"/>
        <updated>2019-02-08T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/training-the-maskrcnn-benchmark-on-my-own-hardware</id>
        <content type="html">&lt;p&gt;My goal is to train a Machine Learning model on my own hardware and my own labeled dataset. In order to do this, I’ve been ramping up on the tools and software necessary to do this. This blog post is about &lt;strong&gt;Training the &lt;a href=&quot;https://github.com/facebookresearch/maskrcnn-benchmark&quot;&gt;maskrcnn-benchmark&lt;/a&gt; on my own hardware&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;initial-detour&quot;&gt;Initial detour&lt;/h2&gt;

&lt;p&gt;I’ll start where I left off from my last &lt;a href=&quot;https://aaronlelevier.github.io/training-an-ml-model-on-the-coco-dataset/&quot;&gt;post&lt;/a&gt;, which was titled &lt;em&gt;“Training an ML model on the COCO Dataset”&lt;/em&gt;, but I hadn’t fully trained a model, I had run a model over a couple of mini-batches of the COCO dataset.&lt;/p&gt;

&lt;p&gt;After my last post, I decided to upgrade my Linux kernal headers unknowningly. Well, come to find out Ubuntu 18.04 with linux-headers &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4.15.0-45-generic&lt;/code&gt; doesn’t currently work with Cuda 10.0 drivers. I tried fixing it a variety of ways, and wasn’t sure why it was working, but in the end, I downgraded back to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4.15.0-29-generic&lt;/code&gt; and it is now working.&lt;/p&gt;

&lt;p&gt;If you run into a similar issue and want to downgrade, how I did it was, check the linux-headers here:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ls /lib/modules/
4.15.0-29-generic  4.15.0-45-generic
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grub&lt;/code&gt;, you can set the preference for choosing what linux-headers you want to use at start up like so:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# /etc/default/grub

#GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=-1
GRUB_DISTRIBUTOR=`lsb_release -i -s 2&amp;gt; /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT=&quot;quiet splash&quot;
GRUB_CMDLINE_LINUX=&quot;&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo update-grub&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reboot&lt;/code&gt; for the config to take effect.&lt;/p&gt;

&lt;h2 id=&quot;lets-train-the-model&quot;&gt;Let’s train the model&lt;/h2&gt;

&lt;p&gt;Now that Cuda drivers are working, I trained the &lt;a href=&quot;https://github.com/facebookresearch/maskrcnn-benchmark&quot;&gt;model&lt;/a&gt; using this command&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nohup python tools/train_net.py --config-file &quot;configs/e2e_mask_rcnn_R_50_FPN_1x.yaml&quot; SOLVER.IMS_PER_BATCH 2 SOLVER.BASE_LR 0.0025 SOLVER.MAX_ITER 720000 SOLVER.STEPS &quot;(480000, 640000)&quot; TEST.IMS_PER_BATCH 1 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nohup&lt;/code&gt; will run the process in the background.&lt;/p&gt;

&lt;p&gt;This is a large model. My hardware is a Nvidia 1080Ti with 11GB of GPU memory. The model is usually run on a cluster of 8 GPUs with a mini-batch of 16. On a single GPU, they recommend a mini-batch of 2. This takes up 6-10GB of memory depending on the image size.&lt;/p&gt;

&lt;p&gt;The run time is also long. At 720,000 iterations above on the 1080Ti, it will run for 3.5 days.&lt;/p&gt;

&lt;p&gt;After 2 days, I got excited and wanted to see how the model is doing. Below is my trained model, and the original model.&lt;/p&gt;

&lt;h3 id=&quot;my-model&quot;&gt;My model&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/ldcvI4o.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;original-model&quot;&gt;Original model&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/fZUh70j.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;okay-continue-training&quot;&gt;Okay, continue training&lt;/h2&gt;

&lt;p&gt;I started the model again. It will load the previous checkpoint, and continue training.&lt;/p&gt;

&lt;p&gt;I first change the iterations to 300,000 thinking that I should lower to about how many I had left, but the model must know the total expected iterations, because when I did this, the model thought that it was done, and ran the validation set.&lt;/p&gt;

&lt;p&gt;I changed the command back to the original 720,000 iterations, and the model loaded it’s last checkpoint, started training again, and calculated 1.5 days left.&lt;/p&gt;

&lt;h2 id=&quot;the-nvidia-1080ti-gpu&quot;&gt;The Nvidia 1080Ti GPU&lt;/h2&gt;

&lt;p&gt;So far, the GPU has been running like a champ. I got it used off eBay, so you never know, but so far so good. It’s been at 72c degrees max. The process hasn’t failed, and ran continuously for the first 2days.&lt;/p&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s next&lt;/h2&gt;

&lt;p&gt;I’m going to let the GPU finish training, run validations for the original vs. my trained model and compare. This comparison will be for spot checking individual images, but also with the validation set. The model returns these statistics for overall model performance. The below are after two days of training, so my plan is to evaluate after the full 3.5 days of training and also the original model to see if I can produce the same results.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;OrderedDict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;bbox&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;OrderedDict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;AP&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.2995932418350566&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;AP50&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5048334612699799&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;AP75&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.3199970069827478&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;APs&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.17024760135017813&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;APm&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.33163478543717106&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;APl&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.38858065511848544&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)])),&lt;/span&gt;
             &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;segm&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;OrderedDict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;AP&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.28114866256991533&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;AP50&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.47389863964406576&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;AP75&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.2971631326535043&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;APs&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.12308321652841664&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;APm&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.30504965888965696&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                           &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;APl&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.41763089921672736&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]))])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;february-10-2019&quot;&gt;February 10, 2019&lt;/h2&gt;

&lt;p&gt;The model finished training after 3.5 days. Final output is prety close to the original.&lt;/p&gt;

&lt;h3 id=&quot;model_finalpth&quot;&gt;model_final.pth&lt;/h3&gt;

&lt;p&gt;This is the final output final that gets loaded by &lt;a href=&quot;https://pytorch.org/tutorials/beginner/saving_loading_models.html&quot;&gt;PyTorch&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;model_final.pth&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TheModelClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load_state_dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/4gQq2qy.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;final-scores&quot;&gt;Final scores&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;OrderedDict([(&apos;bbox&apos;,
              OrderedDict([(&apos;AP&apos;, 0.3787438742878195),
                           (&apos;AP50&apos;, 0.5955128018290543),
                           (&apos;AP75&apos;, 0.41442391560475855),
                           (&apos;APs&apos;, 0.21670904937263522),
                           (&apos;APm&apos;, 0.41267339913138185),
                           (&apos;APl&apos;, 0.49431726896178174)])),
             (&apos;segm&apos;,
              OrderedDict([(&apos;AP&apos;, 0.34392779458751377),
                           (&apos;AP50&apos;, 0.5608730402994763),
                           (&apos;AP75&apos;, 0.3648390120652486),
                           (&apos;APs&apos;, 0.15867316023179875),
                           (&apos;APm&apos;, 0.36995797379803463),
                           (&apos;APl&apos;, 0.5052136454262031)]))])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;next&quot;&gt;Next&lt;/h2&gt;

&lt;p&gt;I’m going to collect data and train the model on my labeled data.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Converting Labelme annotations to COCO dataset annotations</title>
        <link href="http://www.motivatedcoder.com/converting-labelme-annotations-to-coco-dataset-annotations/"/>
        <updated>2019-01-26T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/converting-labelme-annotations-to-coco-dataset-annotations</id>
        <content type="html">&lt;p&gt;This is a short blog about how I converted Labelme annotations to COCO dataset annotations.&lt;/p&gt;

&lt;h2 id=&quot;mlearning&quot;&gt;mlearning&lt;/h2&gt;

&lt;p&gt;I created the repo &lt;a href=&quot;https://github.com/aaronlelevier/mlearning&quot;&gt;mlearning&lt;/a&gt; for storing Machine Learning utilities, helper code, etc…&lt;/p&gt;

&lt;p&gt;The first main addition to this repo is the converter that I wrote. I takes &lt;a href=&quot;https://github.com/wkentaro/labelme&quot;&gt;labelme&lt;/a&gt; annotated images, and converts them to the COCO dataset 2014 annotations format.&lt;/p&gt;

&lt;h2 id=&quot;why&quot;&gt;Why?&lt;/h2&gt;

&lt;p&gt;I’m training a model on the COCO dataset, so I need a way to generate my own labeled data that can be used by this model. I tried out a few data labeling softwares, like &lt;a href=&quot;https://rectlabel.com/&quot;&gt;RectLabel&lt;/a&gt; and &lt;a href=&quot;https://labelbox.com/&quot;&gt;LabelBox&lt;/a&gt;, but they were freemium’s and didn’t give me the output, or weren’t that great to use. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;labelme&lt;/code&gt; is open source. I plan to contribute back my COCO dataset converter once I use it more, and it becomes more stable.&lt;/p&gt;

&lt;p&gt;Let’s see the converter in action.&lt;/p&gt;

&lt;h2 id=&quot;example-output&quot;&gt;Example Output&lt;/h2&gt;

&lt;p&gt;Here’s example output from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mlearning&lt;/code&gt; Github repo.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matplotlib&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inline&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;matplotlib&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pyplot&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;matplotlib.pylab&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pylab&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mlearning&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;util&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mlearning.coco&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Annotation&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mlearning.plotting&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plot_bboxes_and_masks&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;pylab&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rcParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;figure.figsize&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# must set file paths for one&apos;s own data!!!
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ann&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Annotation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expanduser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;~&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;Desktop/license_plate_detection&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# this is the function that displays a random example
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plot_bboxes_and_masks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ann&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/g6l2A3u.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;future-plans&quot;&gt;Future plans&lt;/h2&gt;

&lt;p&gt;I plan to label more images and then train them on the model. I am still doing a proof of concept that I can train on my own hardware, and that the &lt;em&gt;labelme-to-COCO dataset&lt;/em&gt; converter that I wrote works.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Training an ML model on the COCO Dataset</title>
        <link href="http://www.motivatedcoder.com/training-an-ml-model-on-the-coco-dataset/"/>
        <updated>2019-01-21T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/training-an-ml-model-on-the-coco-dataset</id>
        <content type="html">&lt;p&gt;My current goal is to train an ML model on the COCO Dataset. Then be able to generate my own labeled training data to train on. So far, I have been using the &lt;a href=&quot;https://github.com/facebookresearch/maskrcnn-benchmark&quot;&gt;maskrcnn-benchmark&lt;/a&gt; model by Facebook and training on COCO Dataset 2014.&lt;/p&gt;

&lt;p&gt;Here my &lt;a href=&quot;https://github.com/aaronlelevier/maskrcnn-benchmark/blob/plot-images/demo/Plot%20COCO%20Dataset%20ground%20truth%20images.ipynb&quot;&gt;Jupyter Notebook&lt;/a&gt; to go with this blog.&lt;/p&gt;

&lt;p&gt;Okay here’s an account of what steps I took.&lt;/p&gt;

&lt;h2 id=&quot;getting-the-data&quot;&gt;Getting the data&lt;/h2&gt;

&lt;p&gt;The COCO dataset can be download &lt;a href=&quot;http://cocodataset.org/#download&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am only training on the 2014 dataset.&lt;/p&gt;

&lt;p&gt;I’m working with this project:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/facebookresearch/maskrcnn-benchmark&quot;&gt;https://github.com/facebookresearch/maskrcnn-benchmark#perform-training-on-coco-dataset&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And, it must be linked to the correct directories in order to use it with the Github project:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/facebookresearch/maskrcnn-benchmark#perform-training-on-coco-dataset&quot;&gt;https://github.com/facebookresearch/maskrcnn-benchmark#perform-training-on-coco-dataset&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;training&quot;&gt;Training&lt;/h2&gt;

&lt;p&gt;Here are some training commands. These worked.  Funny enough, the first command is for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;720,000&lt;/code&gt; iterations and it reported that it was going to take 3+ days to complete on my GTX 1080Ti. Also, I could only load 2 images at a time and it took up 10 out of 11GB of memory. This is a big model!&lt;/p&gt;

&lt;p&gt;1-16-2019&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python tools/train_net.py --config-file &quot;configs/e2e_mask_rcnn_R_50_FPN_1x.yaml&quot; SOLVER.IMS_PER_BATCH 2 SOLVER.BASE_LR 0.0025 SOLVER.MAX_ITER 720000 SOLVER.STEPS &quot;(480000, 640000)&quot; TEST.IMS_PER_BATCH 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;1-17-2019&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python tools/train_net.py --config-file &quot;configs/e2e_mask_rcnn_R_101_FPN_1x.yaml&quot; SOLVER.IMS_PER_BATCH 2 SOLVER.BASE_LR 0.0025 SOLVER.MAX_ITER 10 SOLVER.STEPS &quot;(480000, 640000)&quot; TEST.IMS_PER_BATCH 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;some-things-that-maskrcnn-does-really-well&quot;&gt;Some Things that maskrcnn does really well&lt;/h2&gt;

&lt;p&gt;everything’s a hyper param&lt;/p&gt;

&lt;p&gt;logging - for lots of feedback&lt;/p&gt;

&lt;p&gt;single &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tqdm&lt;/code&gt; output for training&lt;/p&gt;

&lt;h2 id=&quot;coco-dataset-format-notes&quot;&gt;COCO Dataset format notes&lt;/h2&gt;

&lt;p&gt;Things that I learned about the COCO dataset that will be important in the future for training my own datasets with this format are:&lt;/p&gt;

&lt;h3 id=&quot;images&quot;&gt;Images&lt;/h3&gt;

&lt;p&gt;Image annotations have this format:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{&apos;license&apos;: 3,
&apos;file_name&apos;: &apos;COCO_val2014_000000391895.jpg&apos;,
&apos;coco_url&apos;: &apos;http://images.cocodataset.org/val2014/COCO_val2014_000000391895.jpg&apos;,
&apos;height&apos;: 360,
&apos;width&apos;: 640,
&apos;date_captured&apos;: &apos;2013-11-14 11:18:45&apos;,
&apos;flickr_url&apos;: &apos;http://farm9.staticflickr.com/8186/8119368305_4e622c8349_z.jpg&apos;,
&apos;id&apos;: 391895}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;annotations&quot;&gt;Annotations&lt;/h3&gt;

&lt;p&gt;Annotations have this format:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{&apos;segmentation&apos;: [[239.97,
260.24,
222.04,
270.49,
199.84,
253.41,
213.5,
227.79,
259.62,
200.46,
274.13,
202.17,
277.55,
210.71,
249.37,
253.41,
237.41,
264.51,
242.54,
261.95,
228.87,
271.34]],
&apos;area&apos;: 2765.1486500000005,
&apos;iscrowd&apos;: 0,
&apos;image_id&apos;: 558840,
&apos;bbox&apos;: [199.84, 200.46, 77.71, 70.88],
&apos;category_id&apos;: 58,
&apos;id&apos;: 156}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;segmentation&lt;/strong&gt; explained:&lt;/p&gt;

&lt;p&gt;I was confused how the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;segmentation&lt;/code&gt; above was converted to a mask. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;segmentation&lt;/code&gt; is a list of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x,y&lt;/code&gt; points. In this format: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[x1, y1, x2, y2, etc...]&lt;/code&gt; In this code block, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;segmentation&lt;/code&gt; list of points is reshaped to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[(x1,y1), (x2, y2), ...]&lt;/code&gt; and is then usable by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;matplotlib&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;for seg in ann[&apos;segmentation&apos;]:
    poly = np.array(seg).reshape((int(len(seg)/2), 2))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;poly&lt;/code&gt; becomes an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;np.ndarray&lt;/code&gt; of shape &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(N, 2)&lt;/code&gt; where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;N&lt;/code&gt; is the number of segmentation points.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bbox&lt;/strong&gt; explained:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bbox&lt;/code&gt; is of format &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[x1, y1, x2, y2]&lt;/code&gt;. The bounding box points start at the top left of the image as point &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(0,0)&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x1,y1&lt;/code&gt; offset is from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(0,0)&lt;/code&gt; starting point, where the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt; size goes down, since it’s starting from the top left. Then the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x2,y2&lt;/code&gt; values are offsets from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x1,y1&lt;/code&gt; points.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I’ve now learned 2 datasets. Pascal and COCO. Now I know a little more why most projects doing image tasks support both.&lt;/p&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s Next&lt;/h2&gt;

&lt;p&gt;Next I want to label my own data and train on it. The last &lt;a href=&quot;https://render.githubusercontent.com/view/ipynb?commit=9d799b96f24ffd7d5f964165dcbf2d0037fd5dba&amp;amp;enc_url=68747470733a2f2f7261772e67697468756275736572636f6e74656e742e636f6d2f6161726f6e6c656c65766965722f6d61736b72636e6e2d62656e63686d61726b2f396437393962393666323466666437643566393634313635646362663264303033376664356462612f64656d6f2f506c6f74253230434f434f2532304461746173657425323067726f756e642532307472757468253230696d616765732e6970796e62&amp;amp;nwo=aaronlelevier%2Fmaskrcnn-benchmark&amp;amp;path=demo%2FPlot+COCO+Dataset+ground+truth+images.ipynb&amp;amp;repository_id=165327326&amp;amp;repository_type=Repository#Plot-my-own-labeled-data&quot;&gt;section&lt;/a&gt; of the notebook is my attempt at this using &lt;strong&gt;RectLabel&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I reviewed 3 different applications for labeling data:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Labelbox&lt;/li&gt;
  &lt;li&gt;RectLabel&lt;/li&gt;
  &lt;li&gt;Labelme&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My criteria for evaluating is that it should be free and I should be able to run the program locally and label my own data as I please. User friendly is better obviously.&lt;/p&gt;

&lt;p&gt;If I can’t find something, then maybe I have to create a simple app for labeling data. Definitely doable, but it’d be a detour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Labelbox&lt;/strong&gt; seems like it used to be open source, but they turned it into a SaaS, and I couldn’t get it to run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RectLabel&lt;/strong&gt; is $5 which isn’t bad, but it didn’t generate the segmentation data in the format that I need.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/wkentaro/labelme&quot;&gt;Labelme&lt;/a&gt; seems exactly what I am looking for. Open source. There isn’t a script for exporting to COCO Dataset 2014 format, so maybe this is an opportunity to contribute as well :)&lt;/p&gt;

&lt;p&gt;So labeling my own data and training on it is the next step. Okay, until next time.&lt;/p&gt;

&lt;h2 id=&quot;random-extra&quot;&gt;Random… Extra&lt;/h2&gt;

&lt;p&gt;Some random notes about things learned when doing this.&lt;/p&gt;

&lt;h3 id=&quot;commands&quot;&gt;commands&lt;/h3&gt;

&lt;p&gt;count files in a dir - in order to check that the file count matches what was expected, or when the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zip&lt;/code&gt; file didn’t fully download, or to check the image file count vs. expected.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ls -1 | wc -l
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wget&lt;/code&gt; in background with no timeout, so I can start the job from my laptop, but process runs as a daemon on the DL machine&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wget -bqc --timeout=0 url
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;fastjar&quot;&gt;fastjar&lt;/h3&gt;

&lt;p&gt;If a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zip&lt;/code&gt; file didn’t fully download, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fastjar&lt;/code&gt; can be used to unzip it.&lt;/p&gt;

&lt;p&gt;Trying to unzip the file will give you:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;unzip error “End-of-central-directory signature not found”
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fastjar&lt;/code&gt; if the whole zip file didn’t download:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get install fastjar
jar xvf something.zip
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://askubuntu.com/questions/54904/unzip-error-end-of-central-directory-signature-not-found&quot;&gt;StackExchange reference&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;nvidia-smi&quot;&gt;nvidia-smi&lt;/h3&gt;

&lt;p&gt;equivalent to “tail nvidia-smi”&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# keeps passed traces
nvidia-smi -l 1

# doesn&apos;t keep past traces
watch -n0.1 nvidia-smi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Deep Learning Machine Build</title>
        <link href="http://www.motivatedcoder.com/deep-learning-machine-build/"/>
        <updated>2019-01-12T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/deep-learning-machine-build</id>
        <content type="html">&lt;p&gt;This blog is about my experience building my first Deep Learning machine. There are plenty of great blogs and videos on how to do this. If you’re interested in how to do this only, skip to the &lt;strong&gt;References&lt;/strong&gt; section, and I put links to all of the blogs / videos that I used.&lt;/p&gt;

&lt;h1 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;/h1&gt;

&lt;p&gt;This blog is dedicated to my wife. Without her support, none of this would be possible. My wife told me 6 months ago that I had put a lot of time into machine learning, and I should stick with it. She wouldn’t let change my direction!&lt;/p&gt;

&lt;h1 id=&quot;preface&quot;&gt;Preface&lt;/h1&gt;

&lt;p&gt;One thing that is ringing true for me lately and with this whole project is:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;People can do anything. You might not know how to do it yet but just go for it!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nobody helped me do this as in writing any actual code or physically assembling things. One person gave me advice on Wifi drivers, thanks Evangelos!, but other than that I figured it out :)&lt;/p&gt;

&lt;h1 id=&quot;my-story&quot;&gt;My Story&lt;/h1&gt;

&lt;p&gt;Okay, so the story…&lt;/p&gt;

&lt;p&gt;I got into &lt;a href=&quot;https://pytorch.org/&quot;&gt;PyTorch&lt;/a&gt;. I had tried Keras and Tensorflow as well, but for some reason PyTorch stuck and I really liked the API. It has pretty much the same API as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;numpy&lt;/code&gt; but with GPU  support and for machine learning.&lt;/p&gt;

&lt;p&gt;I went to the &lt;a href=&quot;https://aaronlelevier.github.io/PyTorch-Developer-Conference-2018-part-1/&quot;&gt;Pytorch Developer Conference&lt;/a&gt; October 2, 2018, and had just been excited since.&lt;/p&gt;

&lt;p&gt;I had been using &lt;a href=&quot;https://www.paperspace.com/&quot;&gt;Paperspace&lt;/a&gt; for running models on a GPU that I rented hourly at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$0.50&lt;/code&gt; an hour plus &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$8&lt;/code&gt; per month for persistent storage. This worked okay, but my monthly costs were going up as I was getting more into PyTorch, so it started to feel like it was the right time to invest in my own machine. I started at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$15&lt;/code&gt; a month, and the last month was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$34&lt;/code&gt;. The astute will notice this is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$360&lt;/code&gt; a year. So, if I can make a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$1800&lt;/code&gt; DL machine build last 5 years, then I break even at my current usage, with only power as an additional cost, plus I can use the machine any amount on top of that.&lt;/p&gt;

&lt;p&gt;I decided to build the machine myself instead of paying someone to assemble it. I followed a great &lt;a href=&quot;(https://youtu.be/OZaFqY8UF6I)&quot;&gt;YouTube&lt;/a&gt; video. It’s also in the References section.&lt;/p&gt;

&lt;p&gt;Installing the USB Wifi Adapter was probably the hardest part. I did a separate &lt;a href=&quot;https://aaronlelevier.github.io/install-usb-wifi-dongle-on-ubuntu-18.04/&quot;&gt;blog&lt;/a&gt; on it.&lt;/p&gt;

&lt;p&gt;Installing the CUDA drivers was pretty easy, following Nvidia’s very thorough documentation. There’s a link in the &lt;strong&gt;References&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;some-things-i-learned&quot;&gt;Some things I learned&lt;/h2&gt;

&lt;p&gt;Assempling the DL machine scared me. In the YouTube video they say to be careful at every point or you coulld bend a pin or break something. I was super careful, and didn’t break anything, it just took longer.&lt;/p&gt;

&lt;p&gt;Coming from a software background and doing unit testing, it scared me that the feedback loop for assembling the DL machine and to know if it was successful was super long. Once assembled though, small teaks and confirming that things were powered on worked. Things that I had to test and tweak were:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the hdmi input - if you have a GPU the hdmi has to be plugged in to the GPU hdmi port, not the motherboard hdmi port&lt;/li&gt;
  &lt;li&gt;what usb ports are available. The command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lsusb&lt;/code&gt; will tell you this&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The whole build was a learning experience. I didn’t know anything about setting up a Wifi adapter. I learned a lot and did a separate blog about it &lt;a href=&quot;https://aaronlelevier.github.io/install-usb-wifi-dongle-on-ubuntu-18.04/&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I learned to follow the directions that come with the Motherboard. I was Googling for what goes where and a diagram, but there was instructions in the box that I didn’t look at until I thought to check the box!!&lt;/p&gt;

&lt;p&gt;Same for the power supply, there’s instructions in the box.&lt;/p&gt;

&lt;p&gt;RAM is CPU specific. There’s a list of supported RAM sticks that work with the specific CPU. I first ordered RAM, and it said Intel on it, but my CPU is AMD. I didn’t install it, did some research, and had to return it and get the right RAM. Lucky for me, Newegg has a great return policy.&lt;/p&gt;

&lt;p&gt;“You will need a monitor, keyboard, and maybe mouse”. I first thought, no I just plug my Macbook into the DL machine. This was maybe me not thinking it through. It might be possible, but for the simplist install, use these things.&lt;/p&gt;

&lt;p&gt;An ethernet cable is needed to set up the USB Wifi Adapter. Most motherboards don’t come with Wifi. I had to purchase this separately later once I realized that I needed it.&lt;/p&gt;

&lt;h2 id=&quot;parts-list&quot;&gt;Parts list&lt;/h2&gt;

&lt;p&gt;Here is my parts list for the build:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Case - &lt;a href=&quot;https://www.amazon.com/gp/product/B07D4MN8R7/ref=ppx_yo_dt_b_asin_title_o03__o00_s00?ie=UTF8&amp;amp;psc=1&quot;&gt;Anidees AI-Crystal-AR Mid Tower&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;CPU -  &lt;a href=&quot;https://www.amazon.com/gp/product/B07B428M7F/ref=ppx_yo_dt_b_asin_title_o04__o00_s00?ie=UTF8&amp;amp;psc=1&quot;&gt;AMD Ryzen 7 2700X&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;GPU - &lt;a href=&quot;https://www.ebay.com/itm/GIGABYTE-GeForce-GTX-1080-Ti-Gaming-OC-11GB-GDDR5X-Video-Card-White-/283301035112?_trksid=p2047675.l2557&amp;amp;ssPageName=STRK%3AMEBIDX%3AIT&amp;amp;nma=true&amp;amp;si=1%252FBZEwhqjFA%252FZehikkOSe58oRkY%253D&amp;amp;orig_cvip=true&amp;amp;nordt=true&amp;amp;rt=nc&quot;&gt;GIGABYTE GeForce GTX 1080Ti&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;RAM - &lt;a href=&quot;https://www.amazon.com/gp/product/B06WP4L3D7/ref=ppx_yo_dt_b_asin_title_o01__o00_s00?ie=UTF8&amp;amp;psc=1&quot;&gt;G.SKILL TridentZ RGB Series 16GB (2 x 8GB)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;SSD - &lt;a href=&quot;https://www.newegg.com/Product/Product.aspx?Item=N82E16820147690&quot;&gt;SAMSUNG 970 EVO M.2 2280 500GB NVME SSD&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Motherboard - &lt;a href=&quot;https://www.newegg.com/Product/Product.aspx?Item=N82E16813119100&quot;&gt;ASUS Prime X470-Pro&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Power supply - &lt;a href=&quot;https://www.newegg.com/Product/Product.aspx?Item=9SIA6ZP76J4883&quot;&gt;EVGA SuperNOVA 1000W&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;USB Wifi Adapter - &lt;a href=&quot;https://www.amazon.com/gp/product/B078MJB351/ref=ppx_yo_dt_b_asin_title_o00__o00_s00?ie=UTF8&amp;amp;psc=1&quot;&gt;COMFAST Wireless WiFi Adapter&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;USB thumb drive - &lt;a href=&quot;https://www.amazon.com/gp/product/B007JR5304/ref=ppx_yo_dt_b_asin_title_o01__o00_s01?ie=UTF8&amp;amp;psc=1&quot;&gt;SanDisk 64GB USB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Miscellaneous&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;tools to assemple - &lt;a href=&quot;https://www.amazon.com/gp/product/B0189YWOIO/ref=ppx_yo_dt_b_asin_title_o02__o00_s00?ie=UTF8&amp;amp;psc=1&quot;&gt;iFixit Mako Driver Kit - 64 pieces&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;27 inch LG monitor&lt;/li&gt;
  &lt;li&gt;keyboard&lt;/li&gt;
  &lt;li&gt;mouse&lt;/li&gt;
  &lt;li&gt;ethernet cable&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;build-decisions&quot;&gt;Build Decisions&lt;/h2&gt;

&lt;p&gt;There were a lot of decisions to make along. Here’s a list of some of them and why I chose what I did.&lt;/p&gt;

&lt;h3 id=&quot;gpu&quot;&gt;GPU&lt;/h3&gt;

&lt;p&gt;I chose to go with a used Nvidia GTX 1080Ti because these go for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$500&lt;/code&gt;  on eBay, compared to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$800&lt;/code&gt; for a RTX 2080 or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$1k+&lt;/code&gt; for an RTX 2080Ti. I was using a Nvidia p4000 with 8GB memory on &lt;a href=&quot;https://www.paperspace.com/pricing&quot;&gt;Paperspace&lt;/a&gt;, so when comparing specs, the GTX 1080Ti performs better than the p4000 and has 11GB memory, so this would be an upgrade.&lt;/p&gt;

&lt;h3 id=&quot;cpu&quot;&gt;CPU&lt;/h3&gt;

&lt;p&gt;I was comparing the Intel 8700k or the Ryzen 2700x. Ryzen has more cores and more cache memory. Both are 3.7 GHz clockspeed. &lt;a href=&quot;https://www.google.com/search?q=intel+8700k+vs+amd+2700x&amp;amp;pcmp=f&quot;&gt;Here&lt;/a&gt; is a comparison.&lt;/p&gt;

&lt;h3 id=&quot;ram&quot;&gt;RAM&lt;/h3&gt;

&lt;p&gt;Paperspace did give me 30GB RAM. I went with 16GB RAM. Not sure if I need up to 30GB. I never hit this limit on Paperspace. The motherboard has 4 RAM slots, so this could be upgraded.&lt;/p&gt;

&lt;h3 id=&quot;power-supply&quot;&gt;Power supply&lt;/h3&gt;

&lt;p&gt;The suggested power supply is minimum 650w with this setup. I chose a 1000w power supply to future proof myself in case I wanted to get another GPU. The case has room for another, and this is Jeremy Howard of &lt;a href=&quot;fast.ai&quot;&gt;https://www.fast.ai/&lt;/a&gt;’s recommendation. One for running training jobs and a second for developing. I can only hope to get to that level someday.&lt;/p&gt;

&lt;h1 id=&quot;images&quot;&gt;Images&lt;/h1&gt;

&lt;p&gt;DL Machine&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/ra8araR.jpg&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;All the boxes&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/CMK6mif.jpg&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;jupyter-notebook&quot;&gt;Jupyter Notebook&lt;/h1&gt;

&lt;p&gt;I’m putting a section for this so I remember!&lt;/p&gt;

&lt;p&gt;First, port forwarding must be setup for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;8888&lt;/code&gt; port for the Wifi Home network to port forward to the DL machine.&lt;/p&gt;

&lt;p&gt;Launch Jupyter on the server&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jupyter notebook --no-browser --port=8888
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On the client setup port forwarding&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ssh -N -f -L localhost:8888:localhost:8888 -i ~/.ssh/my.pem  username@hostname
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Go to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localhost:8888&lt;/code&gt; in the browser and Jupyter should be loaded.&lt;/p&gt;

&lt;h1 id=&quot;useful-commands&quot;&gt;Useful commands&lt;/h1&gt;

&lt;p&gt;To see which ssh processes are running, this will show ssh port forwarding&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ps aux | grep ssh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Kill a process by PID&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kill -9 &amp;lt;pid&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;List all Process PIDs accessing a Port&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;lsof -ti:&amp;lt;port&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Kill all processes accessing a port&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;lsof -ti:&amp;lt;port&amp;gt; | xargs kill -9
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wget&lt;/code&gt; in background&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wget -bqc url
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;wifi-interface-setup-and-commands&quot;&gt;Wifi Interface setup and commands&lt;/h2&gt;

&lt;p&gt;Make sure that the driver is downloaded. I used this &lt;a href=&quot;https://github.com/abperiasamy/rtl8812AU_8821AU_linux&quot;&gt;Github repo&lt;/a&gt; for my driver &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rtl8812AU&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Follow the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;README.md&lt;/code&gt; installation instructions:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# cd /usr/src/rtl8812au&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# sudo make clean&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# sudo make&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# sudo make install&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# sudo modprobe -a rtl8812au&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then check &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ifconfig -a&lt;/code&gt; to see if interface is present.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iwconfig&lt;/code&gt; - will show wifi interfaces&lt;/p&gt;

&lt;p&gt;If the interface is present, from here run one of the following to register an ip address to the interface:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo ip link set wlp3s0 down
sudo ip link set wlp3s0 up
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or restart machine:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo shutdown -r
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Check if it’s working&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ping -c3 192.168.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you’re using port forwarding, the IP address may have changed, so check the new IP address and adjust if needed.&lt;/p&gt;

&lt;h1 id=&quot;references&quot;&gt;References&lt;/h1&gt;

&lt;p&gt;Nvidia official CUDA Toolkit Documentation:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#ubuntu-installation&quot;&gt;https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#ubuntu-installation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nvidia CUDA Downloads Page:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://developer.nvidia.com/cuda-downloads?target_os=Linux&amp;amp;target_arch=x86_64&amp;amp;target_distro=Ubuntu&amp;amp;target_version=1804&amp;amp;target_type=deblocal&quot;&gt;https://developer.nvidia.com/cuda-downloads?target_os=Linux&amp;amp;target_arch=x86_64&amp;amp;target_distro=Ubuntu&amp;amp;target_version=1804&amp;amp;target_type=deblocal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Setup DL Machine Tutorials:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://youtu.be/OZaFqY8UF6I&quot;&gt;Gaming PC Build YouTube video&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://linuxconfig.org/how-to-install-the-nvidia-drivers-on-ubuntu-18-04-bionic-beaver-linux&quot;&gt;https://linuxconfig.org/how-to-install-the-nvidia-drivers-on-ubuntu-18-04-bionic-beaver-linux&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://medium.com/yanda/building-your-own-deep-learning-dream-machine-4f02ccdb0460&quot;&gt;Medium - Build your own deep learning machine&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://blog.slavv.com/the-1700-great-deep-learning-box-assembly-setup-and-benchmarks-148c5ebe6415&quot;&gt;The $1700 great Deep Learning box: Assembly, setup and benchmarks&lt;/a&gt;&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Install USB Wifi dongle on Ubuntu 18.04</title>
        <link href="http://www.motivatedcoder.com/install-usb-wifi-dongle-on-ubuntu-18.04/"/>
        <updated>2019-01-05T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/install-usb-wifi-dongle-on-ubuntu-18.04</id>
        <content type="html">&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/Ixs418w.jpg&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To my benefit or downfall, whichever way you look at it, I bought the &lt;a href=&quot;https://www.amazon.com/gp/product/B078MJB351/&quot;&gt;Comfast CF-915AC USB Wifi Adapter&lt;/a&gt; from Amazon. This proved to be super difficult to install. Me being a noob in Wifi networking in Linux. After 3 part time days of fiddling with it, it is now work. Here’s my steps and how I got it working.&lt;/p&gt;

&lt;p&gt;Firstly, the USB Wifi Adapter came with a CD Rom to install the driver. I don’t have a CD Rom drive, so I hit Google, and started looking for what driver to use and how to install.&lt;/p&gt;

&lt;p&gt;Under the &lt;a href=&quot;https://wikidevi.com/wiki/COMFAST&quot;&gt;COMFAST Wiki&lt;/a&gt; it’s listed as using the &lt;strong&gt;RTL8811AU&lt;/strong&gt; Realtek chipset.&lt;/p&gt;

&lt;p&gt;I tried looking for RTL8811AU drivers via Google, since the product only came with a disk for installation and couldn’t find any drivers that matched. The Comfast official driver download links returned &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;404 page not found&lt;/code&gt; errors in Chinese!&lt;/p&gt;

&lt;p&gt;I then found this &lt;a href=&quot;https://ubuntuforums.org/showthread.php?t=2375603&quot;&gt;Ubuntu formus blog&lt;/a&gt; and it said that the &lt;strong&gt;RTL8812AU&lt;/strong&gt; driver could be used.&lt;/p&gt;

&lt;p&gt;I then followed this StackExchange answer to get the USB driver &lt;strong&gt;RTL8812AU&lt;/strong&gt; correctly installed:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://askubuntu.com/a/1045927/324695&quot;&gt;https://askubuntu.com/a/1045927/324695&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ifconfig&lt;/code&gt;, the interface was present, but it didn’t have an IP address.&lt;/p&gt;

&lt;p&gt;I am using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;netplan&lt;/code&gt; and my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/netplan/01-netcfg.yml&lt;/code&gt; currently looks like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;network:
  version: 2
  renderer: networkd
  ethernets:
    enp6s0:
      dhcp4: true
      nameservers:
        addresses: [8.8.8.8,8.8.4.4]
  wifis:
    wlx40a5ef40734c:
      dhcp4: true
      nameservers:
        addresses: [192.168.0.1, 8.8.8.8]
      access-points:
        &quot;my-wifi-router-name&quot;:
          password: &quot;my-password&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is becasue I have WPA security enabled, so the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;netplan&lt;/code&gt; yaml wasn’t work.&lt;/p&gt;

&lt;p&gt;I then followed this StackExchange answer:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://askubuntu.com/a/16588/324695&quot;&gt;https://askubuntu.com/a/16588/324695&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wpasupplicant&lt;/code&gt; package, I generated a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wpa.conf&lt;/code&gt; file as suggested, and using these commands could connect to the Wifi Router&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# install package
sudo apt install wpa_supplicant

# generates a file
wpa_passphrase SSID PASSWORD &amp;gt; wpa.conf

# command uses the file to connect, and runs as a daemon
sudo wpa_supplicant -i wlx40a5ef40734c -c wpa.conf -D wext -B
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Everything is now working. After a reboot, the Wifi still connects. I am smiling!&lt;/p&gt;

&lt;h1 id=&quot;steps-only&quot;&gt;Steps only&lt;/h1&gt;

&lt;p&gt;Here are the commands / steps only extracted from the above blogs.&lt;/p&gt;

&lt;h3 id=&quot;install-driver&quot;&gt;Install driver&lt;/h3&gt;

&lt;p&gt;First remove any old drivers in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/src&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, install new driver:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt purge rtl8812au-dkms
sudo apt install git
git clone https://github.com/abperiasamy/rtl8812AU_8821AU_linux.git
cd rtl8812AU_8821AU_linux
sudo make -f Makefile.dkms install
sudo modprobe rtl8812au
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Can view that driver is covered:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;modinfo rtl8812au | grep A811
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ifconfig -a&lt;/code&gt; and the Wifi interface should be up.&lt;/p&gt;

&lt;h3 id=&quot;configure-netplan&quot;&gt;Configure netplan&lt;/h3&gt;

&lt;p&gt;Configure netplan yaml file, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/netplan/01-netcfg.yml&lt;/code&gt; as shown above&lt;/p&gt;

&lt;p&gt;Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo netplan apply&lt;/code&gt; to apply changes.&lt;/p&gt;

&lt;h3 id=&quot;wpasupplicant&quot;&gt;wpasupplicant&lt;/h3&gt;

&lt;p&gt;Install this package for WPA security support&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt install wpasupplicant
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;reboot-and-check&quot;&gt;Reboot and check&lt;/h3&gt;

&lt;p&gt;Reboot computer and check&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;reboot

# should show the wifi interface now with an IP address if working
ifconfig -a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;logging-in-remotely&quot;&gt;Logging in remotely&lt;/h2&gt;

&lt;p&gt;There are 3 steps to do this&lt;/p&gt;

&lt;h3 id=&quot;1-assign-a-static-ip-address-to-your-home-network&quot;&gt;1. Assign a static IP address to your home network&lt;/h3&gt;

&lt;p&gt;This can be done from logging into your Wifi router. The URL to login will be on the bottom of your Wifi router.&lt;/p&gt;

&lt;p&gt;I have a Netgear router, so I&lt;/p&gt;

&lt;h3 id=&quot;2-the-dl-machine-should-be-dhcp-registered-to-an-ip-address&quot;&gt;2. The DL machine should be DHCP registered to an IP address&lt;/h3&gt;

&lt;p&gt;For me, this was already done in the previous step using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;netplan&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;3-add-port-forwarding&quot;&gt;3. Add port forwarding&lt;/h3&gt;

&lt;p&gt;This is configurable when logged in to the Router config. For me, &lt;a href=&quot;https://www.noip.com/support/knowledgebase/setting-port-forwarding-netgear-router-genie-firmware/&quot;&gt;this Netgear guide&lt;/a&gt; helped me setup port forwarding.&lt;/p&gt;

&lt;h3 id=&quot;4-test&quot;&gt;4. Test&lt;/h3&gt;

&lt;p&gt;I tested by connecting to my phone Wifi hotspot with my laptop then tested that I could ssh to the DL machine&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ssh -i ~/.ssh/my.pem username@hostname
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;some-interesting-points&quot;&gt;Some interesting points&lt;/h1&gt;

&lt;h2 id=&quot;ifconfig&quot;&gt;ifconfig&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ifconfig&lt;/code&gt; will show internet interfaces that are up&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ifconfig -a&lt;/code&gt; will show all internet interfaces whether they are up or down&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ifconfig&lt;/code&gt; was showing the Wifi interface as up, but with no IP. This meant that the USB Wifi adapter driver (driver) installation worked and it was registered as an interface in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;netplan&lt;/code&gt; but couldn’t connect to the network. It was the WPA security blocking it at this point.&lt;/p&gt;

&lt;h2 id=&quot;lshw&quot;&gt;lshw&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lshw -C network&lt;/code&gt; will show hardware. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-C network&lt;/code&gt; to only show “network” class of hardware.&lt;/p&gt;

&lt;p&gt;After successfully installing the driver, I could see the wifi network as DISABLED. Then running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;netplan apply&lt;/code&gt; this show the network as enabled.&lt;/p&gt;

&lt;h1 id=&quot;commands-used&quot;&gt;Commands used&lt;/h1&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# list usb ports and connected devices
lsusb

# configure network interfaces
ifconfig

# configure wifi network interfaces
iwconfig

# get detailed wifi info
iwlist &amp;lt;interface&amp;gt; s

# dynamic kernal support module
dkms

# ip show an manipulate routing, network devices, interfaces
ip link set &amp;lt;interface&amp;gt; up/down

# list hardware
lshw -C network


netplan apply

netplan --debug generate

# check if there&apos;s internet
ping -c3 www.ubuntu.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Commands</title>
        <link href="http://www.motivatedcoder.com/commands/"/>
        <updated>2019-01-01T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/commands</id>
        <content type="html">&lt;p&gt;I am consolidating my commands that I have spread accross blog posts to just this one blog post. I’m going to maintain and update this post, so I’m not searching accross posts for how to do something!&lt;/p&gt;

&lt;h2 id=&quot;jupyter&quot;&gt;Jupyter&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://jupyter.org/&quot;&gt;Jupyter Notebook&lt;/a&gt; commands&lt;/p&gt;

&lt;h3 id=&quot;remote-notebook-setup&quot;&gt;Remote notebook setup&lt;/h3&gt;

&lt;p&gt;Here is how to launch Jupyter on a remote server and then view and use Jupyter as if you were running it locally.&lt;/p&gt;

&lt;p&gt;On remote server, run this. (Need to be in the directory of the project with all dependencies installed obviously)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jupyter notebook --no-browser --port=8888
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Locally. First make sure if the port has been previously bound to, that it’s unbound.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# unbind port
lsof -ti:8888 | xargs kill -9

# connect
ssh -N -f -L localhost:8888:localhost:8888 -i ~/.ssh/my.pem  username@hostname
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Go to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localhost:8888&lt;/code&gt; in the browser and Jupyter should be loaded.&lt;/p&gt;

&lt;h2 id=&quot;lsof&quot;&gt;lsof&lt;/h2&gt;

&lt;p&gt;List all Process PIDs accessing a Port&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;lsof -ti:&amp;lt;port&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Kill all processes accessing a port&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;lsof -ti:&amp;lt;port&amp;gt; | xargs kill -9
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;kill&quot;&gt;kill&lt;/h2&gt;

&lt;p&gt;Kill a process by PID&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;kill -9 &amp;lt;pid&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Kill process by name&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pkill -f &amp;lt;name-of-process&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;wget&quot;&gt;wget&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wget&lt;/code&gt; in background&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wget -bqc url
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;ps&quot;&gt;ps&lt;/h2&gt;

&lt;p&gt;To see which ssh processes are running, this will show ssh port forwarding&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ps aux | grep ssh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;ls&quot;&gt;ls&lt;/h2&gt;

&lt;p&gt;count files in a dir - in order to check that the file count matches what was expected, or when the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zip&lt;/code&gt; file didn’t fully download, or to check the image file count vs. expected.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ls -1 | wc -l
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;fastjar&quot;&gt;fastjar&lt;/h2&gt;

&lt;p&gt;If a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;zip&lt;/code&gt; file didn’t fully download, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fastjar&lt;/code&gt; can be used to unzip it.&lt;/p&gt;

&lt;p&gt;Trying to unzip the file will give you:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;unzip error “End-of-central-directory signature not found”
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fastjar&lt;/code&gt; if the whole zip file didn’t download:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get install fastjar
jar xvf something.zip
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://askubuntu.com/questions/54904/unzip-error-end-of-central-directory-signature-not-found&quot;&gt;StackExchange reference&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;nvidia-smi&quot;&gt;nvidia-smi&lt;/h2&gt;

&lt;p&gt;equivalent to “tail nvidia-smi”&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# keeps passed traces
nvidia-smi -l 1

# doesn&apos;t keep past traces
watch -n0.1 nvidia-smi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;network-and-wifi-setup-related-commands&quot;&gt;Network and Wifi setup related commands&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# list usb ports and connected devices
lsusb

# configure network interfaces
ifconfig

# configure wifi network interfaces
iwconfig

# get detailed wifi info
iwlist &amp;lt;interface&amp;gt; s

# dynamic kernal support module
dkms

# ip show an manipulate routing, network devices, interfaces
ip link set &amp;lt;interface&amp;gt; up/down

# list hardware
lshw -C network

netplan apply

netplan --debug generate

# check if there&apos;s internet
ping -c3 www.ubuntu.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;nvidia-smi-1&quot;&gt;nvidia-smi&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# keeps passed traces
nvidia-smi -l 1

# doesn&apos;t keep past traces
watch -n0.1 nvidia-smi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>My init file is not running - init.d and chkconfig</title>
        <link href="http://www.motivatedcoder.com/my-init-file-is-not-running-initd-and-chkconfig/"/>
        <updated>2018-12-21T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/my-init-file-is-not-running-initd-and-chkconfig</id>
        <content type="html">&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/PMHxDFs.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So, the problem to solve is that an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init.d&lt;/code&gt; script isn’t running and I’m not sure why. When this problem first occurred I hit Google, and was still lost. After Googling and asking around, here is how to solve it and some helpful commands.&lt;/p&gt;

&lt;h2 id=&quot;initial-start&quot;&gt;Initial Start&lt;/h2&gt;

&lt;p&gt;At the start, the contents of my script, let’s call it &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my-init&lt;/code&gt;, looked like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#!/bin/bash
# chkconfig:  - 85 15
# start(), stop(), etc...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I had attempted to add it to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init.d&lt;/code&gt; startup scripts by calling:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo chkconfig --add /etc/init.d/my-init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The first problem was that there were no run levels. This line:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;# chkconfig:  - 85 15&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Has a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-&lt;/code&gt; where the run levels should go. I changed my runlevels to: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;# chkconfig:  345 85 15&lt;/code&gt;  and then ran these commands to re-add my script:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# remove the old file
sudo chkconfig --del /etc/init.d/my-init

# add file back with new changes
sudo chkconfig --add /etc/init.d/my-init
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This site has a good description of runlevels:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.tldp.org/HOWTO/HighQuality-Apps-HOWTO/boot.html&quot;&gt;https://www.tldp.org/HOWTO/HighQuality-Apps-HOWTO/boot.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, now runlevels are fixed, but it isn’t running. If that’s fixed, then where to look next?&lt;/p&gt;

&lt;h2 id=&quot;look-in-etc&quot;&gt;Look in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my-init&lt;/code&gt; was added correctly, then the file should be in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/init.d/&lt;/code&gt; directory. Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ls /etc/init.d/&lt;/code&gt; and the file should be listed.&lt;/p&gt;

&lt;p&gt;Each runlevel has a directory under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/&lt;/code&gt; named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/rc&amp;lt;run-level&amp;gt;.d/&lt;/code&gt;, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/rc3.d/&lt;/code&gt; for all init scripts that have a runlevel of 3.&lt;/p&gt;

&lt;p&gt;If the script has been correctly added to runlevel 3 for example, run this command:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo ls -l /etc/rc3.d/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And it should show a symlinked file, like:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/rc3.d/S85my-init -&amp;gt; /etc/init.d/my-init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;85&lt;/code&gt; is the order number that the script will be called at system boot. init scripts are called in ascending order from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1 - 99&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Okay, so the script is correctly linked, but it’s still not getting called, where next?&lt;/p&gt;

&lt;h2 id=&quot;ps-and-strace&quot;&gt;ps and strace&lt;/h2&gt;

&lt;p&gt;We can look at all running processes and the command used to envoke them using:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ps -ef&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The output is something like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 02:15 ?        00:00:01 /sbin/init
root      3177  1915  0 02:16 ?        00:00:00 /bin/sh /etc/rc3.d/S82something start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At this point, we should be looking for a process that is running that was invoked by the system start. The system is stuck on an init script with a lower level then ours. In this case &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;82&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A couple of things can be done now. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strace&lt;/code&gt;, which may be present or can be installed from the package manager, can be used to inspect the current running process and what it’s doing, by running:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;strace -f -y -p &amp;lt;PID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will show the current output. If there’s nothing useful, then try invoking the failing startup script with verbose output using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-x&lt;/code&gt; and see what is happening when it first get’s invoked. Command:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo bash -x /etc/rc3.d/S82something start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This should show something useful output.&lt;/p&gt;

&lt;p&gt;At this point, the issue was solved and the script was looking for some content it couldn’t find. After that failed, it was polling, trying to find it again, and repeat, so it was never exiting.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;For me, the problem to be solved and how these commands and concepts go together helped me remember and be able to debug when it happened relatively soon again on a different script and issue. I hope that this helps you as well. Thanks for reading.&lt;/p&gt;

&lt;p&gt;-Aaron&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Android Meetup - A/B Test Experimentation/Feature flagging</title>
        <link href="http://www.motivatedcoder.com/AB-Test-Experimentation-and-Feature-Flagging/"/>
        <updated>2018-10-20T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/AB-Test-Experimentation-and-Feature-Flagging</id>
        <content type="html">&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/OO5YuOX.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This blog post is about the Android Meetup that I went to where a Sr. Android Dev on the Uber Eats team discussed A/B Test Experimentation and Feature flagging&lt;/p&gt;

&lt;h2 id=&quot;ab-test-experimentation-what-is-it&quot;&gt;A/B Test Experimentation, What is it?&lt;/h2&gt;

&lt;p&gt;It’s testing two similar groups with different features to see which features are more popular / better&lt;/p&gt;

&lt;h3 id=&quot;why-is-this-valuable&quot;&gt;why is this valuable&lt;/h3&gt;

&lt;p&gt;apps features are then driven by what customers want&lt;/p&gt;

&lt;p&gt;because there if is a bug, the feature can be disabled vs. waiting for a new version of the app to be deployed and the User has to have on auto-update&lt;/p&gt;

&lt;p&gt;auto-update - a lot of Users disable this and do manual app updating&lt;/p&gt;

&lt;p&gt;can hide new feature behind a flag when it crashes&lt;/p&gt;

&lt;p&gt;can flag based on an Android version&lt;/p&gt;

&lt;h3 id=&quot;how-are-features-enabled--disabled&quot;&gt;How are features enabled / disabled&lt;/h3&gt;

&lt;p&gt;toggle feature flags on the server&lt;/p&gt;

&lt;h3 id=&quot;feature-flag-libraries&quot;&gt;feature flag libraries&lt;/h3&gt;

&lt;p&gt;Morpheus - Uber&lt;/p&gt;

&lt;p&gt;Ik - Facebook&lt;/p&gt;

&lt;p&gt;their are open source libraries to do this&lt;/p&gt;

&lt;h2 id=&quot;deployment-statistics&quot;&gt;Deployment statistics&lt;/h2&gt;

&lt;h3 id=&quot;android-deploy&quot;&gt;Android deploy&lt;/h3&gt;

&lt;p&gt;takes 30 minutes to role out a deploy&lt;/p&gt;

&lt;h3 id=&quot;ios-deploy&quot;&gt;iOS deploy&lt;/h3&gt;

&lt;p&gt;takes 1 week&lt;/p&gt;

&lt;h3 id=&quot;switches&quot;&gt;switches&lt;/h3&gt;

&lt;p&gt;geofences - like at the airport&lt;/p&gt;

&lt;p&gt;devices&lt;/p&gt;

&lt;p&gt;target by group&lt;/p&gt;

&lt;p&gt;per app flavor&lt;/p&gt;

&lt;h3 id=&quot;merging-code-with-flags&quot;&gt;merging code with flags&lt;/h3&gt;

&lt;p&gt;great because code gets merged that isn’t running yet until the the flag is enabled&lt;/p&gt;

&lt;h3 id=&quot;firebaseremoteconfig&quot;&gt;FirebaseRemoteConfig&lt;/h3&gt;

&lt;p&gt;config on the server to toggle feature flags&lt;/p&gt;

&lt;p&gt;FirebaseRemoteConfig is loaded on App boot, and then static calls to get data from the cache&lt;/p&gt;

&lt;h3 id=&quot;if--else-pattern-with-feature-flags&quot;&gt;if / else pattern with feature flags&lt;/h3&gt;

&lt;p&gt;eliminate after sometime&lt;/p&gt;

&lt;p&gt;Factory pattern to abstract if/else but if/else checks are just moved there&lt;/p&gt;

&lt;h3 id=&quot;when-to-launch-experiment&quot;&gt;when to launch experiment&lt;/h3&gt;

&lt;p&gt;don’t experiment on new Users&lt;/p&gt;

&lt;p&gt;wait for a User to be logged in&lt;/p&gt;

&lt;p&gt;can’t be the first time the app is started&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;maybe the RemoteConfig callback comes later, and other experiments are being ran, so done on the 2nd bootup or later&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;commits&quot;&gt;commits&lt;/h3&gt;

&lt;p&gt;message says&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;how to test
    &lt;ul&gt;
      &lt;li&gt;this says turn on this flag&lt;/li&gt;
      &lt;li&gt;restart app&lt;/li&gt;
      &lt;li&gt;do this thing&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;how to revert
    &lt;ul&gt;
      &lt;li&gt;this says to toggle the flag the other way&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;scaling&quot;&gt;Scaling&lt;/h3&gt;

&lt;p&gt;For servers - it’s for traffic&lt;/p&gt;

&lt;p&gt;For mobile - it’s for developers&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;number of developers&lt;/li&gt;
  &lt;li&gt;as they leave&lt;/li&gt;
  &lt;li&gt;processes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;merging-code-process-at-uber&quot;&gt;merging code process at Uber&lt;/h3&gt;

&lt;p&gt;Lynting checks are run before committing&lt;/p&gt;

&lt;p&gt;Espresso tests&lt;/p&gt;

&lt;p&gt;Unit tests&lt;/p&gt;

&lt;p&gt;No QA&lt;/p&gt;

&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;/h2&gt;

&lt;p&gt;Abstract Activites&lt;/p&gt;

&lt;p&gt;Dagger for Mocks&lt;/p&gt;

&lt;p&gt;Try to not use Android as much as possible in the logic - better for testing&lt;/p&gt;

&lt;p&gt;big device lab&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;is international for testing&lt;/li&gt;
  &lt;li&gt;can remotely connect to a device lab&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;uber&quot;&gt;Uber&lt;/h3&gt;

&lt;p&gt;Don’t use Gradle - they use Buck (created by Facebook)&lt;/p&gt;

&lt;p&gt;Use a module system - there are 1000 modules&lt;/p&gt;

&lt;p&gt;40m APK size&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;obfuscated&lt;/li&gt;
  &lt;li&gt;minified, etc…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unobfuscated Debug version - 100m&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;test code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Redex - for launching an app quickly&lt;/p&gt;

&lt;p&gt;Obfuscation - use’s Google Proguard&lt;/p&gt;

&lt;p&gt;Anthing for $$ - is internally built&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;b/c it can’t be down&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lots of 3rd party libs&lt;/p&gt;

&lt;p&gt;Open source as much as possible&lt;/p&gt;

&lt;p&gt;Buck - is open source&lt;/p&gt;

&lt;p&gt;OkHttp - contribute to this&lt;/p&gt;

&lt;h3 id=&quot;architecture&quot;&gt;Architecture&lt;/h3&gt;

&lt;p&gt;MVC - is used, so Activity class is much smaller&lt;/p&gt;

&lt;h3 id=&quot;things-to-learn&quot;&gt;things to learn&lt;/h3&gt;

&lt;p&gt;webview&lt;/p&gt;

&lt;p&gt;in app webview&lt;/p&gt;

&lt;h3 id=&quot;mockups&quot;&gt;mockups&lt;/h3&gt;

&lt;p&gt;no testing via Invision mock ups&lt;/p&gt;

&lt;p&gt;always testing on Users&lt;/p&gt;

&lt;h2 id=&quot;firebase&quot;&gt;Firebase&lt;/h2&gt;

&lt;p&gt;Google Play services is needed&lt;/p&gt;

&lt;p&gt;A/B testing exists out of the box in Firebase&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;just has to be enabled&lt;/li&gt;
  &lt;li&gt;Users will get collected into the A/B groups via the Firebase infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;feature-flags&quot;&gt;Feature Flags&lt;/h2&gt;

&lt;p&gt;for new features&lt;/p&gt;

&lt;p&gt;variants of current features&lt;/p&gt;

&lt;p&gt;will get notified if a feature is a security vulnerability&lt;/p&gt;

&lt;h3 id=&quot;locally-changing-of-feature-flags&quot;&gt;Locally changing of feature flags&lt;/h3&gt;

&lt;p&gt;can do this Locally, not on the main FirebaseRemoteConfig&lt;/p&gt;

&lt;h3 id=&quot;toggling-flags&quot;&gt;toggling flags&lt;/h3&gt;

&lt;p&gt;can do this programmatically after so many crashes&lt;/p&gt;

&lt;p&gt;things to flag on&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;city&lt;/li&gt;
  &lt;li&gt;phone type&lt;/li&gt;
  &lt;li&gt;Android version&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;build-flavors&quot;&gt;Build flavors&lt;/h3&gt;

&lt;p&gt;Only have 2 versions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;debug&lt;/li&gt;
  &lt;li&gt;prod&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;libraries&quot;&gt;Libraries&lt;/h2&gt;

&lt;p&gt;Charles - shows http calls&lt;/p&gt;

&lt;h2 id=&quot;ab-test&quot;&gt;A/B Test&lt;/h2&gt;

&lt;p&gt;has to be statistically significant&lt;/p&gt;

&lt;p&gt;crashes&lt;/p&gt;

&lt;p&gt;usage groups should be statistically significant&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;groups should have similar profiles in order to be comparable. i.e same phone or Android version&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PhD’s evaluate if crashes are statistically significant and stats on feature usage to see what features should be used&lt;/p&gt;

&lt;p&gt;Optimizely - library for measuring stats of usage&lt;/p&gt;

&lt;p&gt;sample size - depends on the feature&lt;/p&gt;

&lt;h3 id=&quot;java-version&quot;&gt;Java version&lt;/h3&gt;

&lt;p&gt;version is 8 in the demo&lt;/p&gt;

&lt;h1 id=&quot;other-notes&quot;&gt;other notes&lt;/h1&gt;

&lt;p&gt;take advantage of new features&lt;/p&gt;

&lt;h3 id=&quot;editor-config&quot;&gt;Editor Config&lt;/h3&gt;

&lt;p&gt;show param names for methods (currently I have this turned off)&lt;/p&gt;

&lt;h3 id=&quot;locations&quot;&gt;Locations&lt;/h3&gt;

&lt;p&gt;wifi trusted locations exists in Android O&lt;/p&gt;

&lt;h3 id=&quot;code&quot;&gt;code&lt;/h3&gt;

&lt;p&gt;Dagger - to initialize dependency graph&lt;/p&gt;

&lt;p&gt;retrofit&lt;/p&gt;

&lt;p&gt;RxJava&lt;/p&gt;

</content>
      </entry>
     
  
    
      <entry>
        <title>PyTorch Developer Conference 2018 - PTDC - part 1</title>
        <link href="http://www.motivatedcoder.com/PyTorch-Developer-Conference-2018-part-1/"/>
        <updated>2018-10-13T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/PyTorch-Developer-Conference-2018-part-1</id>
        <content type="html">&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/XGC9TJO.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is my cliff notes style blog about my experience at PyTorch Developer Conference that happened on October 2, 2018. This is part 1 because as I was going through my notes, there was so much content and things to read and explain more, that it couldn’t easily fit into one blog.&lt;/p&gt;

&lt;h2 id=&quot;talks&quot;&gt;Talks&lt;/h2&gt;

&lt;p&gt;The talks section is in loose chronological order of the &lt;a href=&quot;https://pytorch.fbreg.com/schedule&quot;&gt;speaker schedule&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are the links to all videos from the conference:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://youtu.be/JVT4XvixNvs&quot;&gt;PyTorch Developer Conference Part 1&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://youtu.be/8881p8p3Guk&quot;&gt;PyTorch Developer Conference Part 2&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://youtu.be/KJAnSyB6mME&quot;&gt;PyTorch Developer Conference Part 3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;keynote-jerome-presenti&quot;&gt;Keynote Jerome Presenti&lt;/h3&gt;

&lt;p&gt;Recent breakthroughs in AI are things such as &lt;a href=&quot;http://densepose.org/&quot;&gt;DensePose&lt;/a&gt;. This library has been recently open sourced by FaceBook.&lt;/p&gt;

&lt;p&gt;Today FB is announcing &lt;a href=&quot;https://hackernoon.com/pytorch-1-0-468332ba5163&quot;&gt;PyTorch 1.0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Current flow to get PyTorch into production is:&lt;/p&gt;

&lt;p&gt;Pytorch -&amp;gt; &lt;a href=&quot;https://pytorch.org/docs/stable/onnx.html&quot;&gt;ONNX&lt;/a&gt; -&amp;gt; &lt;a href=&quot;https://caffe2.ai/&quot;&gt;Caffe2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PyTorch 1.0 is about making this a more seemless process with the &lt;a href=&quot;https://pytorch.org/docs/master/jit.html&quot;&gt;torch.jit&lt;/a&gt; module.&lt;/p&gt;

&lt;p&gt;We need testing and tooling for ML, like software development 20 years ago. A seamless process to get PyTorch into production should exist, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;torch.jit&lt;/code&gt; was created.&lt;/p&gt;

&lt;p&gt;Hardware breakthroughs like the &lt;a href=&quot;https://www.nvidia.com/en-us/data-center/volta-gpu-architecture/&quot;&gt;volta&lt;/a&gt; have accelerated ML research.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://arxiv.org/pdf/1801.00829.pdf&quot;&gt;Operator fusion&lt;/a&gt; now speeds up training times.&lt;/p&gt;

&lt;h3 id=&quot;deep-dive-on-pytorch-10&quot;&gt;Deep Dive on PyTorch 1.0&lt;/h3&gt;

&lt;p&gt;The goal of PyTorch 1.0 is to make putting PyTorch models into production as seamless as possible. For this, the PyTorch team is also considering:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Research and flexibility is central to PyTorch.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Production constraints are:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;hardware efficiency&lt;/li&gt;
      &lt;li&gt;scalability&lt;/li&gt;
      &lt;li&gt;cross platform&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Currently &lt;a href=&quot;https://pytorch.org/docs/stable/onnx.html&quot;&gt;ONNX&lt;/a&gt; is the way to put PyTorch models into production.&lt;/p&gt;

&lt;p&gt;With PyTorch 1.0 comes the introduction of the &lt;a href=&quot;https://pytorch.org/docs/master/jit.html&quot;&gt;torch.jit&lt;/a&gt; module. This module allows the developer to write code once, and with the use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;torch.jit.trace&lt;/code&gt; decorators and other helpers from the module, the Python PyTorch model will be output to run independently from Python, for instance in a C++ program, and be production ready.&lt;/p&gt;

&lt;p&gt;PyTorch model development workflow that’s possible as of 1.0:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;experiment with models in Python&lt;/li&gt;
  &lt;li&gt;extract the model using a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;torch.jit.script&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;optimize and deploy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Torch scripts do operator fusion for algebraic simplification.&lt;/p&gt;

&lt;h4 id=&quot;torchjit-module&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;torch.jit&lt;/code&gt; module&lt;/h4&gt;

&lt;p&gt;Functions are decorated with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;torch.jit.script&lt;/code&gt;, while subclasses of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;torch.jit.ScriptModule&lt;/code&gt; use a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;torch.jit.script_method&lt;/code&gt; decorator. Also:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;records control flow&lt;/li&gt;
  &lt;li&gt;uses a subset of Python&lt;/li&gt;
  &lt;li&gt;more info here: &lt;a href=&quot;https://pytorch.org/docs/master/jit.html#torch.jit.ScriptModule&quot;&gt;https://pytorch.org/docs/master/jit.html#torch.jit.ScriptModule&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;torch.jit.trace&lt;/code&gt; does the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;runs code straight through&lt;/li&gt;
  &lt;li&gt;records what happens&lt;/li&gt;
  &lt;li&gt;can run later without Python present&lt;/li&gt;
  &lt;li&gt;more info here: &lt;a href=&quot;https://pytorch.org/docs/master/jit.html#torch.jit.trace&quot;&gt;https://pytorch.org/docs/master/jit.html#torch.jit.trace&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Models can then be saved to disk.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://pytorch.org/tutorials/advanced/cpp_export.html&quot;&gt;Tutorial for loading a PyTorch module to C++&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PyTorch library hierarchy described as:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Aten
 | 
Autograd
 |      \
 |    Python script
C++ extensions
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://pytorch.org/tutorials/advanced/cpp_extension.html&quot;&gt;Custom C++ exetensions for PyTorch can be written&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Uses &lt;a href=&quot;https://github.com/pybind/pybind11&quot;&gt;PyBind&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setup.py&lt;/code&gt; &lt;a href=&quot;https://pytorch.org/tutorials/advanced/cpp_extension.html#building-with-setuptools&quot;&gt;can load&lt;/a&gt; the custom extension&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deep learning C++ bare metal for ML&lt;/p&gt;

&lt;p&gt;All links available at &lt;a href=&quot;https://pytorch.org/cppdocs/&quot;&gt;pytorch.org/cppdocs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://pytorch.org/tutorials/intermediate/dist_tuto.html&quot;&gt;Distributed training&lt;/a&gt; uses &lt;a href=&quot;https://github.com/pytorch/pytorch/tree/master/torch/csrc/distributed/c10d&quot;&gt;C10D&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;performance driven C++ backend with Python frontend&lt;/li&gt;
  &lt;li&gt;uses futures with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async_op=True&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/pytorch/pytorch/blob/dfa03e94ebf24b12e889f749c481ed687441cf75/torch/distributed/distributed_c10d.py&quot;&gt;distributed_c10d.py&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;communication overlap&lt;/li&gt;
  &lt;li&gt;smart gradient sharing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;torch.distributed&lt;/code&gt; is deprecated in favor of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C10D&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;fairseq&quot;&gt;Fairseq&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/pytorch/fairseq&quot;&gt;Fairseq&lt;/a&gt; provides a sequence modeling toolkit&lt;/p&gt;

&lt;p&gt;Seq2Seq library that has been instrumental at FB&lt;/p&gt;

&lt;p&gt;Won the Global Machine Translation 2018 competition&lt;/p&gt;

&lt;p&gt;Trains machine translations (MT) in both directions&lt;/p&gt;

&lt;h3 id=&quot;pytorch-translate&quot;&gt;PyTorch Translate&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/pytorch/translate&quot;&gt;https://github.com/pytorch/translate&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;predict content language&lt;/li&gt;
  &lt;li&gt;predict view language&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Uses this flow&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Alten -&amp;gt; decode
            \
            C++ Beam search
           /
Encoder -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://code.fb.com/ai-research/rosetta-understanding-text-in-images-and-videos-with-machine-learning/&quot;&gt;FBGEMM for quantization&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/pytorch/text&quot;&gt;PyTorch Text&lt;/a&gt; has DataLoaders and abstractions for NLP&lt;/p&gt;

&lt;h3 id=&quot;ai-at-facebook&quot;&gt;AI at Facebook&lt;/h3&gt;

&lt;p&gt;2.2B Users&lt;/p&gt;

&lt;p&gt;300+ trillion predictions made per day&lt;/p&gt;

&lt;p&gt;FB AI Infrastructure runs many experiments per day&lt;/p&gt;

&lt;p&gt;Things that FB needs to achieve it:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;AI as a service&lt;/li&gt;
  &lt;li&gt;Data platform&lt;/li&gt;
  &lt;li&gt;AI foundation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Current library relationship&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;PyTorch - research
 |
ONNX - transferring
 |
Caffe2 - production
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Things that help scaling ML learning&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;increased batch sizes&lt;/li&gt;
  &lt;li&gt;increased learning rate&lt;/li&gt;
  &lt;li&gt;overlap with training and balance&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;more-notes-about-the-current-ml-environment&quot;&gt;More notes about the current ML environment&lt;/h3&gt;

&lt;p&gt;Models are needed for a highly fragmented hardware world. Mobile is highly fragmented and faces size constraints. Python isn’t always present, so production models should run without needing Python.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://arxiv.org/abs/1806.08342&quot;&gt;Quantization&lt;/a&gt; has been proven to speed up training without hurting model accuracy.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://anaconda.org/anaconda/libtorch&quot;&gt;LibTorch&lt;/a&gt; C++ frontend for PyTorch is now available.  Or, for download here &lt;a href=&quot;https://download.pytorch.org/libtorch/nightly/cpu/libtorch-macos-latest.zip&quot;&gt;https://download.pytorch.org/libtorch/nightly/cpu/libtorch-macos-latest.zip&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;people-i-met&quot;&gt;People I met&lt;/h3&gt;

&lt;p&gt;The community was so friendly and welcoming. Coming from a software development background and not data science, with my knowledge of data science from online classes I was able to communicate, learn and understand everyone at the conference.&lt;/p&gt;

&lt;p&gt;Some people I met were:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Conor - ML Intern&lt;/li&gt;
  &lt;li&gt;Tom - CTO at Paperspace&lt;/li&gt;
  &lt;li&gt;Francisco - ML Intern at fast.ai&lt;/li&gt;
  &lt;li&gt;Fedro - Data scientist working with Yann LeCun&lt;/li&gt;
  &lt;li&gt;James - core PyTorch Dev&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;next&quot;&gt;Next&lt;/h3&gt;

&lt;p&gt;I’ll be working on part 2 of this blog in the same style as this one. It will be a continuation of material presented in the conference with lots of links. More great PyTorch to come :)&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Python Unit Testing with MagicMock</title>
        <link href="http://www.motivatedcoder.com/python-unit-testing-with-magicmock/"/>
        <updated>2018-08-26T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/python-unit-testing-with-magicmock</id>
        <content type="html">&lt;p&gt;This blog post demostrates how to mock in Python given different scenarios using the &lt;a href=&quot;https://docs.python.org/3/library/unittest.mock.html&quot;&gt;mock&lt;/a&gt; and &lt;a href=&quot;https://github.com/alex/pretend&quot;&gt;pretend&lt;/a&gt; libraries.&lt;/p&gt;

&lt;p&gt;This blog post is example driven.&lt;/p&gt;

&lt;h2 id=&quot;what-is-mocking&quot;&gt;What is mocking&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Mock_object&quot;&gt;Mocking&lt;/a&gt; is the use of simulated objects, functions, return values, or mock errors for software testing. It is useful for creating specific application states to run automated tests against.&lt;/p&gt;

&lt;p&gt;Mocking can be useful for simulating an API response, where the API response can be made a static return value, so the tests are deterministic vs. an ever changing live API call that takes longer to request, the API could be subject to &lt;a href=&quot;https://helpx.adobe.com/coldfusion/api-manager/throttling-and-rate-limiting.html&quot;&gt;rate limiting&lt;/a&gt;, or maybe it’s a live system that can’t be live tested at will, such as a payment system.&lt;/p&gt;

&lt;p&gt;Let’s get started.&lt;/p&gt;

&lt;h2 id=&quot;initial-setup&quot;&gt;Initial Setup&lt;/h2&gt;

&lt;p&gt;Assume these libraries are imported&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# python2
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mock&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MagicMock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# python3
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;unittest.mock&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MagicMock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pretend&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stub&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# common example of a library to mock against
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;requests&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;some-basics-of-the-mock-library&quot;&gt;Some basics of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock&lt;/code&gt; library&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@patch&lt;/code&gt; can be used as a decorator for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unittest&lt;/code&gt; methods. It can target a production test method and make it’s return value a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MagicMock&lt;/code&gt; instance.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@patch&lt;/code&gt; is the same thing as using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MagicMock&lt;/code&gt; class. It sets the mocked method as a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MagicMock&lt;/code&gt; instance for the duration of the unit test method, then set’s back the method to reference it’s original definition when the unit test method completes.&lt;/p&gt;

&lt;p&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MagicMock&lt;/code&gt; instance can:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;capture the arguments that the method is called with&lt;/li&gt;
  &lt;li&gt;count how many times it’s called&lt;/li&gt;
  &lt;li&gt;return values that we specify&lt;/li&gt;
  &lt;li&gt;return the same or different values each time the mocked method is called&lt;/li&gt;
  &lt;li&gt;be made to raise errors&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;mock-at-the-call-site&quot;&gt;Mock at the call site&lt;/h2&gt;

&lt;p&gt;This is the first example, so a lot is going on here.&lt;/p&gt;

&lt;p&gt;The prod method must be targeted based on the call site of where the method being mocked is called, not where the method is defined.&lt;/p&gt;

&lt;p&gt;The below example shows that even though the method lives in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar.py&lt;/code&gt;, when we use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@patch&lt;/code&gt; to mock the method, it’s targeted using the Python path to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;foo.Biz.baz&lt;/code&gt;. This is the Python path to the call site.&lt;/p&gt;

&lt;p&gt;When using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@patch&lt;/code&gt;, the decorated unit test method will now require an additional argument. This is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock_biz&lt;/code&gt; in the example. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock_biz&lt;/code&gt; is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MagicMock&lt;/code&gt; instance.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# bar.py
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# foo.py
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# test.py
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;unittest&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mock&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MagicMock&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unittest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;foo.Bar.biz&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# not -&amp;gt; @patch(&quot;bar.Bar.biz&quot;)
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;called&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;called&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call_count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertIsInstance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MagicMock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;mock-two-things&quot;&gt;Mock two things&lt;/h1&gt;

&lt;p&gt;When mocking two methods, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MagicMock&lt;/code&gt; arguments to the method should be passed in in the order that the decorators wrap the unit test method. So, in the below example, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@patch&lt;/code&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar.requests.put&lt;/code&gt; first wraps the unit test method, so it takes the place of the first argument, then the next is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bar.requests.get&lt;/code&gt;, so it’s the 2nd argument.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# bar.py
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;requests&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query_first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query_first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;/remote/api/{id}&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;/remote/other/api/{id}&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                                                     &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# test.py
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;unittest&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mock&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unittest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bar.requests.get&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bar.requests.put&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock_put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock_get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query_first&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;called&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;called&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;mock-as-an-argument-captor&quot;&gt;Mock as an Argument Captor&lt;/h1&gt;

&lt;p&gt;Here is an example of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MagicMock&lt;/code&gt; instance capturing different arguments. It can capture positional and keyword arguments. In the below example, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;url&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;method&lt;/code&gt; are positional arguments to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bar.biz&lt;/code&gt;, and are stored in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock_biz.call_args[0]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;headers&lt;/code&gt; are keyword arguments, and are stored in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mock_biz.call_args[1]&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# bar.py
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# foo.py
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;GET&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# test.py
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unittest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;foo.Bar.biz&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;/api/users/{id}&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;phone_number&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;+17025551000&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;PUT&apos;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Authorization&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;JWT &amp;lt;your_token&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;called&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call_count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;data&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;headers&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;mock-a-return-value&quot;&gt;Mock a return value&lt;/h1&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MagicMock&lt;/code&gt; instance &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return_value&lt;/code&gt; attribute’s value can be set to mock a return value.&lt;/p&gt;

&lt;p&gt;This is a common use case for how to mock an API response.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# bar.py
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# foo.py
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# test.py
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unittest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;foo.Bar.biz&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;expected_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;return_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expected_value&lt;/span&gt;
        
        &lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expected_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;mock-multiple-return-values&quot;&gt;Mock multiple return values&lt;/h1&gt;

&lt;p&gt;If the mocked method is called multiple times, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MagicMock.return_value&lt;/code&gt; has been set, the same value will be returned each time the mocked method is called.&lt;/p&gt;

&lt;p&gt;In order to return different values each time, the value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MagicMock.side_effect&lt;/code&gt; can be set as in the below example.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MagicMock.call_args_list&lt;/code&gt; can be used to check what the different arguments each time the mocked method is called.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# bar.py
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expensive_computation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;expensive_computation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# foo.py
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;process_expensive_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
&lt;span class=&quot;c1&quot;&gt;# test.py
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unittest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bar.Bar.expensive_computation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;foo.process_expensive_value&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock_process_exp_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock_exp_comp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;value1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;value2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;mock_exp_comp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;side_effect&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        
        &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_exp_comp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;called&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_exp_comp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call_count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_process_exp_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call_args_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_process_exp_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call_args_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;mock-an-exception&quot;&gt;Mock an Exception&lt;/h1&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MagicMock.side_effect&lt;/code&gt; is more commonly used to mock throwing an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Exception&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is very useful because maybe the application hit a particular error state that is seen in the logs that needs to be guarded against. Instead of having to get the application back in that exact state to cause the error, the method that threw the error can be mocked to do throw the error, and then code can be written and tested to react accordingly.&lt;/p&gt;

&lt;p&gt;Here is an example:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# bar.py
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;some_condition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CustomException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
            
&lt;span class=&quot;c1&quot;&gt;# foo.py
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# test.py
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unittest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;foo.Bar.biz&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;mock_biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;side_effect&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CustomException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertRaises&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CustomException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;using-mock-objects&quot;&gt;Using mock objects&lt;/h2&gt;

&lt;p&gt;Here is an example of creating a mock object using the &lt;a href=&quot;https://github.com/alex/pretend&quot;&gt;stub&lt;/a&gt; library in order to create the exact response structure that you want to simulate and react to.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# bar.py
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;requests&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;/api/users/&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# foo.py
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;biz&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status_code&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loads&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;utf8&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;process_users_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;process_users_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# test.py
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pretend&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stub&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unittest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bar.requests.get&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;patch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;foo.process_users_data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock_process_users_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mock_get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;fake_reponse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;status_code&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dumps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;users&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;data&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;utf8&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;mock_get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;return_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fake_reponse&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mock_process_users_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;called&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assertEqual&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;mock_process_users_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loads&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fake_reponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;utf8&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;other-info-about-mocking&quot;&gt;Other info about mocking&lt;/h2&gt;

&lt;p&gt;Parent methods can be mocked, so if your code calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;super()&lt;/code&gt;, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@patch&lt;/code&gt; should target the parent class’s method.&lt;/p&gt;

&lt;p&gt;Constructors can be mocked. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return_value = None&lt;/code&gt; must be set because a Python constructor can’t have  a return value.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Mocking has been super useful for me in my professional software developer career. Code gets more and more complicated as applications scale, so being able to isolate inputs and outputs to a function within a system is priceless for unit testing.&lt;/p&gt;

&lt;p&gt;Integration testing, the degree of mocking, and overall test strategy has to be thought of a lot. It can’t just be “mock all the things” and then you have 100% test coverage, and an application that is bullet proof. Maybe the mocks are wrong, there’s too many, etc.. Maybe things that don’t need to be tested are tested. Over testing is a thing.&lt;/p&gt;

&lt;p&gt;If you have any feedback, drop me a &lt;a href=&quot;mailto:aaron.lelevier@gmail.com&quot;&gt;line&lt;/a&gt; or comment below.&lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Using Git Aliases and How to Display the Current Git Branch Name in a Terminal Prompt</title>
        <link href="http://www.motivatedcoder.com/git-workflow-hacks/"/>
        <updated>2018-06-22T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/git-workflow-hacks</id>
        <content type="html">&lt;p&gt;Here are two Git workflow hacks that help me be more productive.&lt;/p&gt;

&lt;h2 id=&quot;git-aliases&quot;&gt;Git Aliases&lt;/h2&gt;

&lt;p&gt;Git aliases help me to be more productive. With how often we as developers type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git&lt;/code&gt; commands, using aliases allows for less typing and less typos. Here are my current &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git&lt;/code&gt; aliases.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/aaronlelevier/4147ac784c543bfd8029f13db4669706.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;I like to keep the above &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git&lt;/code&gt; aliases in a separate file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.gitshortcuts&lt;/code&gt; from my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.bash_profile&lt;/code&gt;. Then I add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;source ~/.gitshortcuts&lt;/code&gt; to my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.bash_profile&lt;/code&gt;. This helps keep things neat.&lt;/p&gt;

&lt;h2 id=&quot;display-the-current-git-branch-name-in-a-terminal-prompt&quot;&gt;Display the Current Git Branch Name in a Terminal Prompt&lt;/h2&gt;

&lt;p&gt;I found myself always typing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git status&lt;/code&gt; to find out what branch I was on before running the next &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git&lt;/code&gt; command. Always having the current &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git&lt;/code&gt; branch name displayed removes the need to always check this.  Here’s my terminal prompt.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/aaronlelevier/d70964e817bcbb96af5b061c48c6c7ef.js&quot;&gt;&lt;/script&gt;

&lt;h2 id=&quot;use-backup-branches-bonus&quot;&gt;Use backup branches (Bonus)&lt;/h2&gt;

&lt;p&gt;I worked with a senior developer that once told me:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Behind the scenes I’m always managing a backup branch&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This really stuck with me. His convention was to create a backup branch with the suffix &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-BAK&lt;/code&gt;. This strategy is really helpful. If you’re unsure if a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git rebase&lt;/code&gt; will work, and all conflicts will be resolved correctly or some other series of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git&lt;/code&gt; actions, having a backup branch allows you to easily restore from the last time that you were sure about your changes without having to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git reflog&lt;/code&gt; and so on.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;That’s it for now. I’m sure there’s a lot more &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git&lt;/code&gt; hacks that I should be using. Drop me a line and let me know!&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Intro to Graphs</title>
        <link href="http://www.motivatedcoder.com/intro-to-graphs/"/>
        <updated>2018-06-05T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/intro-to-graphs</id>
        <content type="html">&lt;p&gt;The goal of this blog post is to distill down my learning of Graph Theory. The following learning took about 8 hours of my time, so if I can give it to someone in a single blog post with links for further reading, then I hope that I’m adding value to the reader.&lt;/p&gt;

&lt;p&gt;I initially did this research before getting into &lt;a href=&quot;https://neo4j.com/&quot;&gt;Neo4j&lt;/a&gt;, the most widely used graph database. I like to use motivation of doing something new to also learn new things in that area, so it becomes a richer learning experience.&lt;/p&gt;

&lt;p&gt;At the time of this writing, the &lt;a href=&quot;https://aws.amazon.com/neptune/&quot;&gt;AWS Neptune&lt;/a&gt; graph database has recently been made publicly available, so this blog post is potentially more relevant.&lt;/p&gt;

&lt;h1 id=&quot;what-is-a-graph&quot;&gt;What is a Graph?&lt;/h1&gt;

&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Graph_(discrete_mathematics)&quot;&gt;Graph&lt;/a&gt; is a finite &lt;a href=&quot;https://en.wikipedia.org/wiki/Set_theory&quot;&gt;set&lt;/a&gt; of connected &lt;a href=&quot;https://en.wikipedia.org/wiki/Vertex_(graph_theory)&quot;&gt;nodes&lt;/a&gt;. These nodes are connected by &lt;a href=&quot;https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms#edge&quot;&gt;edges&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the below graph. Each number is a node. Each line connecting them is an edge.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/iE31kn3.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;nodes&quot;&gt;Nodes&lt;/h2&gt;

&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Vertex_(graph_theory)&quot;&gt;node&lt;/a&gt; is a connected object in the graph. They can also called a &lt;em&gt;vertex&lt;/em&gt; (singular) or &lt;em&gt;vertices&lt;/em&gt; (plural).&lt;/p&gt;

&lt;p&gt;Nodes should have a unique identifier, such as a name or id. They can also store any other amout of arbitrary information. In a social graph, for example, a node would be a person. In a computer network, different machines would be nodes, their IP address or host name could be a unique identifier of the node.&lt;/p&gt;

&lt;h2 id=&quot;edges&quot;&gt;Edges&lt;/h2&gt;

&lt;p&gt;An &lt;a href=&quot;https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms#edge&quot;&gt;edge&lt;/a&gt; is the connection between two nodes.&lt;/p&gt;

&lt;p&gt;An edge can also be called an &lt;em&gt;arc&lt;/em&gt; or a &lt;em&gt;line&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Edges can be &lt;em&gt;directed&lt;/em&gt; or &lt;em&gt;undirected&lt;/em&gt; (more on this later).&lt;/p&gt;

&lt;p&gt;Edges can store information as well. In the case of a social graph, they may store information like how long two people have been connected. In a computer network graph, they could store connection protocols.&lt;/p&gt;

&lt;h2 id=&quot;incidents&quot;&gt;Incidents&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/TiWWQpR.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;incident-vertices&quot;&gt;Incident vertices&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Incident vertices&lt;/em&gt; are vertices that an edge connects. In the above graph, edge &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e&lt;/code&gt;’s incident vertices are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{U,V}&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;incident-edge&quot;&gt;Incident edge&lt;/h3&gt;

&lt;p&gt;An &lt;em&gt;incident edge&lt;/em&gt; is the edge that connects a pair of vertices. Above, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{U,V}&lt;/code&gt;’s incident edge is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Wikipedia Reference: &lt;a href=&quot;https://proofwiki.org/wiki/Definition:Incident_(Graph_Theory)/Undirected_Graph&quot;&gt;https://proofwiki.org/wiki/Definition:Incident_(Graph_Theory)/Undirected_Graph)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stack Overflow reference: &lt;a href=&quot;https://stackoverflow.com/a/16886038&quot;&gt;https://stackoverflow.com/a/16886038&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;types-of-graphs&quot;&gt;Types of Graphs&lt;/h1&gt;

&lt;p&gt;There are two main types of graphs. Undirected and Directed. This section discusses these in more detail.&lt;/p&gt;

&lt;h2 id=&quot;undirected-graph&quot;&gt;Undirected Graph&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/Kt78Dph.jpg&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Graph_(discrete_mathematics)#Undirected_graph&quot;&gt;Undirected graphs&lt;/a&gt; are connected graphs, but their is no direction to those connections. There isn’t a direction though between the nodes.&lt;/p&gt;

&lt;p&gt;An example of this is &lt;strong&gt;LinkedIn&lt;/strong&gt;. People have connections, or edges in graph theory terminology, but there is not direction to the relationships.&lt;/p&gt;

&lt;p&gt;Undirected graphs can be represented as a list of unordered pairs that represent all connections making up the graph.&lt;/p&gt;

&lt;h2 id=&quot;unidirectional-graphs&quot;&gt;Unidirectional Graphs&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/xpuQ40X.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;There are 2 types of &lt;a href=&quot;https://en.wikipedia.org/wiki/Directed_graph&quot;&gt;directed graphs&lt;/a&gt;. The first is a unidirectional graph. This type of directed graph has relationships that go in a single direction.&lt;/p&gt;

&lt;p&gt;An example of this would be an organizational hierarchy. An employee has a boss, or maybe more than one if he or she is so lucky, but you can’t be someone’s boss and that person also be your boss.&lt;/p&gt;

&lt;p&gt;Directed graphs can be represented as a list of ordered pairs.&lt;/p&gt;

&lt;p&gt;Here, &lt;em&gt;edges&lt;/em&gt; can be called directed edges, arrows, or directed (arcs, lines).&lt;/p&gt;

&lt;p&gt;This type of graph is also known as an &lt;em&gt;oriented graph&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;bidirectional-graphs&quot;&gt;Bidirectional Graphs&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/CZHWvtP.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Bidirected_graph&quot;&gt;bidirectional graph&lt;/a&gt; is a directed graph, where edges can be directed in both directions.&lt;/p&gt;

&lt;p&gt;An example of this is Twitter. In Twitter you can follow someone, and they can follow you. In this case the relationship could be in both directions, but not necessarily.&lt;/p&gt;

&lt;h1 id=&quot;graph-matricies&quot;&gt;Graph Matricies&lt;/h1&gt;

&lt;p&gt;Different types of matrices can be used to represent a single graph’s information. These matricies can be used to compute different information and for performant lookups.&lt;/p&gt;

&lt;p&gt;It is importatant to note that a single matrix may or may not be an &lt;a href=&quot;https://en.wikipedia.org/wiki/Isomorphism&quot;&gt;isomophism&lt;/a&gt; of the graph. This means that all information about the graph may not be represented in a single matrix. Diagonal matrices, for example, tell the number of incoming edges per node, but not which nodes are connected.&lt;/p&gt;

&lt;h2 id=&quot;adjacency-matrix&quot;&gt;Adjacency Matrix&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/L84sNRM.gif&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;An &lt;a href=&quot;https://en.wikipedia.org/wiki/Adjacency_matrix&quot;&gt;adjacency matrix&lt;/a&gt; is a square matrix that tells which nodes are connected by displaying a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt; if connected, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; if not connected.&lt;/p&gt;

&lt;p&gt;In an &lt;em&gt;undirected&lt;/em&gt; graph, as the above pictures, this matrix is symmetric.&lt;/p&gt;

&lt;p&gt;For &lt;em&gt;directed graphs&lt;/em&gt;, the adjacency matrix will have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt; denoting the direction of the incoming edge, otherwise &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;, so the matrix is most likely not symmetric.&lt;/p&gt;

&lt;h3 id=&quot;coding-challenge-example&quot;&gt;Coding challenge example&lt;/h3&gt;

&lt;p&gt;I came accross an &lt;em&gt;adjacency matrix&lt;/em&gt; in a coding challenge as part of a job interview. The challenge was to take a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3x3&lt;/code&gt; matrix of unique random values from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1-9&lt;/code&gt;. And, then be able to accept a sequence of values, and say how many steps it takes to traverse back and forth on this random &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3x3&lt;/code&gt; grid where positions to traverse is a random sequence as well. An adjacent position is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt; step, otherwise it’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt; steps.&lt;/p&gt;

&lt;p&gt;Here’s a concrete example of this problem:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Rando 3x3 grid
[[2, 5, 9],
 [1, 8, 3],
 [4, 6, 7]]
 
How may steps does it take to traverse [2, 5, 8, 3, 4]?
 
Can you take any random grid and also random sequence and comput this?
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This can be solved by loading the random 3x3 data into an &lt;em&gt;adjacency matrix&lt;/em&gt;. The adjacent positions in the grid are connections, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;’s, otherwise they are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;’s. An adjacency matrix can be used as a lookup to solve how many steps it takes.&lt;/p&gt;

&lt;p&gt;And &lt;em&gt;adjacency list&lt;/em&gt; could also be used.&lt;/p&gt;

&lt;h2 id=&quot;degree-matrix&quot;&gt;Degree Matrix&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/LjEt3p3.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Degree_matrix&quot;&gt;degree matrix&lt;/a&gt; is a diagonal matrix that says the degree of the vertices. The degree of a vertex is the number of it’s incidence edges. The vertices are plotted on the rows and columns.&lt;/p&gt;

&lt;p&gt;In the above matrix, vertex &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt; in the top left most position has a degree of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4&lt;/code&gt; &lt;em&gt;incidence edges&lt;/em&gt;, edge &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt; has degree of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;h2 id=&quot;incidence-matrix&quot;&gt;Incidence Matrix&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/hWR9bX0.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;inidence-matrix-of-above-graph&quot;&gt;Inidence Matrix of above graph&lt;/h3&gt;

&lt;p&gt;The columns are the edges, and the rows are the nodes. Edge &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e1&lt;/code&gt; in column &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt; is the incidence edge of vertices &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{1,2}&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e2&lt;/code&gt; is the incidence edge for vertices &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{1,3}&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[[1, 1, 1, 0],
 [1, 0, 0, 0],
 [0, 1, 0, 1],
 [0, 0, 1, 1]]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Incidence_matrix&quot;&gt;incidence matrix&lt;/a&gt; is a matrix that says which edges connect which nodes by plotting the incidence edges as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;’s, otherwise &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;’s.&lt;/p&gt;

&lt;p&gt;Incidence matrices are square if the number of vertices equals the number of nodes, otherwise they’re non-square.&lt;/p&gt;

&lt;h3 id=&quot;directed-incidence-matrix&quot;&gt;Directed Incidence Matrix&lt;/h3&gt;

&lt;p&gt;For &lt;em&gt;unidirectional graphs&lt;/em&gt; these are represented with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-1&lt;/code&gt; for outgoing edges, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt; for incoming edges, otherwise &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For a &lt;em&gt;bidirectional graph&lt;/em&gt; they follow the same rules as a unidirectional incidence matrix, except for incoming and outgoing endges between nodes, the data is represented by a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;adjacency-list&quot;&gt;Adjacency List&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/hWR9bX0.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;adjacency-list-of-the-above-graph&quot;&gt;Adjacency list of the above graph&lt;/h3&gt;

&lt;p&gt;The rows represent a node and the columns are the connected nodes values.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[[2, 3, 4],
 [1],
 [1, 4],
 [1, 3]]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;An &lt;a href=&quot;https://en.wikipedia.org/wiki/Adjacency_list&quot;&gt;adjacency list&lt;/a&gt; is a list of nodes’ adjancent nodes. The first element, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[2, 3, 4]&lt;/code&gt;, is node &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;’s adjacent nodes, the second element, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[1]&lt;/code&gt;, is node &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;’s adjacent nodes, and so on.&lt;/p&gt;

&lt;h1 id=&quot;continued-reading&quot;&gt;Continued Reading&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;https://www.geeksforgeeks.org/graph-data-structure-and-algorithms/&quot;&gt;Graph Data Structure And Algorithms&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;comprehensive list of graph algorithms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/neo4j-contrib/neo4j-graph-algorithms&quot;&gt;Neo4j Graph Algorithms&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Neo4j at the time of this writing has 300+ algorithms for use with it’s graph database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Directed_acyclic_graph&quot;&gt;Directed Acyclic Graphs&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;These are one particularly interesting naturally occuring type of &lt;em&gt;unidirectional graph&lt;/em&gt; that is used in project management, and there are software frameworks that implement them as well.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;example-graph-project&quot;&gt;Example Graph Project&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/4yJh6XE.png&quot; alt=&quot;Imgur&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is from a demo project that I did. It’s a &lt;em&gt;Bidirectional Graph&lt;/em&gt; of my Github followers using  Neo4j, D3.js, and Python Multithreading. Here’s the link if anyone’s interested:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/aaronlelevier/neo4j-github-followers&quot;&gt;https://github.com/aaronlelevier/neo4j-github-followers&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Graphs are very interesting. They appear in so many places like social networks, machine learning, decision trees, and a lot more. This is really just a quick introduction. There are many sub-types of graphs within the above three main categories of graphs mentioned.&lt;/p&gt;

&lt;p&gt;This research was originally part of my pre-research in order to learn more about graphs before trying out &lt;a href=&quot;https://neo4j.com/&quot;&gt;Neo4j&lt;/a&gt;, the largest graph database platform. I first saw Neo4j as recommended experience to have on a job posting, and I didn’t know what it was, so I started to look into it. This research was in my spiral notebook, so now it’s public for other’s if they’re intersted.&lt;/p&gt;

&lt;p&gt;Thank you for reading. Happy coding!&lt;/p&gt;

</content>
      </entry>
     
  
    
      <entry>
        <title>virtualenv Cheatsheet</title>
        <link href="http://www.motivatedcoder.com/virtualenv-cheatsheet/"/>
        <updated>2018-05-26T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/virtualenv-cheatsheet</id>
        <content type="html">&lt;p&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; is one of the first things a Python programmer learns about. This blog post describes what it is, how to set it up, and examples of some concrete use cases.&lt;/p&gt;

&lt;h2 id=&quot;what-is-a-virtualenv&quot;&gt;What is a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt;?&lt;/h2&gt;

&lt;p&gt;A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; is a way of having separate Python environments. It allows you to have different environments for Python 2 and Python 3 and the 3rd party package dependencies to go along with that environment.&lt;/p&gt;

&lt;h2 id=&quot;quickstart&quot;&gt;Quickstart&lt;/h2&gt;

&lt;p&gt;Run the following commands to create and activate your first &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;virtualenv-for-python3&quot;&gt;virtualenv for Python3&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# installs PIP globally
curl https://bootstrap.pypa.io/get-pip.py | python

# creates a virtualenv
python3 -m venv venv

# activates the virtualenv
source venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;virtualenv-for-python2&quot;&gt;virtualenv for Python2&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# installs PIP globally
curl https://bootstrap.pypa.io/get-pip.py | python

# installs virtualenv globally
pip install virtualenv

# creates a virtualenv
virtualenv -p python2.7 venv

# activates the virtualenv
source venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;verify-its-working&quot;&gt;Verify it’s working&lt;/h3&gt;

&lt;p&gt;You should see the command line now starting with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;(venv)&lt;/code&gt;. This means that the virtualenv is active.&lt;/p&gt;

&lt;p&gt;Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;which python&lt;/code&gt; and it should point to a Python executable inside the virtualenv at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;venv/bin/python&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;quickstart-explanation&quot;&gt;Quickstart Explanation&lt;/h2&gt;

&lt;p&gt;First get &lt;a href=&quot;https://pypi.org/project/pip/&quot;&gt;pip&lt;/a&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip&lt;/code&gt;, which stands for “Pip Installs Packages”, is the Python ecosystem’s package installer. If it is not already installed. This can be done using the linked instructions, or with this command.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl https://bootstrap.pypa.io/get-pip.py | python
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you already have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip&lt;/code&gt; or just want to check, run this command to check and output all installed 3rd party packages:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip freeze
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you currently have other 3rd party packages, and want to clean up the gloal dependencies, then run this command to remove all 3rd party packages:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip freeze | xargs pip uninstall -y
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is my prefered configuration. To only have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; as the single global 3rd party package. Other packages are local to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, install &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; globally.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip install virtualenv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Check what version of Python is the default version.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python -V
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On my machine, the previous command returned &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Python 2.7.14&lt;/code&gt;. So, when I create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; this will be the default Python version, unless another version is specified.&lt;/p&gt;

&lt;p&gt;Create a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;virtualenv venv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Why is it named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;venv&lt;/code&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By convention, the name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;venv&lt;/code&gt; is used as the name of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt;, but any name can be used.&lt;/p&gt;

&lt;p&gt;Now, activate the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;source venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;venv&lt;/code&gt;, the name of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; should show at the start of the command line prompt.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# before
~/Documents/github/jira (master) $

# after
(venv) ~/Documents/github/jira (master) $
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip freeze&lt;/code&gt; at this point, there should be no output because this is a new Python environment. The global &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; that was just installed should not appear in the output.&lt;/p&gt;

&lt;p&gt;At this point, any 3rd party Python package can be installed, just like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; was installed globally, and as long as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; is active, it will be private to that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To deactivate the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt;, run:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;deactivate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;cheatsheet&quot;&gt;CheatSheet&lt;/h2&gt;

&lt;p&gt;Here are some use cases and common commands.&lt;/p&gt;

&lt;h3 id=&quot;create-a-virtualenv-in-python3&quot;&gt;Create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; in Python3&lt;/h3&gt;

&lt;p&gt;The &lt;a href=&quot;https://docs.python.org/3/library/venv.html&quot;&gt;venv&lt;/a&gt; standard library package is available as of Python 3.3 and can be used to create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python3 -m venv venv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;virtualenv-with-a-specific-version-of-python&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; with a specific version of Python&lt;/h3&gt;

&lt;p&gt;This will create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; in Python 3.5&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;virtualenv -p /usr/local/bin/python3.5 venv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;access-the-virtualenv-without-it-being-active&quot;&gt;Access the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; without it being active&lt;/h3&gt;

&lt;p&gt;By using the path to the Python executable inside of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;venv&lt;/code&gt;, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; and all of it’s 3rd party packages will be loaded:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;~/Documents/github/jira (master) $ python
Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 12:01:12)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&amp;gt;&amp;gt;&amp;gt; exit()
~/Documents/github/jira (master) $ venv/bin/python
Python 3.6.2 (v3.6.2:5fd33b5926, Jul 16 2017, 20:11:06)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&amp;gt;&amp;gt;&amp;gt; exit()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;virtualenv-with-cron&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt; with &lt;a href=&quot;https://en.wikipedia.org/wiki/Cron&quot;&gt;cron&lt;/a&gt;&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;crontab -e
* * * * * /path/to/venv/bin/python /path/to/code.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;include-global-python-packages-when-creating-a-virtualenv&quot;&gt;Include global Python packages when creating a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt;&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;virtualenv --system-site-packages venv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;delete-a-virtualenv&quot;&gt;Delete a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;virtualenv&lt;/code&gt;&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rm -rf venv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;store-copy-of-python-package-versions&quot;&gt;Store copy of Python package versions&lt;/h3&gt;

&lt;p&gt;This is done by convention in a file called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;requirements.txt&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip freeze &amp;gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;install-all-packages-from-requirementstxt&quot;&gt;Install all packages from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;requirements.txt&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;This command would be used when running another projects code, to install all dependencies of the project.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://virtualenv.pypa.io/en/stable/&quot;&gt;virtualenv&lt;/a&gt; has been very useful. Now days, with Docker, and containers, they’re not always necessary, but if you’re developing locally and have multiple Python projects, they’re a must. You won’t get package conflicts, and can maintain different Python version and environments.&lt;/p&gt;

&lt;h3 id=&quot;any-questions&quot;&gt;Any questions?&lt;/h3&gt;

&lt;p&gt;Thank you for reading. If you have any questions or anything that I can add, please let me know. Thanks.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Multithreading in Python</title>
        <link href="http://www.motivatedcoder.com/multithreading-in-python/"/>
        <updated>2018-04-05T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/multithreading-in-python</id>
        <content type="html">&lt;p&gt;This blog post is about Processes, Threads, and the GIL in Python.  Because of the way that the Python GIL operates, it may be different than one initially expects, so this blog post is an attempt to discuss this in more detail.&lt;/p&gt;

&lt;h3 id=&quot;some-background&quot;&gt;Some background&lt;/h3&gt;

&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Process_(computing)&quot;&gt;Process&lt;/a&gt; is a instance of a computer program in execution. It has it’s own address space, data stack, memory, and auxiliary data to keep track of it’s execution.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Thread_(computing)&quot;&gt;Threads&lt;/a&gt; exist within a process. They can run in parallel to the main thread of a process and share the same data space.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://wiki.python.org/moin/GlobalInterpreterLock&quot;&gt;GIL&lt;/a&gt;, Global Interpreter Lock, in Python says that when in effect only one thread can run at a time per Python process.&lt;/p&gt;

&lt;h3 id=&quot;how-the-gil-behaves&quot;&gt;How the GIL behaves&lt;/h3&gt;

&lt;p&gt;If the GIL is in effect, it is a &lt;a href=&quot;https://en.wikipedia.org/wiki/Lock_(computer_science)&quot;&gt;Lock&lt;/a&gt;, and only one thread can run at a time.&lt;/p&gt;

&lt;p&gt;With CPU tasks, the GIL will be in effect. If multiple CPU tasks are being run on the same Python process, the GIL will block the additional tasks if they are non yielding until one completes and the GIL is released.&lt;/p&gt;

&lt;p&gt;Yielding means non-blocking, so the use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Threads&lt;/code&gt; or the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yield&lt;/code&gt; statement in Python for example are non-blocking if the task itself doesn’t block.&lt;/p&gt;

&lt;p&gt;The GIL is released when doing I/O. I/O invokes built-in operating system C code, so the GIL is released and then reacquired when the I/O completes. This means that threads can be used in Python to improve I/O program performance.&lt;/p&gt;

&lt;p&gt;The GIL is also often released in extension code. &lt;a href=&quot;https://docs.python.org/3/c-api/init.html#releasing-the-gil-from-extension-code&quot;&gt;Here&lt;/a&gt; is more detail.&lt;/p&gt;

&lt;h3 id=&quot;separate-python-processes&quot;&gt;Separate Python processes&lt;/h3&gt;

&lt;p&gt;Each Python process has it’s own GIL managing access to it’s main thread of execution. Python processes can run in parallel and there are primitives for sharing data between processes.&lt;/p&gt;

&lt;h3 id=&quot;some-python-modules-for-multiple-threads-or-processes&quot;&gt;Some Python modules for multiple threads or processes&lt;/h3&gt;

&lt;p&gt;The &lt;a href=&quot;https://docs.python.org/3/library/threading.html&quot;&gt;threading&lt;/a&gt; module is a higher-level interface built on top of the Python’s &lt;a href=&quot;https://docs.python.org/3/library/_thread.html&quot;&gt;thread&lt;/a&gt; module. This is shown in the example below.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://docs.python.org/3/library/concurrent.futures.html&quot;&gt;concurrent.futures&lt;/a&gt; module has the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ThreadPoolExecutor&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProcessPoolExecutor&lt;/code&gt; class. With these classes, jobs are submitted to a worker pool of a given size and then executed.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://docs.python.org/3/library/subprocess.html&quot;&gt;subprocess&lt;/a&gt; module allows for the spawning of new processes. This is commonly used in testing for running independent test code in parallel.&lt;/p&gt;

&lt;h3 id=&quot;sharing-data-between-threads-or-processes&quot;&gt;Sharing data between Threads or Processes&lt;/h3&gt;

&lt;p&gt;The Python &lt;a href=&quot;https://docs.python.org/3/library/queue.html&quot;&gt;queue&lt;/a&gt; module adds this functionality. An example of using a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Queue&lt;/code&gt; to share data between threads is shown below.&lt;/p&gt;

&lt;h3 id=&quot;example-of-improved-python-performance-with-multithreaded-io&quot;&gt;Example of improved Python performance with multithreaded I/O&lt;/h3&gt;

&lt;p&gt;Here is an example of a single vs. multithreaded I/O program using the Github API to demonstrate the difference in performance.&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/aaronlelevier/cbf7d38a571ae72a0339aa0f12f88df2.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;Example output&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ python github_followers.py --username aaronlelevier
single_threaded time(sec): 4.647056104964577
multi_threaded time(sec): 1.0500583100365475
both single_threaded and multi_threaded count: 127
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;

&lt;p&gt;If you are doing Python I/O, whether it be HTTP data syncing or other I/O tasks, multithreading can be used to improve program performance.&lt;/p&gt;

&lt;p&gt;Extension code may also be used for running Python code in parallel on a single process.&lt;/p&gt;

&lt;h3 id=&quot;more-info&quot;&gt;More info&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.informit.com/articles/article.aspx?p=1850445&quot;&gt;Core Python Applications Programming - Multithreading&lt;/a&gt; by Wesley Chun&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://pyvideo.org/pycon-us-2015/python-concurrency-from-the-ground-up-live.html&quot;&gt;Python Concurrency From the Ground Up: LIVE!&lt;/a&gt; by David Beazley&lt;/p&gt;

</content>
      </entry>
     
  
    
      <entry>
        <title>Analyzing the Pandas Series Apply Method</title>
        <link href="http://www.motivatedcoder.com/analyzing-the-pandas-series-apply-method/"/>
        <updated>2018-03-04T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/analyzing-the-pandas-series-apply-method</id>
        <content type="html">&lt;p&gt;I saw the &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.apply.html&quot;&gt;Pandas.apply&lt;/a&gt; method and started thinking about this pattern and if it’d be useful to implement on other objects. Here’s a brief blog about the pattern.&lt;/p&gt;

&lt;p&gt;The general pattern outside of framework or language specifics is:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Apply an anonymous function to a value or an iterable&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;pandas-example&quot;&gt;Pandas Example&lt;/h3&gt;

&lt;p&gt;In the case of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pandas.apply&lt;/code&gt; it let’s you apply a function to each item in a iterable, which, in the case of Pandas, is each item of a single &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.html&quot;&gt;Series&lt;/a&gt; in a &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html&quot;&gt;DataFrame&lt;/a&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Series&lt;/code&gt; implements the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt; method.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;number&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]})&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;series&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;number&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;series&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;is_even&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;series&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_even&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;### OUTPUT ###
# &amp;lt;class &apos;pandas.core.series.Series&apos;&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 0    False
# 1     True
# 2    False
# 3     True
# Name: number, dtype: bool
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;python-object-instance-example&quot;&gt;Python object instance example&lt;/h3&gt;

&lt;p&gt;Can this pattern then be used with Python base class instances inheriting from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;object&lt;/code&gt;? Yes, here’s what that would look like.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;age&lt;/span&gt;
        
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
&lt;span class=&quot;n&quot;&gt;person&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;Bob&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{p.name} is {p.age}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;### OUTPUT ###
# &apos;Bob is 60&apos;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Defining the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt; method allows the &lt;a href=&quot;https://docs.python.org/3/reference/expressions.html#lambda&quot;&gt;lambda&lt;/a&gt; to be immediately returned, instead of having to assign it to a reference, then invoke it.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{p.name} is {p.age}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;### OUTPUT ###
# &apos;Bob is 60&apos;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;python-iterable-example&quot;&gt;Python iterable example&lt;/h3&gt;

&lt;p&gt;Okay, so let’s use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt; pattern with a Python iterable and see what it looks like.&lt;/p&gt;

&lt;p&gt;This code snippet subclasses the Python &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;list&lt;/code&gt; standard &lt;em&gt;type&lt;/em&gt;, which may or may not be kosher. The point is that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;type&lt;/code&gt; being subclassed just has to implement the iterable interface. This could be anything, a Django &lt;a href=&quot;https://docs.djangoproject.com/en/2.0/ref/models/querysets/&quot;&gt;QuerySet&lt;/a&gt; for example.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PersonList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__iter__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;person_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PersonList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;person&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;Bob&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;person2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;Jerry&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;person_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;person_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;person2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;person_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{p.name} is {p.age}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;### OUTPUT ###
# [&apos;Bob is 60&apos;, &apos;Jerry is 55&apos;]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s do the same using Python’s &lt;a href=&quot;https://docs.python.org/3/library/functions.html#map&quot;&gt;map&lt;/a&gt; builtin function.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;{p.name} is {p.age}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;person2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;### OUTPUT ###
# [&apos;Bob is 60&apos;, &apos;Jerry is 55&apos;]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Python &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dict&lt;/code&gt; example for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iter&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;items&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;python-iterable-example-2---dict&quot;&gt;Python iterable example #2 - dict&lt;/h3&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmployeeDict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__iter__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply_items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;employee_dict&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EmployeeDict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;manager&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;clerk&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;person2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;employee_dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;### OUTPUT ###
# [&apos;manager&apos;, &apos;clerk&apos;]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt; pattern with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dict&lt;/code&gt; items&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;employee_dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply_items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;The {}&apos;s name is {}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;### OUTPUT ###
# [&quot;The manager&apos;s name is Bob&quot;, &quot;The clerk&apos;s name is Jerry&quot;]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;summary-and-note-on-pandasapply&quot;&gt;Summary and Note on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pandas.apply&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pandas.apply&lt;/code&gt; method does a lot more than apply a lambda function. Here is the full method signature and link to the &lt;a href=&quot;https://github.com/pandas-dev/pandas/blob/master/pandas/core/series.py#L2407&quot;&gt;source&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It makes sense to do a lot more, because if your class has to defined an extra method &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apply&lt;/code&gt; when you could just be calling the builtin Python &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;map&lt;/code&gt; function, then it should be worth it.&lt;/p&gt;
</content>
      </entry>
     
  
    
      <entry>
        <title>Reusable Test Database Pattern in Django!</title>
        <link href="http://www.motivatedcoder.com/reusable-test-database-pattern-in-django/"/>
        <updated>2018-02-17T00:00:00+00:00</updated>
        <id>www.motivatedcoder.com/reusable-test-database-pattern-in-django</id>
        <content type="html">&lt;p&gt;This is a short blog post about the resusabled database pattern that I use for working on Django projects.&lt;/p&gt;

&lt;h3 id=&quot;use-case&quot;&gt;Use Case&lt;/h3&gt;

&lt;p&gt;You have a large Django project where running migrations takes in excess of 30 seconds, etc… Some undesireably long about of time. This is expensive time wise, if you are working on one test, and this is the overhead to re-run the single test each time.&lt;/p&gt;

&lt;h3 id=&quot;inspiration&quot;&gt;Inspiration&lt;/h3&gt;

&lt;p&gt;When chatting with my coworker, &lt;a href=&quot;https://github.com/approaching236&quot;&gt;@approaching236&lt;/a&gt;, he recommended looking into how to do this in Django. He said that there’s a 3rd party package in Ruby on Rails that does this and Django should be able to do the same thing. It’s been a huge win as far as speeding up how fast we iterate when testing, needless to say!&lt;/p&gt;

&lt;h3 id=&quot;solution&quot;&gt;Solution&lt;/h3&gt;

&lt;p&gt;Use The Django &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DATABASES&lt;/code&gt; configuration for a &lt;a href=&quot;https://docs.djangoproject.com/en/2.0/topics/testing/advanced/#testing-primary-replica-configurations&quot;&gt;TEST MIRROR&lt;/a&gt; database.&lt;/p&gt;

&lt;p&gt;This configuration lets you run tests against a database without having to create a test database, run all migrations, and drop the test database each time. Instead, it runs the tests on an existing database, and rolls back each transaction after each unit test method, or test class, so as not to mutate database state for unit testing, as you would expect.&lt;/p&gt;

&lt;p&gt;To use this configuration, update the Django project like so:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# myproject/settings/test.py
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DATABASES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&apos;default&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&apos;ENGINE&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;django.db.backends.postgresql_psycopg2&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&apos;NAME&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;test_db&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&apos;USER&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;username&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&apos;PASSWORD&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;password&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&apos;HOST&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;localhost&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&apos;PORT&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;5432&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&apos;TEST&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;&apos;MIRROR&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&apos;default&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To use this config, you will want to build an an empty database with the schema migrated one time. After that, migrations no longer have to be run, and unit tests can be re-run without the database migrations overhead.&lt;/p&gt;

&lt;h3 id=&quot;helper-bash-functions&quot;&gt;Helper Bash Functions&lt;/h3&gt;

&lt;p&gt;Here are some helper bash functions that I’ve found useful with the reusable database pattern. Once in a while there is leaked database state, so I usually make an initial backup after creating the initial empty database, in case that occurs, then a restore of the backup is quick.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# drop, create, migrate schema of a given database&lt;/span&gt;
migratedb &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DJANGO_SETTINGS_MODULE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;myproject.settings.test
    dropdb test_db
    createdb test_db
    ./manage.py migrate
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# create a backup of a given database&lt;/span&gt;
backupdb &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$# &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-eq&lt;/span&gt; 0 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;then
        &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;db_name not specified&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;db_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;db_name_copy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;db_name&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;_copy
        psql &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;DROP DATABASE &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$db_name_copy&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&quot;&lt;/span&gt;
        psql &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;CREATE DATABASE &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$db_name_copy&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; WITH TEMPLATE &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$db_name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# restore database from a given backup&lt;/span&gt;
restoredb &lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$# &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-eq&lt;/span&gt; 0 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;then
        &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;db_name not specified&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else
        &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;db_name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;db_name_copy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;db_name&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;_copy
        psql &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;DROP DATABASE &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$db_name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&quot;&lt;/span&gt;
        psql &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;CREATE DATABASE &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$db_name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; WITH TEMPLATE &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$db_name_copy&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</content>
      </entry>
     
  
</feed>
