<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Joao Moura</title>
    <description>Engineer Manager by day and passionate speaker that loves open source and building games and other stuff by night.</description>
    <link>http://joaomdmoura.com/</link>
    <atom:link href="http://joaomdmoura.com/feed.xml" rel="self" type="application/rss+xml" />
    
      <item>
        <title>Engineering Leadership: Balancing Technical and Managerial Responsibilities</title>
        <description>&lt;p&gt;&lt;img src=&quot;/images/posts/img19.png&quot; alt=&quot;Header&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Ah, the age-old conundrum: as an engineering leader, how do you strike the perfect balance between your technical and managerial responsibilities? Fear not, for you’re not alone in this struggle!&lt;/p&gt;

&lt;h2 id=&quot;the-great-shift-and-the-managerial-mindset&quot;&gt;The Great Shift and The Managerial Mindset&lt;/h2&gt;

&lt;p&gt;As you move up the ranks in your engineering career, it’s natural to find yourself with fewer hands-on technical tasks and more managerial duties. It’s all part of the journey, so don’t fret! But how do you navigate this transition without feeling like you’re losing your technical edge?&lt;/p&gt;

&lt;p&gt;First, understand that this balancing act is something that all managers grapple with. Many managers question if they’re becoming technically stale, but rest assured, it’s normal to feel this way. Remember that your performance as a manager is measured by the aggregate performance of your team. It’s less about &lt;em&gt;you&lt;/em&gt; and more about &lt;em&gt;enabling others&lt;/em&gt;. Your main goal is to create an environment where your team can thrive and excel.&lt;/p&gt;

&lt;p&gt;That said your ability to take informed decisions depends on having technical &lt;em&gt;context&lt;/em&gt; (what is different from technical knowledge itself), so even though you primary responsability is not technical work, there is a lot of value on acquiring technical context, especially domain-specific knowledge about the code paths your team is responsible for.&lt;/p&gt;

&lt;p&gt;As a manager, knowing every technical detail is neither realistic nor scalable. Instead, focus on understanding the broader technical landscape, and trust your team to handle the nitty-gritty.&lt;/p&gt;

&lt;h2 id=&quot;knowledge-vs-experience-and-staying-up-to-date&quot;&gt;Knowledge vs. Experience and Staying Up-to-Date&lt;/h2&gt;

&lt;p&gt;There’s a difference between technical &lt;em&gt;knowledge&lt;/em&gt; and technical &lt;em&gt;experience&lt;/em&gt;. As you progress in your managerial career, prioritize maintaining your technical experience over being an encyclopedia of technical knowledge. 
Staying up-to-date with technical changes is valuable and will help you with foward-thinking, but make sure you do so without becoming a blocker for your team or dropping the ball on other fronts. A good rule of thumb I’ve use is asking myself “is this the most impactful thing I could be doing to help my team achieve our goals”&lt;/p&gt;

&lt;h2 id=&quot;asking-the-right-questions&quot;&gt;Asking the Right Questions&lt;/h2&gt;

&lt;p&gt;Ultimately, good management is less about making the right technical decisions and more about asking the right questions. This is where your technical experience comes into play. By using your experience to guide your team, you’ll foster an environment where innovation and success can flourish.&lt;/p&gt;

&lt;p&gt;So, there you have it! The key to balancing technical and managerial responsibilities lies in understanding your role, focusing on the big picture, and leveraging your technical experience to ask the right questions. Embrace the challenge and watch your team soar! 🚀&lt;/p&gt;
</description>
        <pubDate>Tue, 11 Apr 2023 00:01:00 +0000</pubDate>
        <link>http://joaomdmoura.com/articles/2023/04/11/engineering-leadership-balancing-technical-and-managerial-responsibilities/</link>
        <guid isPermaLink="true">http://joaomdmoura.com/articles/2023/04/11/engineering-leadership-balancing-technical-and-managerial-responsibilities/</guid>
      </item>
    
      <item>
        <title>For people transitioning from Programming to Management</title>
        <description>&lt;p&gt;Management may sound boring for most developers, but as we go through our career it becomes clear that it’s a key role for a company. A good manager can make a huge difference in building great teams and awesome products.&lt;/p&gt;

&lt;p&gt;Some developers want to build new stuff and have a deep interest on the technical side of things. Others might show a great set of soft skills and care for their teammates, for those, the jump to management could be a good option.&lt;/p&gt;

&lt;p&gt;These are just some of the traits of a good manager, but when doing the jump there is much more that should be taken into account. The struggle involved in the jump is pretty real and that’s what I want to discuss in this article.&lt;/p&gt;

&lt;p&gt;Most developers struggle when moving to a managerial role, I am part of this group. But once you understand why you are struggling you can finally start to work on tools to get better at it. As I got better as a manager I started to get emails, asking me for help, and that’s what lead me to write this article, provide an easy way for future managers to understand their struggles and better deal with it.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/img18.png&quot; alt=&quot;Header&quot; /&gt;&lt;/p&gt;

&lt;p&gt;There is a bunch of reasons that make the transition to management so hard, the initial months can be a real struggle for those without experience. Understanding the issues is the initial step to handle with it, so let’s talk about some of the reasons why it feels so hard to make the jump.&lt;/p&gt;

&lt;h2 id=&quot;feedback-loop&quot;&gt;Feedback Loop&lt;/h2&gt;
&lt;p&gt;Developers are used to have short feedback loops, think about it: you can start a new task by chatting with your teammates, then you can do some pair programming, and later you’ll have a code review cycle. That is not all, depending on your team’s process you’ll have retrospectives and daily meetings.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;When transitioning to a managerial position most of that goes away. You can still ask for help, and I actually encourage you to do it, but there will be no “code reviews” nor “pair programming” on your decisions. You won’t be able to know if you are doing a good job until you let some of your decisions mature and start showing results.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can still ask for feedback and I recommend you to do it as well, if you provide the correct environment, you can get an awesome result from that. But to see the results of your actions you will need to give it some time, good results take time.&lt;/p&gt;

&lt;p&gt;Not having external validation can be a huge issue for most people, it can easily undermine one’s confidence, that’s why you need to be able to fight back.&lt;/p&gt;

&lt;p&gt;One tool I used to deal with it was having quick review notes, I wrote down the decisions I took and weeks later I’d review that, asking myself if I would take the same decision once again.&lt;/p&gt;

&lt;p&gt;Another good resource is to have other managers that you can share experiences with, in a way that you can support each other. Don’t be afraid of asking for help, most of the managers I talked with so far are always eager to help a fellow manager.&lt;/p&gt;

&lt;h2 id=&quot;fast-context-switching&quot;&gt;Fast Context Switching&lt;/h2&gt;
&lt;p&gt;As developers we are used have to laser focus into tasks for long hours, context switching is something that we are not used to, it’s always a pain to stop a task to attend a meeting or something else.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The problem is that when managing you must master context switching, it’s actually a great part of the job. Being able to go from one meeting to another, to talk about different tasks, while paying attention to it all, making sure everyone has what it needs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This requires practice, it sucks to feel lost between different topics but you must power through it. One thing that helped me was to keep notes, physical notes from topics I need to get back and dig further. I visit this notebook every day, many times a day, mostly before meetings, making sure I got everything I needed covered. Writing things down allowed me to context-switch without getting worried about forgetting things.&lt;/p&gt;

&lt;h2 id=&quot;delegating&quot;&gt;Delegating&lt;/h2&gt;
&lt;p&gt;This is hard, the good thing is that if you ever was a team/technical leader you probably have some experience with this already. For those that never had to delegate tasks this can be a huge issue to overcome. Not doing it properly can result in micromanaging and that won’t benefit anyone, you will be stressed trying to keep up with everything and your team will feel like you don’t trust them. That will also prevent them from learning from their own mistakes, and from growing.&lt;/p&gt;

&lt;p&gt;You need to take the jump. Accept that sharing responsibilities will make it easier for you to do a better job and also help your team to improve their skills.&lt;/p&gt;

&lt;h2 id=&quot;recovering&quot;&gt;Recovering&lt;/h2&gt;
&lt;p&gt;Managing can be stressful, it drains physical and mental energy. It also drains sentimental energy, yup you read it right, being responsible for other people takes a huge load on mental health, anxiety and stress can easily kick in if you don’t watch yourself.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Spare time to recovery, smile, have fun, make sure to invest in healthy relationships. These simple things can have a huge impact on your work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I tried to keep this post short, but if you’re interested in knowing more about management in general make sure to let me know over &lt;a href=&quot;https://twitter.com/joaomdmoura&quot;&gt;twitter&lt;/a&gt;. I’m always eager to help other and share experiences.&lt;/p&gt;
</description>
        <pubDate>Sun, 03 Jun 2018 00:01:00 +0000</pubDate>
        <link>http://joaomdmoura.com/articles/2018/06/03/for-people-transitioning-from-programming-to-management/</link>
        <guid isPermaLink="true">http://joaomdmoura.com/articles/2018/06/03/for-people-transitioning-from-programming-to-management/</guid>
      </item>
    
      <item>
        <title>Making Code Reviews Better</title>
        <description>&lt;p&gt;&lt;img src=&quot;/images/posts/img17.png&quot; alt=&quot;Header&quot; /&gt;&lt;/p&gt;

&lt;p&gt;How many of you are doing code reviews every day? Do you enjoy it? Is it fun? Or do you do it because you feel like you have to? I know that is a lot of questions to start an article, but I want to make a point here, so bear with me just for one more question.&lt;/p&gt;

&lt;h2 id=&quot;why-do-we-do-pr-reviews&quot;&gt;Why do we do PR reviews?&lt;/h2&gt;
&lt;p&gt;Most developers would say that we do reviews to catch bugs, but that is not it. Code review can actually be about way more than this. On pull requests, we are only seeing a part of it, essentially just a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git diff&lt;/code&gt; , so you can catch syntax errors, but we can’t see how that interacts with the rest of the system just yet, so if reviewing a PR is not about catching errors then what is it about?&lt;/p&gt;

&lt;p&gt;After a research conducted within real companies about pull requests, the three main benefits an engineering team can get out of reviewing PRs are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Knowledge Transfer&lt;/li&gt;
  &lt;li&gt;Increased Team Awareness&lt;/li&gt;
  &lt;li&gt;Finding Alternative Solutions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Code Review is the discipline of explaining and discussing your code with your peers and that goes a long way to becoming a better software engineer. It’s actually a communication resource that gives the opportunity to discuss real implementations.&lt;/p&gt;

&lt;p&gt;That’s why we need to not only prioritize it but also get better on it so we can extract its full value.&lt;/p&gt;

&lt;h2 id=&quot;getting-better-at-it&quot;&gt;Getting better at it&lt;/h2&gt;
&lt;p&gt;There are two main things you can do to help your team with code reviews, two rules of engagement, the first rule is what you can do as an Author of a pull request and the second is what you can do as a reviewer.&lt;/p&gt;

&lt;h3 id=&quot;as-an-author&quot;&gt;As an author&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;If the content is king, context is God - Gary Vaynerchuck&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This quote was about social media but it can also be applied to code reviews, if the content is your code then the context is the “Why” you are doing it.&lt;/p&gt;

&lt;p&gt;Provide context is the main thing you should do as an author of a Pull Request, not only the context behind the “Why” you’re doing that change but also any technical context that might help other folks down the road, like the techniques you used, or maybe explaining a design pattern you choose. Let the reviewer know what you have learned in the process of doing this code, that’s a great opportunity to share knowledge.&lt;/p&gt;

&lt;h3 id=&quot;as-a-reviewer&quot;&gt;As a Reviewer&lt;/h3&gt;

&lt;p&gt;The main rule for a good review process is&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Ask, don’t tell.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Feedbacks on code reviews tend to be received much more negatively than when done face to face. So we need to overcome this if we want our feedback to be received in the right way.&lt;/p&gt;

&lt;p&gt;One way of doing that is to offer compliments, I do recommend you to do it, make sure to point out the good stuff and the things you have learned from a PR.&lt;/p&gt;

&lt;p&gt;The key to overcoming the negative tone a code review can have is to ask questions instead of making demands. Questions have the power to start healthy conversations.&lt;/p&gt;

&lt;p&gt;Comments like “Extract this into its own function to avoid duplication” only provide two alternatives to the author, she either changes it or replies starting what looks like an argument. But instead, you could rephrase that for “What do you think about extracting this into its own function to avoid duplication?”, that opens up a bunch of possibilities to actually start a conversation, maybe she has thought about it already, maybe that is not possible, or maybe that is actually a good idea and she will embrace it and change the code.&lt;/p&gt;

&lt;p&gt;“What do you think about” is a great conversation opener for code reviews.&lt;/p&gt;

&lt;h2 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;Code reviews can be a great tool that can empower you and your team, but as any tool, it needs to be used properly otherwise it can make people extremely uncomfortable to pitch in their ideas and to contribute more to the codebase.&lt;/p&gt;

&lt;p&gt;Keep in mind that Code Review is so much more than finding bugs, it actually helps your company to spread knowledge and your developers to get better at their jobs.&lt;/p&gt;

&lt;p&gt;Last but not least, this article was hugely inspired by a great talk of Rails Conf 2015 called &lt;a href=&quot;https://www.youtube.com/watch?v=PJjmw9TRB7s&quot;&gt;Implementing a Strong Code-Review Culture&lt;/a&gt; so make yourself comfortable to check it as well and get more in-depth explanations and examples.&lt;/p&gt;
</description>
        <pubDate>Sun, 03 Jun 2018 00:01:00 +0000</pubDate>
        <link>http://joaomdmoura.com/articles/2018/06/03/making-code-reviews-better/</link>
        <guid isPermaLink="true">http://joaomdmoura.com/articles/2018/06/03/making-code-reviews-better/</guid>
      </item>
    
      <item>
        <title>Unboxing Data Science, Chapter II</title>
        <description>&lt;p&gt;You might have read the first chapter of this series a few days ago, the idea was to see if that was something that people were willing to check before I invested too much time into writing this, but it seems people are eager to learn more about data science e see how that is applied to real businesses and real needs.&lt;/p&gt;

&lt;p&gt;In this series, I’ll share how I tackled three different challenges and how I used data science to produce some great tools in the e-commerce project I was working back then, the challenges were:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;How can I predict how much money we will make next month?&lt;/li&gt;
  &lt;li&gt;What customers clusters we have and what defines them?&lt;/li&gt;
  &lt;li&gt;Can I predict a customer quality as it puts its first order?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this chapter, I’ll talk about the first point, how I was able to predict the e-commerce monthly revenue with a margin of error of 10%.&lt;/p&gt;

&lt;h2 id=&quot;tools&quot;&gt;Tools&lt;/h2&gt;
&lt;p&gt;For this initial challenge I used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;numpy&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pandas&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sklearn&lt;/code&gt;, we will also use two different Machine Learning algorithms, the classic &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Linear Regression&lt;/code&gt; and one way more complex called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Gradient Boosting Regressor&lt;/code&gt;, worry not, I’ll explain how each one works so bear with me.&lt;/p&gt;

&lt;p&gt;I’ll start by importing everything I need:&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;# Importing necessary libraries
&lt;/span&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;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;seaborn&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sns&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;matplotlib.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;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sklearn.linear_model&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LinearRegression&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sklearn.ensemble&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GradientBoostingRegressor&lt;/span&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;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'fivethirtyeight'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&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;'font.serif'&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;s&quot;&gt;'Ubuntu'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&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;'font.monospace'&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;s&quot;&gt;'Ubuntu Mono'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&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;'axes.labelweight'&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;s&quot;&gt;'bold'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&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;'xtick.labelsize'&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;15&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&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;'ytick.labelsize'&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;15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;assesment&quot;&gt;Assesment&lt;/h2&gt;
&lt;p&gt;Starting from an empty Jupyter notebook I poked a bit around the orders data I had.&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;# =======================================================
# Read Orders data by day
# =======================================================
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;orders&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;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'orders.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Convert datetimes to pandas datetime type
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;orders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;created_at&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;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;orders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;created_at&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;orders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;processed_at&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;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;orders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;processed_at&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;The main goal of this part was to gain some domain knowledge, understand what were the main factors that drive the revenue for a specific month, those are the factors that we want to feed into the prediction mode.&lt;/p&gt;

&lt;p&gt;The first thing that I noticed when plotting the orders by month was that there was some seasonality and that the month of the year has a huge influence on the revenue as you can see below:&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;# Getting paid Orders only.
# ============================================================
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;orders&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;orders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;orders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;paid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;orders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;canceled&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;n&quot;&gt;by_month_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;orders&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;month&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value_counts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sort_index&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ax1&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;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subplots&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;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;figsize&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;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;barplot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;by_month_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;by_month_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ax1&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;/images/posts/img8.png&quot; alt=&quot;Graph 01&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So the month of the year is definitely a data that we need to feed into our prediction model.&lt;/p&gt;

&lt;p&gt;I had only 3 years worth of data, but that was enough to check how much a month revenue correlates with all other months revenues:&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;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;statsmodels.graphics.tsaplots&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plot_acf&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ax1&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;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subplots&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;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;figsize&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;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plot_acf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;monthly_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;revenue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ax1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pyplot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;show&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;/images/posts/img11.png&quot; alt=&quot;Graph 01&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Each point on this graph indicates how much one month correlates with the other months, axis X representing all months I have, 33 months, and axis Y representing the correlation index, here we can see that a specific month has a high correlation with the point 12 and 13, that indicates that a month’s revenue is highly correlated to the same month’s revenue one year before.&lt;/p&gt;

&lt;p&gt;Basically what it means is that if you had a good revenue in January last year that might imply on a good January this year, the monthly revenue tend to follow a pattern. This means that the revenue from the same month but on the last year is another data that we need to feed into our Machine Learning model.&lt;/p&gt;

&lt;h2 id=&quot;more-data&quot;&gt;More Data&lt;/h2&gt;
&lt;p&gt;Now that I had some insight into the data I had it was time to put together other data that might have a say in predicting in predicting the revenue for a month.&lt;/p&gt;

&lt;p&gt;After some poking around I found other data that was worth having: &lt;strong&gt;The Ads Investment ($) it was planning on doing that month&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once I had all the data in hand was the time to apply to Machine Learning on it, the data I decided to use was:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Last year’s same month revenue&lt;/li&gt;
  &lt;li&gt;Last month’s revenue&lt;/li&gt;
  &lt;li&gt;$ spent on Ads for the current month&lt;/li&gt;
  &lt;li&gt;What month it is&lt;/li&gt;
  &lt;li&gt;What season it is&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;trying-linear-regression&quot;&gt;Trying Linear Regression&lt;/h2&gt;
&lt;p&gt;Known as one of the simplest ML algorithms, linear regression is pretty straightforward and rely on you having data that have a linear relationship.&lt;/p&gt;

&lt;p&gt;I spare the last 4 months of my data so that I could test my prediction model and see if it would have guessed how much the revenue would be for those.&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;test_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;final_data&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;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;final_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;final_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;drop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;final_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;feature_cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;final_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;revenue&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;linreg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LinearRegression&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;linreg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit&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;n&quot;&gt;y&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;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ax1&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;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subplots&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;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;figsize&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;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;feature_cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;revenue&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ndf&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;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;linreg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predict&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;n&quot;&gt;ndf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'estimates'&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;values&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ndf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'difference'&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;ndf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimates&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ndf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;revenue&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ndf&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ndf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'bar'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ax1&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;/images/posts/img12.png&quot; alt=&quot;Graph 01&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The prediction was okay, but it wasn’t as effective as I wanted it to be, in some months, like November it missed by more than 30%, and that wasn’t as helpful as I needed it to be taking into account we wanted to use this intel to better prepare ourselves, to be more proactive than reactive in terms of the business in general.&lt;/p&gt;

&lt;p&gt;So I decided I needed a better ML (Machine Learning) model that could better capture the relationships between the data that I had.&lt;/p&gt;

&lt;h2 id=&quot;trying-gradient-boosting-regressor&quot;&gt;Trying Gradient Boosting Regressor&lt;/h2&gt;
&lt;p&gt;I decided I needed a model that could capture more complex relationships other than linear, and while looking for it I learned about the Gradient Boosting Regressor, it seemed awesome, but the issue is that it’s based on Decision Trees, and Decision Trees are good on predicting values that it already knows, but there is no way it could predict a value it has not yet seen, and that was exactly the case because we as an e-commerce startup were going through a huge growth so our numbers kept growing as well, and it would be impossible for the algorithm to predict a revenue higher than the ones it has already seen.&lt;/p&gt;

&lt;p&gt;So that is when I learned about how to deal with trends and use a method called Random Walk. First, let’s check the trend over the past years of data:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/img13.png&quot; alt=&quot;Graph 01&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P.S. the drop on the end of the chart is because it was missing the how of the last month worth of data.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This chart shows a trend in the number of orders, the same trend occurs on the revenue and the fact that we are always increasing the revenue is what makes it hard for us to use a Decision-Tree-based model, but what if instead of estimating the revenue we could estimate another value that is kept under a range? You got it, instead of estimating the revenue we can estimate the difference between the current monthly revenue and the same month’s revenue from the year before.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/img14.png&quot; alt=&quot;Graph 01&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As you can see the difference is kept under a usual range, sometimes more and some less but within a range and that enables us to use a Decision-Tree-based model, so all we have to do is to estimate the difference and then sum it up with the revenue from the same month one year before.&lt;/p&gt;

&lt;p&gt;Once I’ve trained the model this is the results I got for the same 4 last months of the year:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P.S. there was some tunning to figure out the best number of trees and the maximum depth of each tree.&lt;/em&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;f&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;ax1&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;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subplots&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;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;figsize&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;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&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;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;final_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;feature_cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;final_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;revenue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;final_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;last_year_same_month_revenue&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;X_test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;feature_cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ndf&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;n&quot;&gt;test_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;revenue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;params&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;'n_estimators'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1540&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'max_depth'&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;est&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GradientBoostingRegressor&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;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit&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;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ndf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'estimates'&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;est&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_test&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;test_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;last_year_same_month_revenue&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ndf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'difference'&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;ndf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;estimates&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ndf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;revenue&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plot&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ndf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'bar'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ax1&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;/images/posts/img15.png&quot; alt=&quot;Graph 01&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here is a comparative on how it predicts better when compared to a just simple linear regression, check how close the GradientBoostRegressor algorithm + Random Walk got when compared with the Linear regression.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/img16.png&quot; alt=&quot;Graph 01&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As you can see the new algorithm performed way better and is still live in production producing results within a margin of error of 10%.&lt;/p&gt;

&lt;p&gt;Once I had the prediction model it was only a matter of exporting it and making it an API so that I could integrate it with an dashboard.&lt;/p&gt;

&lt;p&gt;This way the business can now predict the next month revenue and properly prepare for it.&lt;/p&gt;

&lt;h2 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h2&gt;

&lt;p&gt;I hope you have liked this article I tried to not make it too technical while also sharing some code so you can try out some cool stuff on your side as well, I’m not sure if I will be able to share all the code involved because of confidentiality concerns but I’ll make sure to share as much as I can.&lt;/p&gt;

&lt;p&gt;If you liked this chapter make sure to let me know on &lt;a href=&quot;https://twitter.com/joaomdmoura&quot;&gt;Twitter&lt;/a&gt;, it makes a huge difference getting me pumped and willing to write more about it.&lt;/p&gt;

&lt;p&gt;On the next chapter, I’ll talk about the second challenge: What customers clusters we have and what defines them?&lt;/p&gt;
</description>
        <pubDate>Sat, 02 Jun 2018 00:01:00 +0000</pubDate>
        <link>http://joaomdmoura.com/articles/2018/06/02/unboxing-data-science-chapter-ii/</link>
        <guid isPermaLink="true">http://joaomdmoura.com/articles/2018/06/02/unboxing-data-science-chapter-ii/</guid>
      </item>
    
      <item>
        <title>Unboxing Data Science, Chapter I</title>
        <description>&lt;p&gt;Back when I was a teenager I learned a valuable lesson from my father that I kept with me through my career:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Never settle for untapped potential.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I can’t stress this enough, untapped potential freaks the shit out of me, I’m not only talking about personal potential but also businesses potential. With that as a guide I always tried to make sure that whatever project I’m working on, it should be enabling the people and business behind to use its full potential. And that is the kind of thought the made interested in Data Science.&lt;/p&gt;

&lt;p&gt;Learning data science can be a pain for newcomers, and I believe the reason behind it is the lack of understanding the possibilities of using data science, for me that was a crucial turning point on passing the initial learning curve, understanding what value I could extract from it and how exactly I could use it.&lt;/p&gt;

&lt;p&gt;My plan is for this article to be an initial kick off on a new series of articles I’m calling Unboxing Data Science, still deciding if I this is something I should invest the time into writing, so If you want to see it through let me know over &lt;a href=&quot;https://twitter.com/joaomdmoura&quot;&gt;twitter&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;getting-started&quot;&gt;Getting started&lt;/h2&gt;
&lt;p&gt;I was working on an e-commerce and that was growing like crazy, revenue was going great but that was starting to raise some issues like, “How much money are we making next month” or “Should we prepare more inventory”, these are really important questions and put a business into reactive mode instead of a proactive mode.&lt;/p&gt;

&lt;p&gt;That’s when I first decided to learn data science. Data science is all about prediction, you wanna try to build a model that will predict an outcome based on other data, so I decided that my first challenge would be to create a prediction model for the next month revenue.&lt;/p&gt;

&lt;h2 id=&quot;the-stack&quot;&gt;The Stack&lt;/h2&gt;
&lt;p&gt;For this series, we will use Python, a Jupyter Notebook and a few libraries like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;panda&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;numpy&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scikit-learn&lt;/code&gt;, we won’t use it all in this first article, but you will need to install Python 3 and Jupyter, an easy way to get all your environment ready is to &lt;a href=&quot;https://www.anaconda.com/download&quot;&gt;download Anaconda&lt;/a&gt;, it will install all dependencies we need at once.&lt;/p&gt;

&lt;p&gt;From Anaconda you can easily launch Jupyter and create your first notebook, I won’t dive into the details of that because it’s pretty straightforward and there are a ton of help online already.&lt;/p&gt;

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

&lt;p&gt;Because of the stack we are going to use, the easiest way to consume data is in the form of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.csv&lt;/code&gt; file and that is exactly what I used, first I downloaded a dump and converted that into a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.csv&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;As you learn data science you’ll realize that the key difference between building a great model is the data that you have and the new data you generate from it. That together with domain knowledge is key to build great models. In my case, I had all the data I need right in front of me, 3 years of orders histories right there in the e-commerce’s database, so I started poking it a bit first checking the number of orders by month.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/img8.png&quot; alt=&quot;Graph 01&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That’s when we start to see some patterns, it’s clear that the sales build up on the lasts months of the year, so we can definitely see how the month itself impact the revenue therefore that is something we need to take into account on our model.&lt;/p&gt;

&lt;p&gt;We can also see this pattern by season:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/img9.png&quot; alt=&quot;Graph 02&quot; /&gt;&lt;/p&gt;

&lt;p&gt;All that translates into data that we can use down the road when building our model. Another crucial component for me was to check if there is a trend for the revenue, that was key for me down the road as well:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/img10.png&quot; alt=&quot;Graph 03&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here we can see how as the time goes by the sales tend to grow, and that makes measuring future revenue even more crucial for the business itself.&lt;/p&gt;

&lt;h2 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;Wanna know more about how I solve this and get deeper into learning Data Science and Machine Learning? If you do, let me know, I’m trying to decide if this series is something I should invest my time in producing and getting feedback is crucial for me to take this decision, you can do that through &lt;a href=&quot;https://twitter.com/joaomdmoura&quot;&gt;my twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If that gets enough traction I’ll write the next article now getting technical and showing how I not only built this initial charts but also the next steps I took after that.&lt;/p&gt;
</description>
        <pubDate>Fri, 01 Jun 2018 00:01:00 +0000</pubDate>
        <link>http://joaomdmoura.com/articles/2018/06/01/unboxing-data-science-chapter-i/</link>
        <guid isPermaLink="true">http://joaomdmoura.com/articles/2018/06/01/unboxing-data-science-chapter-i/</guid>
      </item>
    
      <item>
        <title>I'm Joining Toptal</title>
        <description>&lt;p&gt;Hey folks, I’m joining &lt;a href=&quot;https://www.toptal.com/&quot;&gt;Toptal&lt;/a&gt; as Engineering Manager, and I’m super excited about it, also really excited to finally share this with you all!&lt;/p&gt;

&lt;p&gt;For those that doesn’t know, &lt;a href=&quot;https://www.toptal.com/&quot;&gt;Toptal&lt;/a&gt; is a network of freelancers that have the top software developers, designers, and finance experts on their pool. They are well known among developers and have a pretty challenging interview process.&lt;/p&gt;

&lt;p&gt;I’m super thankful about the work I was able to do in the past years, had awesome opportunities, from being the CTO of a mid-sized Brazilian startup, to making the jump to the international market and working remotely for amazing startups both in NY and SF.&lt;/p&gt;

&lt;p&gt;I had the opportunity to lead remote teams and also did a bunch of stuff I was really interested about, from learning and using Elixir as my main programming language, what I did for almost 3 years (currently writing a book about it), to doing an specialization on Data Science and using it in the real world.&lt;/p&gt;

&lt;p&gt;While doing all that I had the opportunity to meet a ton of awesome people and talk on great events.&lt;/p&gt;

&lt;p&gt;Through it all I always counted on my habilities to help and interact with people, that made a key difference on my carrier in general and prepared me to tackle different challenges.&lt;/p&gt;

&lt;p&gt;A few months ago I decided I was familiar enough with the processes of working remotely so that I could go back to a more managerial role, where I can add more value and help other people to tackle the challenges they are facing, while they are shaping their careers.&lt;/p&gt;

&lt;p&gt;That was my main motivation on joining Toptal, knowing that the have really talented people and a ton of awesome challenges to tackle.&lt;/p&gt;
</description>
        <pubDate>Thu, 01 Mar 2018 00:01:00 +0000</pubDate>
        <link>http://joaomdmoura.com/articles/2018/03/01/i-m-joining-toptal/</link>
        <guid isPermaLink="true">http://joaomdmoura.com/articles/2018/03/01/i-m-joining-toptal/</guid>
      </item>
    
      <item>
        <title>Building a Mobile App with Ember + Cordova + Rails</title>
        <description>&lt;p&gt;You wanna build that great side project you have been thinking about, but you have never built a mobile app before, fear not my friend, bear with me through this article and you will be amazed about how fast you can take your idea of the ground.&lt;/p&gt;

&lt;p&gt;I did write an article in the past about building mobile apps with ember and Cordova, maybe you even read it already, that was a gentle quick off on how to quickly build an app, so I decided to write a new and better version of it.&lt;/p&gt;

&lt;h2 id=&quot;the-stack&quot;&gt;The Stack&lt;/h2&gt;
&lt;p&gt;For this article we will be using Ember, Cordova and Rails, you might be wondering why, the reason in simple, because that is the fastest stack to build an mobile app I’ve tried in the past years.&lt;/p&gt;

&lt;p&gt;I’ve done native, react, ionic, I have tried it all, but this combo still is the fastest one to develop in. Keep in mind that I’m a believer of the “move fast and break things” mantra, and that the main goal here is to spin off an idea out of the ground, not necessarily achieve the best performance. This stack will put you in that sweet spot of building something fast, using tech that you might already know, and avoid boilerplate code.&lt;/p&gt;

&lt;h2 id=&quot;installing&quot;&gt;Installing&lt;/h2&gt;
&lt;p&gt;Start by installing the tools we will use, I won’t spent much time explaining this, there is a bunch of great guides around.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Postgres&lt;/li&gt;
  &lt;li&gt;Ember.js - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;npm install -g ember-cli&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Cordova - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;npm install -g cordova&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Corber - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;npm install -g corber&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Rails (Assuming you have Ruby installed) - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gem install rails&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;creating-the-application&quot;&gt;Creating the Application&lt;/h2&gt;
&lt;p&gt;In this article we will create a product listing app, that will be fed by an Rails API, with a simple CRUD admin.&lt;/p&gt;

&lt;p&gt;Let’s start but creating a new ember application and initiating &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;corber&lt;/code&gt;&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;ember new my_freaking_awesome_app
&lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;my_freaking_awesome_app
corber init
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Corber will guide you through its setup process, letting you choose the platforms you want (iOS, Android, or both).&lt;/p&gt;

&lt;p&gt;Now we have a brand new ember app to star to work with, if you want to fully understand ember you can check its guides, but for now we will use two of the ember “features”, routes and a components.&lt;/p&gt;

&lt;p&gt;Let’s start by making sure our app shows its awesome name on its first view, go to the file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app/templates/application.hbs&lt;/code&gt;, remove the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{{welcome-page}}&lt;/code&gt; and add the proper title before the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{{outlet}}&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-html 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;nt&quot;&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Freaking Awesome App&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
{{outlet}}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;creating-a-route&quot;&gt;Creating a Route&lt;/h2&gt;
&lt;p&gt;Now let’s create an route for our app, for the sake of this article lets say our awesome app is a shop list, with a list of products we need to buy on our next run to the groceries store, so lets start by creating an route to show the products we need.&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;ember generate route products
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Open the new generated template at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app/templates/products.hbs&lt;/code&gt; and add a proper title to it:&lt;/p&gt;

&lt;div class=&quot;language-html 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;nt&quot;&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Products&lt;span class=&quot;nt&quot;&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
{{outlet}}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s make this our root route, so update the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;router.js&lt;/code&gt; to define that:&lt;/p&gt;

&lt;div class=&quot;language-javascript 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;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;EmberRouter&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;@ember/routing/router&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;./config/environment&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Router&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;EmberRouter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;locationType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;rootURL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;rootURL&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;Router&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&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;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;products&lt;/span&gt;&lt;span class=&quot;dl&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;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// &amp;lt;- This is it!&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Router&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;running-our-app&quot;&gt;Running our App&lt;/h2&gt;
&lt;p&gt;Let’s first run our app on the browser so we can check how it’s looking so far before compiling it to our phones. To do it just run:&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;ember serve
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now you should be able to access &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://localhost:4200&lt;/code&gt; on your favorite browser and see how it’s looking so far.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/img6.png&quot; alt=&quot;State Machine&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;create-a-component&quot;&gt;Create a Component&lt;/h2&gt;
&lt;p&gt;Now let’s create our first component, that will hold our product list:&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;ember generate component product-list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can open our component template at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app/templates/components/product-list.hbs&lt;/code&gt;
Let’s add a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loop&lt;/code&gt; to show all of our products. Replace the content of the template with:&lt;/p&gt;

&lt;div class=&quot;language-html 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;nt&quot;&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  {{#each products as |product|}}
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
      {{product.name}}
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  {{/each}}
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now lets go back to our template for the products route at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app/templates/products.hbs&lt;/code&gt; and load our new product list component in there replacing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{{outlet}}&lt;/code&gt; with:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{{product-list products=model}}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we need to define the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;model&lt;/code&gt;, on the route itself, and feed that with our Rails API.&lt;/p&gt;

&lt;h2 id=&quot;create-product-model&quot;&gt;Create Product Model&lt;/h2&gt;
&lt;p&gt;Let’s use the ember generator to create the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Product&lt;/code&gt; model on ember’s side.&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;ember generate model product name:string
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With our model created, now we can set it to find all products on the product router we created before, just create a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;model&lt;/code&gt; function at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app/routes/products.js&lt;/code&gt; like bellow:&lt;/p&gt;

&lt;div class=&quot;language-javascript 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;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Route&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;@ember/routing/route&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Declare the function bellow, its simply getting all products (that will come from rails)&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;model&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;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;store&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;findAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;dl&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;h2 id=&quot;integrating-ember-with-rails&quot;&gt;Integrating Ember with Rails&lt;/h2&gt;
&lt;p&gt;Now we need to set an adapter that will properly tell our ember app to call the rails app whenever looking for products.&lt;/p&gt;

&lt;p&gt;Let’s start by creating an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Adapter&lt;/code&gt;, that will inherit one of the existing ember adapters.&lt;/p&gt;

&lt;p&gt;Create a new folder &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;adapters&lt;/code&gt; under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app&lt;/code&gt; and a file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;application.js&lt;/code&gt; inside of it with the following content&lt;/p&gt;

&lt;div class=&quot;language-javascript 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;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DS&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;ember-data&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;RESTAdapter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;https://ember-app-article.herokuapp.com/&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Address of our rails app, link to the rails app&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;buildURL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;suffix&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;c1&quot;&gt;// hack to mount the url correctly to our case&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;suffix&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;nx&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.json&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&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;h2 id=&quot;create-rails-app&quot;&gt;Create Rails App&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Disclaimer: In case you want to skip this, you can use an application I already created for it online at https://ember-app-article.herokuapp.com/&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is meant to be pretty straightforward, you can learn more about rails on its website and on other great tutorials, I’ll assume you have installed all you need, so lets just open a new terminal and create a new application:&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;rails new product_list_admin &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; postgresql
&lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;product_list_admin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now let’s create a scaffold for our products by using rails generators and running migrations:&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;rails g scaffold product name:string
rake db:create
rake db:migrate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now you can start your rails application by running:&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;rails server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And you will be able to see our new products management interface at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://localhost:3000/products&lt;/code&gt;. Through this interface you are able to add new products to your list.&lt;/p&gt;

&lt;p&gt;Now we need to make sure the Rails app is ready to accept calls from the ember app, so lets add rack-cors to our project and enable it to accept calls from our ember app.&lt;/p&gt;

&lt;h3 id=&quot;enabling-cors&quot;&gt;Enabling Cors&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: This would allow your app to receive requests from any other address and isn’t the safest option, recommend you to understand CORS better before using this in production.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rack-cors&lt;/code&gt; to your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-ruby 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;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'rack-cors'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Update your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;config/application.rb&lt;/code&gt; to include the following:&lt;/p&gt;

&lt;div class=&quot;language-ruby 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;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;middleware&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;insert_before&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;no&quot;&gt;Rack&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Cors&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;allow&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;origins&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'*'&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;resource&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'*'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:any&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:methods&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:options&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;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;updating-products-controller&quot;&gt;Updating Products Controller&lt;/h3&gt;

&lt;p&gt;Because ember expects us to send the products in a specific format we will need to do a quick update on our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProductsController&lt;/code&gt; to make sure we return a root node on the JSON response.&lt;/p&gt;

&lt;p&gt;Just update your index function on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProductsController&lt;/code&gt; to the following:&lt;/p&gt;

&lt;div class=&quot;language-ruby 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;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;index&lt;/span&gt;
  &lt;span class=&quot;vi&quot;&gt;@products&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;all&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;respond_to&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&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;nf&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;render&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:index&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;nf&quot;&gt;json&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;render&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;json: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;products: &lt;/span&gt;&lt;span class=&quot;vi&quot;&gt;@products&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;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This just makes sure whenever returning the JSON version of the index route it will have a root node product.&lt;/p&gt;

&lt;h2 id=&quot;deploy-rails-app&quot;&gt;Deploy Rails App&lt;/h2&gt;
&lt;p&gt;I won’t spend much time explaining the ins and outs of deploying a rails app, but I do recommend you to deploy it in heroku for now, just for the sake of simplicity. &lt;strong&gt;Also make sure to update the ember adapter we declared before with the url for your deployed rails app.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;compile-our-app&quot;&gt;Compile our app&lt;/h2&gt;
&lt;p&gt;If you run your ember app and rails app you will now notice your products will appear on the ember app, and you can add and edit them over on your rails app.&lt;/p&gt;

&lt;p&gt;Let’s compile and test our app on a simulator. Depending on the platform you are building for (android or iOS) you will need to install different stuff, I won’t go over it all, but basically you will need Android Studio or Xcode (only Mac), I’ll assume you have installed it already, so go into your ember project folder you can run.&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;corber build &lt;span class=&quot;nt&quot;&gt;--environment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;production &lt;span class=&quot;nt&quot;&gt;--platform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ios
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once that is compiled you can then open the project on Andoird Studio or Xcode by running:&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;corber open
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;From there you can build that on a simulator or on your on phone, this is how our awesome app should look like:&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/images/posts/img7.png&quot; alt=&quot;app iphone&quot; width=&quot;450&quot; /&gt;
&lt;/p&gt;

&lt;h2 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;This was supposed to be more of a hands on approach to quickly building mobile apps using overall web knowledge, I invite you to understand how Ember and Rails works better, so you can start to take more advantage of these framework as you build your apps.&lt;/p&gt;

&lt;p&gt;If you liked this article please let me know over twitter, my handle is &lt;a href=&quot;https://twitter.com/joaomdmoura&quot;&gt;joaomdmoura&lt;/a&gt;, and I’m always eager o engage in nice conversations.&lt;/p&gt;
</description>
        <pubDate>Fri, 02 Feb 2018 00:01:00 +0000</pubDate>
        <link>http://joaomdmoura.com/articles/2018/02/02/building-a-mobile-app-with-ember-cordova-rails/</link>
        <guid isPermaLink="true">http://joaomdmoura.com/articles/2018/02/02/building-a-mobile-app-with-ember-cordova-rails/</guid>
      </item>
    
      <item>
        <title>State Machine in Elixir with Machinery</title>
        <description>&lt;p&gt;State machines are a well defined concept that developers all around have been using, some without even knowing it.&lt;/p&gt;

&lt;h2 id=&quot;finite-state-machines&quot;&gt;Finite State Machines&lt;/h2&gt;
&lt;p&gt;Finite state machines are basically a control flow, a sequence of states and a define set of rules about the transitions between those states.&lt;/p&gt;

&lt;p&gt;One of the best examples of that are shopping carts, it has pretty well defined states, and a set o triggers to transition it from one state to another.&lt;/p&gt;

&lt;p&gt;Let’s check an example bellow:
&lt;img src=&quot;/images/posts/img3.png&quot; alt=&quot;State Machine&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As detailed on the imagine above we can see a set of defined states:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Empty&lt;/li&gt;
  &lt;li&gt;Filled&lt;/li&gt;
  &lt;li&gt;Payed&lt;/li&gt;
  &lt;li&gt;Abandoned&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each transition is triggered by a specific function, but there is even more into it, some transitions can trigger other callbacks, or even have guard conditions, let’s see how that looks once we put it all together:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/img4.png&quot; alt=&quot;State Machine&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Okay, that escalated quickly. As you can see, once you include the callbacks (green) and the guard conditions (blue) the logic starts to get more complex and the code can start to get messy.&lt;/p&gt;

&lt;p&gt;After an initial implementation, as the state machines gets more complex, some logic will probably start to be split and fall all over the place, there will be callbacks on controllers, some as private functions some not, maybe some guard conditions will end up as validations on models, well you can get the whole picture, it’ll soon became unsustainable to keep extending it. Some other developers might go another routes and just put it all on the model, what some might consider an even worse bad smell.&lt;/p&gt;

&lt;p&gt;So the question remains: how to implement useful state machines on Elixir without a bunch o boilerplate and/or messy code?&lt;/p&gt;

&lt;h2 id=&quot;machinery&quot;&gt;Machinery&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/joaomdmoura/machinery&quot;&gt;Machinery&lt;/a&gt; is an open source library I’ve been working on the last months, it’s a thin State Machine library that integrates with Phoenix out of the box, but you can use it in any Elixir application, even not a Phoenix one.&lt;/p&gt;

&lt;p&gt;It’s just a small layer that provides a DSL for declaring states, having guard clauses and callbacks for structs in general. It also has (when implemented with Phoenix) an optional build-in GUI that will represent each resource’s state.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/joaomdmoura/machinery&quot;&gt;Machinery&lt;/a&gt; is built to work with any structs and also offer you the ability to have different states machines.&lt;/p&gt;

&lt;h2 id=&quot;how-to-use-it&quot;&gt;How to use it&lt;/h2&gt;
&lt;p&gt;The package can be installed by adding machinery to your list of dependencies in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mix.ex&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-elixir 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;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deps&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&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;ss&quot;&gt;:machinery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;~&amp;gt; 0.12.1&quot;&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;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Be sure to also add a new field to the struct that will have the state, you want to make sure that is a string.
If you have a Phoenix app it will involve create a new migration and changing the model accordingly.&lt;/p&gt;

&lt;h3 id=&quot;declaring-states--transitions&quot;&gt;Declaring States &amp;amp; Transitions&lt;/h3&gt;
&lt;p&gt;After that, you can create a new module to hold your state machine logic, in there you will declare your states, valid transitions, callbacks and guard conditions.&lt;/p&gt;

&lt;p&gt;You will later down the road pass this module as an argument to be used when changing states.&lt;/p&gt;

&lt;div class=&quot;language-elixir 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;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;YourProject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;UserStateMachine&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Machinery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# The first state declared will be considered&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# the initial state&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;states:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;created&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;partial&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;complete&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;transitions:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;created&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;partial&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;complete&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;partial&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;completed&quot;&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;transitioning-to-new-state&quot;&gt;Transitioning to new state&lt;/h3&gt;
&lt;p&gt;After having that in place you can transition state from anywhere on your application using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Machinery.transition_to/3&lt;/code&gt;, it expects three arguments:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The struct that holds the state&lt;/li&gt;
  &lt;li&gt;The state machine module we just declared&lt;/li&gt;
  &lt;li&gt;The state we want to transit it to&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-elixir 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;no&quot;&gt;Machinery&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transition_to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;your_struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;UserStateMachine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;next_state&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# {:ok, updated_struct}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That is just the initial implementation, let’s not forget that you can still declare the callbacks and guard functions, let’s check how to implement those using machinery.&lt;/p&gt;

&lt;h3 id=&quot;guard-functions&quot;&gt;Guard Functions&lt;/h3&gt;
&lt;p&gt;Guard functions or guard conditions, are functions that you can declare inside your state machine module, it’s expected to return a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boolean&lt;/code&gt; value, if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; it will let the transition occur and if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;false&lt;/code&gt; it’ll block it.&lt;/p&gt;

&lt;p&gt;As you might notice, you should use the second argument to pattern match what state you want to guard.&lt;/p&gt;

&lt;div class=&quot;language-elixir 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;# Guard the transition to the &quot;complete&quot; state.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;guard_transition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;complete&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:missing_fields&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;no&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;before-and-after-callbacks&quot;&gt;Before and after callbacks&lt;/h3&gt;
&lt;p&gt;Before and after callbacks are pretty straightforward, you should declare it inside the state machine module as well, it’ll execute any code inside this function before or after the transitions occurs, it’ll receive the struct as argument and it’s expected to return the struct back.&lt;/p&gt;

&lt;p&gt;Here as well, you should use the second argument to pattern match into what state transition you need to trigger the callbacks.&lt;/p&gt;

&lt;div class=&quot;language-elixir 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;# callbacks should always return the struct.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;before_transition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;complete&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;after_transition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;complete&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;persisting-state&quot;&gt;Persisting state&lt;/h3&gt;
&lt;p&gt;Keep in mind that Machinery won’t update your database automatically, but it can if you tell it how (because that may depend on what you’re using to store your data). The way you are expected to do it it through a function called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;persist/2&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;persist/2&lt;/code&gt; should always return the updated struct.&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-elixir 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;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;YourProject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;UserStateMachine&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;YourProject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Accounts&lt;/span&gt;

  &lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Machinery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;states:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;created&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;complete&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;transitions:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;created&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;complete&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;n&quot;&gt;persist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state_you_are_transiting_to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Updating a user on the database with the new state.&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&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;no&quot;&gt;Accounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update_user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;struct&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;ss&quot;&gt;state:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state_you_are_transiting_to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Returning the User struct as it should.&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;the-shopping-cart-flow&quot;&gt;The shopping cart flow&lt;/h2&gt;
&lt;p&gt;Let’s check a real case scenario and implement the initial cart behavior described on the flow charts I shared earlier and see how that would look like:&lt;/p&gt;

&lt;div class=&quot;language-elixir 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;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;FakeProject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;ShoppingCartMachine&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# We start by declaring all states and &lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# each permitted transition.&lt;/span&gt;
  &lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Machinery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;states:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;empty&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;filled&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;payed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;abandoned&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;transitions:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;empty&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;  &lt;span class=&quot;s2&quot;&gt;&quot;filled&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;filled&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;payed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;abandoned&quot;&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;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;guard_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;filled&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Check if there is enough of this item in stock&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# it returns a boolean, if true it will move on with&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# the transition, if false, it'll block it and keep&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# the previous state&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_stock?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&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;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;guard_function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;payed&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Check if payment is received and return boolean&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# if it returns true the transition will be allowed&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# to happen&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Payment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cart&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;ss&quot;&gt;:confirmed&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;before_transition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;filled&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# A transition callback that will perform an action,&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# in this case right before the transition occurs,&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# locking the items on a cart to prevent another&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# customer from adding it if there is not enough stock.&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lock_form_cart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cart&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;after_transition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;abadonned&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# An after transition callback, it's used to perform&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# an action after a transition.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# In this case Unlocking the items on the cart just &lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# moved to the abandoned state.&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unlock_form_cart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cart&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And there it is, we have a simple and straightforward implementation of a state machine, using callbacks and guard functions with a nice and readable DSL.&lt;/p&gt;

&lt;p&gt;Now we can easily create transition it from one state to another making sure all guard and callbacks functions are properly handled.&lt;/p&gt;

&lt;h2 id=&quot;bonus-dashboard-for-your-state-machine&quot;&gt;BONUS: Dashboard for your State Machine&lt;/h2&gt;
&lt;p&gt;If you’re using Phoenix and want a visual dashboard representing your state machine (its states and each resource), you can easily have it. It will also enable you to change states by dragging it from one state to another. (pretty much like Trello)&lt;/p&gt;

&lt;p&gt;This is how it looks like:
&lt;img src=&quot;/images/posts/img5.gif&quot; alt=&quot;State Machine&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To enable the Machinery Dashboard all you need is to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Add the plug &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Machine.Plug&lt;/code&gt; to you &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Endpoint&lt;/code&gt; module.
```elixir
defmodule YourApp.Endpoint do
  # …&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;# It accepts the path you want to mount the dashboard at as an argument,
  # it will mount it under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/machinery&lt;/code&gt; as default.
  plug Machinery.Plug
  # plug Machinery.Plug, ‘/my-custom-route’&lt;/p&gt;

&lt;p&gt;# …
end&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. Add the proper config to `config.mix`
- **interface:** a flag to enable the dashbord.
- **repo:** your app's repo module.
- **model:** the model that will hold the state.
- **module:** the machinery module where you have the declared states.
- *(Optional)* **dashboard_states:** A list of the states you want on the dashboard.

```elixir
config :machinery,
  interface: true,
  repo: YourApp.Repo,
  model: YourApp.User,
  # Optinal: dashboard_states: [&quot;created&quot;, &quot;partial&quot;],
  module: YourApp.UserStateMachine
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s it, now you can start you Phoenix app and navigates to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://localhost:4000/machinery&lt;/code&gt;, or whatever custom routes you have mounted the dashboard at.&lt;/p&gt;

&lt;h2 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;I hope you have liked the article and have fully understood what is a state machine, how it works, and how you can easily build one into your elixir project using machinery, even if it isn’t a Phoenix app.&lt;/p&gt;

&lt;p&gt;I’d love to hear a feedback from you, so please let me know on the comments bellow and over &lt;a href=&quot;https://twitter.com/joaomdmoura&quot;&gt;twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also check and help the Machinery project by checking it on &lt;a href=&quot;https://github.com/joaomdmoura/machinery&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Tue, 02 Jan 2018 00:01:00 +0000</pubDate>
        <link>http://joaomdmoura.com/articles/2018/01/02/state-machine-in-elixir-with-machinery/</link>
        <guid isPermaLink="true">http://joaomdmoura.com/articles/2018/01/02/state-machine-in-elixir-with-machinery/</guid>
      </item>
    
      <item>
        <title>Learn Elixir with a Rubyist, episode VII</title>
        <description>&lt;h2 id=&quot;processes-communication&quot;&gt;Processes Communication&lt;/h2&gt;
&lt;p&gt;Hey folks, I wonder how many of you have read all episodes so far, if you are one of them please shout out to me on &lt;a href=&quot;https://twitter.com/joaomdmoura&quot;&gt;twitter&lt;/a&gt;, I’d love to have some feedback :)&lt;/p&gt;

&lt;p&gt;This is a series of short bar-like conversations around Elixir and its features, it aims to help you to wrap your head around it by using meaningful examples and putting it in the context of real world problems.&lt;/p&gt;

&lt;p&gt;If you haven’t yet, you probably should check the last episodes, I’ve been writing this in a logical sequence that makes it way easier to understand by gracefully increasing the complexity of the topics and examples:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-i&quot;&gt;Episode I - Elixir, Pipe Operator and Pattern Matching&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-ii&quot;&gt;Episode II - Actor Model, Modules and functions&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-iii&quot;&gt;Episode III - Maps, Functions + Pattern Matching = ❤️&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-iv&quot;&gt;Episode IV - Elixir Types, Data Structures and Underscore&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-v&quot;&gt;Episode V - Concurrency, Processes and Recursion&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-vi&quot;&gt;Episode VI - Head + Tail and List Comprehension&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-vii&quot;&gt;Episode VII - Processes Communication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;processes-communication-1&quot;&gt;Processes Communication&lt;/h2&gt;
&lt;p&gt;We have talked a lot about processes on other episodes, not only how they work but also how they are a key component of Elixir, something it inherited from Erlang, and a core piece to extract the most out of the language capabilities.&lt;/p&gt;

&lt;p&gt;On &lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-ii&quot;&gt;Episode II - Actor Model, Modules and functions&lt;/a&gt; we talked about Actor Model, a known architecture that was used on the implementation of Erlang VM, it enables processes to be totally isolated from each other, not sharing any context, and by doing so, it actually makes easier to share specific information between processes, but in a organized way, by exchanging messages.&lt;/p&gt;

&lt;p&gt;Every process in Erlang (and therefore in Elixir as well) is considered an Actor, completely isolated from its pears, a single processes might be related to other processes, like Supervisors, or linked processes (we’ll talk about that in a near future), but it does not share the same context and variables with other processes.  &lt;/p&gt;

&lt;p&gt;Every process also has what you could imagine as an empty mailbox, just waiting for messages, and you can program your processes to respond to those messages depending on their content. You can also make your process send messages to others by using an identifier,  a process ID, what we call PID (Process Identifier).&lt;/p&gt;

&lt;p&gt;This alone can sound silly, but having this ability is a huge deal and enables you to do a lot of fun stuff you wouldn’t do in other non-functional languages like Ruby.&lt;/p&gt;

&lt;p&gt;Let’s start by checking on how to send, receive and respond to messages on processes, doing this will involve some previous knowledge from past articles mostly episodes I, III and V.&lt;/p&gt;

&lt;div class=&quot;language-elixir 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;# Let's start by figuring out our console Process ID (PID)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# by now you already now that all you need to strat the &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# interactive console is to type `iex` on your terminal.&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# The `self/0` function return the current Process PID.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;current_proc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# #PID&amp;lt;0.56.0&amp;gt;&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# Now we can use the `process_info/2` function &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# from Erlang to get all messages our current &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# process (the interactive console) have&lt;/span&gt;
&lt;span class=&quot;ss&quot;&gt;:erlang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:messages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# {:messages, []}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# As you can see, there is no messages waiting.&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# We can send a message from this process to itself by&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# using the `send/2` function, it has two arguments, the &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# PID and the message.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current_proc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;new message&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# Now, if we check our current process messages we will&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# find one message waiting to be dealt with.&lt;/span&gt;
&lt;span class=&quot;ss&quot;&gt;:erlang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:messages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# {:messages, [&quot;new message&quot;]}&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# To handle messages we need to use a receive block&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# it's really straightforward and uses pattern matching&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# agains the next message on the list.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;receive&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Received &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&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;c1&quot;&gt;# &quot;Received new message&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# The message is displayed and now if we check the list&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# of messages, it should be empty again&lt;/span&gt;

&lt;span class=&quot;ss&quot;&gt;:erlang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:messages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# {:messages, []}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can tell, sending and receiving messages is something really simple in Elixir, and that’s one of its major benefits, it makes super easy for you to take advantage of its main capabilities.&lt;/p&gt;

&lt;p&gt;In this first example we send only a string, but keep in mind you can send any type of data, the most commonly used are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tuples&lt;/code&gt; (you can check more about tuples on &lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-iv&quot;&gt;Episode IV - Elixir Types, Data Structures and Underscore&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Another thing that you might have noticed is that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;receive&lt;/code&gt; block only handles one message, the next one on the list of messages. If you have multiple messages waiting, the receive block will only handle the next one, the one on the bottom of the list:&lt;/p&gt;

&lt;div class=&quot;language-elixir 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;current_proc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# #PID&amp;lt;0.56.0&amp;gt;&lt;/span&gt;


&lt;span class=&quot;ss&quot;&gt;:erlang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:messages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# {:messages, []}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# No messages waiting.&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# This time we sen multiple messages to this same process&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# we will send tuples, with a `:new_message` atom and&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# an integer&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current_proc&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;ss&quot;&gt;:new_message&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;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current_proc&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;ss&quot;&gt;:new_message&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;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current_proc&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;ss&quot;&gt;:new_message&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;c1&quot;&gt;# On our messages list we'll find all three messages&lt;/span&gt;
&lt;span class=&quot;ss&quot;&gt;:erlang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:messages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# {:messages, [new_message: 1, new_message: 2, new_message: 3]}&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# Now we use the `receive` block to pattern match the&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# tuple with `{:new_message, n}`, and then display a message&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# indicating we got the message&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;receive&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:new_message&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;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Received new message: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&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;c1&quot;&gt;# &quot;Received new message: 1&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Only the first message was handled, the other two&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# are still in the list waiting for another &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# receive block&lt;/span&gt;

&lt;span class=&quot;ss&quot;&gt;:erlang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:messages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# {:messages, [new_message: 2, new_message: 3]}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Okay, but how can we have a process constantly waiting for messages and handling it as it arrives? That’s where recursion comes into play, we talked about it on &lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-v&quot;&gt;Episode V - Concurrency, Processes and Recursion&lt;/a&gt;, and this is an awesome use case for it.&lt;/p&gt;

&lt;div class=&quot;language-elixir 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;# Let's create a `Sum` module that will have a `sum_number/1`&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# funciton.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Sum&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# The `sum_number/1` expects one argument, an integer &lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# that will be used to perform a sum operation  &lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sum_number&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;do&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Here we use `receive` to match messages into the&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# tuple `{:sum, n}` where `n` is an integer sent&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# within the message.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# At this point the process will stop and wait for a &lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# message (if there is none) before trying to match it&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# and move on.&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;receive&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:sum&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;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; 

        &lt;span class=&quot;c1&quot;&gt;# We display the result of the sum between the number &lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# passed as argument to `sum_number/1` and the number&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# on the received message&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&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;o&quot;&gt;+&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;c1&quot;&gt;# Then call this function again passing the same argument.&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# By using recursion (calling this function again)&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# we setup the receive block again, waiting for the &lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# next message, so every time a message is received&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# this function will handle it and setup a new receive &lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# block to handle the next one.&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sum_number&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;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Now we spawn a new process to execute the `sum_number/1`&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# function from the `Sum` module we defined above, passing `2`&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# as the argument, and this will return the PID for this new process&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sum_proc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spawn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:sum_number&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;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# #PID&amp;lt;0.121.0&amp;gt;&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# Then we can send a message for the process we just spawn above&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# passing the tuple `{:sum, 3}` to check what will be displayed&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sum_proc&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;ss&quot;&gt;:sum&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;c1&quot;&gt;# 5&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# The number `5` is displayed as expected result of `2 + 3`.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Because the process uses recursion we can still send messages&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# to it and it stills alive, waiting for another message.&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sum_proc&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;ss&quot;&gt;:sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 12&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sum_proc&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;ss&quot;&gt;:sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 8&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sum_proc&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;ss&quot;&gt;:sum&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;c1&quot;&gt;# 4&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Here we can check the process is still alive and &lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# therefore waiting for messages&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alive?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sum_proc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we already know how to use recursion for creating a process always ready to receive messages, but what about multiple processes communicating with each other? Let’s check bellow.&lt;/p&gt;

&lt;h2 id=&quot;practical-example&quot;&gt;Practical Example&lt;/h2&gt;
&lt;p&gt;For this example we’ll build a  in-memory storage for gravatar images and its paths. Before diving into the code it’s important that you understand that functional languages do not have the usual structures for holding state, keep in mind there is no objects nor instances. Recursion is one of the ways you can support state, and that’s exactly what we need for this example.&lt;/p&gt;

&lt;p&gt;We want to have an module with a function that returns the local path for a gravatar image for a given email, in order to achieve that we will need to perform the following actions:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Check if we already have this image locally&lt;/li&gt;
  &lt;li&gt;Check if the image on Gravatar&lt;/li&gt;
  &lt;li&gt;Download the image and save it locally&lt;/li&gt;
  &lt;li&gt;Return the local image path&lt;/li&gt;
  &lt;li&gt;Append the new image path to a in-memory storage&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-elixir 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;# We start creating our Gravatar module&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Gravatar&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# We'll get into `ensure_all_started/1` on future episodes&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# but here we have to start `:inets` app because we'll&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# need one of its modules down the road when downloading&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# the gravatar image, `:inets` is part of erlang &lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# standard library&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Application&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ensure_all_started&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:inets&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# This is our main function `gravatar_images/1`, it expects&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# a `Map` as argument and this `Map` will store the paths&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# for all images as we find and download them.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# As you can tell we are using pattern matching to ensure&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# the `images_path` argument will be `Map`, this doesn't&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# mean it needs to be empty, we could start with pre-existing&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# images already.&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gravatar_images&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;images_path&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;k&quot;&gt;do&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Here is our receive block, it tries to match messages&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# into three different patterns (all expect to receive&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# also the PID from the process that sent the message): &lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# - {:all_stored_images, pid}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# - {:get_image, email, pid}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# - {:store_image, email, path}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;receive&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;# `:all_stored_images` will basically send a message&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# back for the process that sent this, with all the&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# images, by returning the `images_path` map. &lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# Then it will call `gravatar_images/1` again, passing&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# the same map as argument once again, so we sill have &lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# the receive block ready for the next message.&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:all_stored_images&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&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;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;images_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;gravatar_images&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;images_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;# `:get_image` will send a message back to the PID that&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# send this message with the local path for that image&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:get_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&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;c1&quot;&gt;# `get_image/2` is a private function defined down bellow,&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# it tries to find the image into the Map we are using&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# as storage, if it doesn't finds it, it'll download&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# the image and return the path&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;new_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;images_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# Here we send the message back with the `new_path`&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# of this image to the process that sent the &lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# initial message&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# Then we send a message to this own process but&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# with the tuple `{:store_image, email, new_path}`&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&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;ss&quot;&gt;:store_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# We call `gravatar_images/1` once again because we&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# need to setup a new `receive` block to handle the&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# message we just sent above with the `:store_image` tuple.&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;gravatar_images&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;images_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;# `:store_image` will update the email key on the map&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# we are using as storage to store the local path for&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# the image.&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# Using the pipe operator we call `gravatar_images/1`&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# function again, but now passing the new Map as the&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# argument, and that's what enable us to hold state&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# and having a in-memory storage.&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:store_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&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;o&quot;&gt;-&amp;gt;&lt;/span&gt;  
        &lt;span class=&quot;no&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;images_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&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;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gravatar_images&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# The functions bellow are related to the gravatar &lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# integration, I'll avoid getting deep into explaning &lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# what is going on because it's not the main subject for&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# this example&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;defp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;images_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Tries to get the `email` key from the map, if there&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# is no key with that value, then call `download_image`.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Here we are using case with pattern mathing, we talked&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# about it in later episodes already.&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&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;n&quot;&gt;images_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:not_found&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;:not_found&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;download_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&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;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Request, download and write the file to our local env&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# return the path as the function response.&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;defp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;download_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&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;s2&quot;&gt;&quot;gravatar/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.jpg&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gravatar_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write!&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;file&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;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Returns the binary of the image from gravatar API.&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;defp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gravatar_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;http_opts&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;ss&quot;&gt;body_format:&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;url_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;n&quot;&gt;gravatar_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&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;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resp&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;ss&quot;&gt;:httpc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url_data&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;http_opts&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;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&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;s1&quot;&gt;'OK'&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;n&quot;&gt;body&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;resp&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;# Mounts the gravatar API url accordinly to &lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# their docs.&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;defp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gravatar_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;email_hash&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:crypto&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:md5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&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;no&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encode16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;'http://www.gravatar.com/avatar/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email_hash&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;.jpg'&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# First we spaw a new process, that will execute&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# the `gravatar_images/1` method from the `Gravatar`&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# module we just created, seding and empty map (`%{}`)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# as argument (so no image yet).&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spawn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Gravatar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:gravatar_images&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;c1&quot;&gt;# Now we can send this process a message to get the &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# avatar picture for a email&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&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;ss&quot;&gt;:get_image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;me@learnelixir.com&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()})&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# If we check the messages our current interactive&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# console has, we are supposed to have a new one with&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# the local path for the image we just requested&lt;/span&gt;
&lt;span class=&quot;ss&quot;&gt;:erlang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:messages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# {:messages, [&quot;gravatar/me@learnelixir.com.jpg&quot;]}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# As you can see, we do have a new message with the &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# local path for that image&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# If we ask for all images stored so far it will&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# shoot a new message back, now with the whole map&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&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;ss&quot;&gt;:all_stored_images&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()})&lt;/span&gt;

&lt;span class=&quot;ss&quot;&gt;:erlang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:messages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# {:messages,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#  [&quot;gravatar/me@joaomdmoura.com.jpg&quot;,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   %{&quot;me@joaomdmoura.com&quot; =&amp;gt; &quot;gravatar/me@joaomdmoura.com.jpg&quot;}]}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Now we have two messages, the last one and a new &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# one with a map that has an email as a key and the&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# path as value.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;P.S.1 - If you already know Elixir and Erlang you probably noticed there is some room for improvement, I could have used the Task module or even ETS + GenServer to keep state. But for the sake of the simplicity of this examples it’s more than enough, we will talk about the Task module next, and about ETS a GenServers in the future.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s Next?&lt;/h2&gt;
&lt;p&gt;Finally on Episode VII of Elixir with a Rubyist! Again I failed to get into the Task module, but I do now we have gone through all the knowledge necessary to understand and use it, so the next episode will be dedicated to it!&lt;/p&gt;

&lt;p&gt;I’m really glad from all the feedback I got so far, but I’d love to hear it from you, so please let me know on the comments bellow and over &lt;a href=&quot;https://twitter.com/joaomdmoura&quot;&gt;twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you don’t want to miss the next episodes and cool information around talks and even access to the code we use on the episodes you should subscribe to our mailing list by putting your email bellow.&lt;/p&gt;

&lt;p&gt;On the next episode we will refactor our practical example using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task&lt;/code&gt; module and understand how to use it.&lt;/p&gt;
</description>
        <pubDate>Mon, 09 Jan 2017 00:01:00 +0000</pubDate>
        <link>http://joaomdmoura.com/articles/2017/01/09/learn-elixir-with-a-rubyist-episode-vii/</link>
        <guid isPermaLink="true">http://joaomdmoura.com/articles/2017/01/09/learn-elixir-with-a-rubyist-episode-vii/</guid>
      </item>
    
      <item>
        <title>Learn Elixir with a Rubyist, episode VI</title>
        <description>&lt;h2 id=&quot;head--tail--list-comprehension&quot;&gt;[Head | Tail] &amp;amp; List Comprehension&lt;/h2&gt;
&lt;p&gt;Another week another article, glad to be back to publish one article a week, this is the sixth episode and as promised we will talk about one of the most used features of Erlang, the [head | tail] implementation and list comprehensions.
Now is also a great opportunity to let me know what you’re thinking about the series on &lt;a href=&quot;https://twitter.com/joaomdmoura&quot;&gt;twitter&lt;/a&gt; and check the latest episodes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-i&quot;&gt;Episode I - Elixir, Pipe Operator and Pattern Matching&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-ii&quot;&gt;Episode II - Actor Model, Modules and functions&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-iii&quot;&gt;Episode III - Maps, Functions + Pattern Matching = ❤️&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-iv&quot;&gt;Episode IV - Elixir Types, Data Structures and Underscore&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-v&quot;&gt;Episode V - Concurrency, Processes and Recursion&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-vi&quot;&gt;Episode VI - Head + Tail and List Comprehension&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-vii&quot;&gt;Episode VII - Processes Communication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;lists--head--tail&quot;&gt;Lists &amp;amp; [Head | Tail]&lt;/h2&gt;
&lt;p&gt;We have already talked about lists in the past articles, mainly on the - &lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-iv&quot;&gt;Episode IV - Elixir Types, Data Structures and Underscore&lt;/a&gt;, by now you may have realized that list are one of the main types in Elixir (and also in Erlang), because of that, there is a bunch o optimizations and tools that were created to support it.&lt;/p&gt;

&lt;p&gt;Having a good support for lists is a common trait of functional languages because its tools enable you to achieve recursion easier, even without specific loop functions, as we already discussed on the last Episode V (Concurrency, Processes and Recursion).&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[head | tail]&lt;/code&gt; was already present on Erlang, it enables you to split a list by taking away its first element and putting the rest of the list into a new list. Let’s start by checking some examples of how &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[head | tail]&lt;/code&gt; works:&lt;/p&gt;

&lt;div class=&quot;language-elixir 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;# Declaring a list is really simple and straightforward,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# it can contain anything, from integers to other lists.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;list&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;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;c1&quot;&gt;# Let's start by simply using pattern matching with the&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# the [head | tail] syntax.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&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;list&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# You can see the value of `h` is now the first element&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# of the list we had&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 1&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# And `t` is the other elements from the same list but now&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# into a new one.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# [2, 3]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# You can also use the Erlang `hd/1` and `tl/1` functions&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# both take a list as argument and return its head or tail&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;hd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 1&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;tl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# [2, 3]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# You can also use the [head | tail] syntax to push elements&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# into a list, here `:atom` is being assigned as the head of &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# a list, and our old list as the tail, therefore it will &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# result in a new list with `:atom` as its first element&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;new_list&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;ss&quot;&gt;:atom&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# [:atom, 1, 2, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It may no seem but the head and tail implementation enables you to do awesome stuff, we checked some examples on the last episode, and will have event better ones on the next, but before jumping into practical examples let’s check more about list and its capabilities.&lt;/p&gt;

&lt;h2 id=&quot;lists-comprehensions&quot;&gt;Lists Comprehensions&lt;/h2&gt;
&lt;p&gt;List comprehension is an old concept that is also present on Erlang, it can be used to construct lists (normally based on other lists) in a very natural, easy way, like a mathematician is used to do. It’s another common trait of functional languages because it enables you to loop through lists, filtering and mapping its elements.&lt;/p&gt;

&lt;p&gt;Elixir brings a syntactic sugar for comprehensions, the for syntax ,  you can do most of common tasks using it, let’s check some examples of how it works:&lt;/p&gt;

&lt;div class=&quot;language-elixir 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;# The `for` syntax is pretty simple, it can be divided &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# into three different parts: an Enumerable, in this case&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# a list `[1, 2, 3, 4]`, the variable to which each &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# elements is being assigned to (`i`), and the operation that&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# will be performed using each element (`2 * i`).&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&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;k&quot;&gt;do&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;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# [2, 4, 6, 8]&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# As you can see each element of the list is being assigned&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# to `i` and then multipled by `2`, resulting into a new list&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# `for` also enable you to have filters applied to&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# your comprehensions, let's check bellow:&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&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;mi&quot;&gt;5&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;o&quot;&gt;&amp;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;k&quot;&gt;do&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;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# [6, 8, 10]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# As you can see, becasue we are now passing another argument,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# a filter (`i &amp;gt; 2`), elements that do now pass throught it&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# won't be processes and therefore won't be on the new list.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# `1` and `2` were ignored and the numbers bigger than `2`&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# were doubled as expected.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;lists-comprehensions--pattern-matching&quot;&gt;Lists Comprehensions + Pattern Matching&lt;/h2&gt;

&lt;p&gt;You can also put &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; together with pattern matching, by now you probably realized you can use pattern matching with almost anything on Elixir, by doing it we’ll be able you to filter the elements from the list (or other Enumerable).&lt;/p&gt;

&lt;p&gt;This can be really useful when working with tuples (we talked about it on - &lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-iv&quot;&gt;Episode IV - Elixir Types, Data Structures and Underscore&lt;/a&gt; and multiple comprehensions. Let’s check how it works when using a list of tuples and pattern matching:&lt;/p&gt;

&lt;div class=&quot;language-elixir 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;# We just create a list of tuples. In this case it &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# represents cities and its countries.&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;cities&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;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;us&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;new york&quot;&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;s2&quot;&gt;&quot;us&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;san francisco&quot;&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;s2&quot;&gt;&quot;cn&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;beijing&quot;&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;s2&quot;&gt;&quot;fr&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;paris&quot;&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;c1&quot;&gt;# Here we are using pattern matching by trying to match&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# each tuple into the following pattern `{:us, city}`.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# The elements that doesn't match it will be ignored&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# and the ones that do match will have its city name&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# assigned to the `city` variable.&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;us&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# [&quot;New york&quot;, &quot;San francisco&quot;]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# As you can see only the first and second elements from&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# our list were used and capitalized, because it was &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# the only ones that matched our pattern.&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Because we are using pattern matching we can do it &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# both ways, by also trying to match the city's name&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;country&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;paris&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&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;country&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# [&quot;fr&quot;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;lists-comprehensions--into-option&quot;&gt;Lists Comprehensions + into option&lt;/h2&gt;

&lt;p&gt;Another great and really useful feature that comes with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for&lt;/code&gt; implementation is the into option, it enables you to have the end result from the comprehension &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;into&lt;/code&gt; another type that is not a list, like a map (we talked about maps on - &lt;a href=&quot;http://joaomdmoura.com/articles/learn-elixir-with-a-rubyist-episode-iii&quot;&gt;Episode III - Maps, Functions + Pattern Matching = ❤️&lt;/a&gt;), here is a quick examples of how it works:&lt;/p&gt;

&lt;div class=&quot;language-elixir 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;# Here we have a list with valid and invalids &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# responses, we want to get the error on that&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# list and put it into a map, using the `error`&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# key.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;list&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;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;valid&quot;&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;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;valid&quot;&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;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;invalid argument&quot;&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;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;into:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{},&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&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;ss&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# %{error: [&quot;invalid argument&quot;]}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# by returning a tuple the `for` will understand &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# the the first element represents the key and the&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# second one the value that should be on the map.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# And there is our Map, exactly how we wanted it.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I know it looks good enough already but gets even better, for also enables you to pass as many generators and filters as you need, check it out:&lt;/p&gt;

&lt;div class=&quot;language-elixir 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;# This time we have 2 lists, one with integer &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# and another with atoms, lets use `for`&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# on both at the same time&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;list_1&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;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;n&quot;&gt;list_2&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;ss&quot;&gt;:a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list_2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&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;n&quot;&gt;y&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;c1&quot;&gt;# [&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#  {1, :a}, {1, :b}, {1, :c}, &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#  {2, :a}, {2, :b}, {2, :c}, &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#  {3, :a}, {3, :b},{3, :c}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ]&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# The result will be the based on the comprehension &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# of both lists, getting a element from the first&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# and going through all elements of the second one.&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# You can have as many list you need, this concept&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# also enable you to use as many filters as you want&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# and even assign variables.&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# In this example we will have two list, and we want to&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# mutiply its elements by each other and puts the &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# result into a new list, but only if the result of the&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# operation is bigger than `4`&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;list_1&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;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;n&quot;&gt;list_2&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;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;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; 
      &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# [5, 5, 6]&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# This is it! This example performed the following&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# operations:&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 1 + 3 = 4&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 1 + 4 = 5&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 2 + 3 = 5&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 2 + 4 = 6&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# But the result from the first calulation got excluded&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# from our final result because it didn't pass &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# the `&amp;gt; 4` filter we had.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s Next?&lt;/h2&gt;
&lt;p&gt;Yay! Episode VI of Elixir with a Rubyist! I was hoping to get into the Task module into this episode but I thought it would be better to wait for the next one taking into account we had so much to check on lists.&lt;/p&gt;

&lt;p&gt;This is a series of short bar-like conversations around Elixir, it’s aimed to help developers that are trying to understand and wrap their heads around it.&lt;/p&gt;

&lt;p&gt;I hope you have liked it so far, if you do, please let me know on the comments bellow and over &lt;a href=&quot;https://twitter.com/joaomdmoura&quot;&gt;twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On the next episode we will finally get into the Task module and understand how exchange information between processes.&lt;/p&gt;
</description>
        <pubDate>Sun, 08 Jan 2017 00:01:00 +0000</pubDate>
        <link>http://joaomdmoura.com/articles/2017/01/08/learn-elixir-with-a-rubyist-episode-vi/</link>
        <guid isPermaLink="true">http://joaomdmoura.com/articles/2017/01/08/learn-elixir-with-a-rubyist-episode-vi/</guid>
      </item>
    
  </channel>
</rss>
