<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ron</title>
    <description>The latest articles on DEV Community by Ron (@ronald_arias).</description>
    <link>https://dev.to/ronald_arias</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F565187%2F2cb8570a-a676-4252-9177-c9b6cdf5c489.jpg</url>
      <title>DEV Community: Ron</title>
      <link>https://dev.to/ronald_arias</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ronald_arias"/>
    <language>en</language>
    <item>
      <title>Brief Introduction to Microservices</title>
      <dc:creator>Ron</dc:creator>
      <pubDate>Thu, 29 Apr 2021 07:53:17 +0000</pubDate>
      <link>https://dev.to/ronald_arias/brief-introduction-to-microservices-3ph8</link>
      <guid>https://dev.to/ronald_arias/brief-introduction-to-microservices-3ph8</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oJ8HQSa5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cb7m95aa4as9p0urj9ux.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oJ8HQSa5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cb7m95aa4as9p0urj9ux.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Almost certainly, in this day and age you have heard of Microservices architectures. The term gets thrown around very often when talking about scaling and handling growth within your system.&lt;/p&gt;

&lt;p&gt;But what are, really, Microservices?&lt;/p&gt;

&lt;p&gt;The fact is, this type of architecture is nowhere near new. Airbnb was building Microservices at scale back in 2012 just to give you an example. Distributed Systems were around many years before that.&lt;/p&gt;

&lt;p&gt;Microservices are small services [micro], that have one purpose or serve a specific domain only. By having many of these, you're able to scale horizontally instead of keep growing a big machine.&lt;/p&gt;

&lt;p&gt;The idea of Microservices is actually better explained when put against traditional monolith applications, and that's probably the best example out there.&lt;/p&gt;

&lt;p&gt;In the earlier days, you'd have a single codebase for your app, using a single programming language, and you'd scale the resources it needed as required given your growth. In hindsight you can clearly see the problem with that, at some point you'll need huge machines to support scale. There were workarounds to manage this issue, but even then you'll hit a cap at some point.&lt;/p&gt;

&lt;p&gt;The logical next step was to start separating these applications into different systems that communicate passing messages between each other. These systems could be split by domain for example, say accounting vs inventory. Still, these splits were also somewhat inflexible and would grow in the same way as their strict monolithic peers.&lt;/p&gt;

&lt;p&gt;At some point, what Engineers figured out was that making these services smaller you gain flexibility, to the point that when needing to add functionality you could just build a new service, and if needing more power in a particular area of the system, you could spin many of these services to cope with the load or scale them independently. &lt;/p&gt;

&lt;p&gt;That was sort of the birth of Microservices.&lt;/p&gt;

&lt;p&gt;The end.&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;Jokes, this is when things got exciting!&lt;/p&gt;

&lt;p&gt;Now armed with this knowledge, Software Engineers and Architects could build all sorts of different topologies to handle their specific needs.&lt;/p&gt;

&lt;p&gt;However, Microservices did come with some challenges of its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Communication between services
&lt;/h2&gt;

&lt;p&gt;There are many ways to communicate across services, and that has also evolved over time. The traditional way is to pass messages via HTTP or &lt;a href="https://en.wikipedia.org/wiki/SOAP"&gt;SOAP&lt;/a&gt; in the same fashion other &lt;a href="https://en.wikipedia.org/wiki/Service-oriented_architecture"&gt;Service-Oriented Architectures&lt;/a&gt; did.&lt;/p&gt;

&lt;p&gt;Another option is to use shared data stores like databases to write data on one place and read it in another place.&lt;/p&gt;

&lt;p&gt;Each of these are not exclusive to Microservices in fact, they were adopted from previous service-oriented iterations. The novelty now is that messages can be smaller and serve a single purpose as well, for example a service could accept only messages related to updating a user's profile information, or making a booking and that decreases complexity overall.&lt;/p&gt;

&lt;p&gt;Given the scale at what modern applications grew, even these ways of communication weren't enough, so the current standard of using &lt;a href="https://aws.amazon.com/message-queue/"&gt;message queues&lt;/a&gt; was born. Companies like Google, Amazon, Facebook built their own implementations of event queues but nowadays we can find more widely adopted options like &lt;a href="https://kafka.apache.org/intro"&gt;Kafka&lt;/a&gt; or &lt;a href="https://www.rabbitmq.com/"&gt;RabbitMQ&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Event-Driven architectures are the modern standard at the time of writing, and they're a whole new level of complexity and awesomeness, which I will write more about in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hybrid Architectures
&lt;/h2&gt;

&lt;p&gt;The practice of having hybrid architectures, running different services on multiple programming languages and setups is widespread now. You can easily &lt;a href="https://rarias.dev/learn-multiple-programming-languages/"&gt;have multiple programming languages&lt;/a&gt; running within the same system now that small services are running somewhat independently from each other.&lt;/p&gt;

&lt;p&gt;This allows you to maximise the benefits of each technology you pick, as long as you find a good way to communicate between them.&lt;/p&gt;

&lt;h2&gt;
  
  
  How small do the Microservice needs to be?
&lt;/h2&gt;

&lt;p&gt;This is where it starts getting tricky. There isn't a single rule to define what is Microservice or how micro is micro. There's a guideline that says it needs to be small enough to serve a single purpose and be contained within a single domain but that's vague, probably on purpose. &lt;/p&gt;

&lt;p&gt;In practice, when you create Microservices what tends to happen is that you start with something that resembles a Microservice given that definition, but over time the service grows and you need to reevaluate whether it needs to be split as it doesn't serve a single purpose anymore.&lt;/p&gt;

&lt;p&gt;You need to find a balance between having too many services that are too small and make it harder to maintain, versus having services too big that are not Microservices anymore and become harder to scale.&lt;/p&gt;

&lt;p&gt;You can call it bad practice, bad design, band planning, or whatever, but that's what usually happens, and it's natural to only notice in hindsight. The good news is that if the services are "small enough", splitting or rewriting them is often not much of a problem. Even replacing them completely in a new programming language is also on the table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transactions on Distributed Systems
&lt;/h2&gt;

&lt;p&gt;One of the main issues in Microservice architectures is the concept of transactions. If multiple services execute different parts of a transaction, how do you rollback when the process fails half-way?&lt;/p&gt;

&lt;p&gt;This is a very complex problem and can be solved in different ways depending on your architecture. Most certainly you are better off using an existing design pattern to solve this problem.&lt;/p&gt;

&lt;p&gt;Two common patterns to solve this issue are the &lt;strong&gt;2-phase commit&lt;/strong&gt; pattern (2pc), which uses an orchestrator service to rollback transactions if something goes wrong. This is a synchronous approach to solving the issue; The other pattern is the &lt;strong&gt;Saga&lt;/strong&gt; pattern, which aims to produce events of the different stages of a transaction and compensating the failed transactions when something goes wrong. This is the asynchronous approach.&lt;/p&gt;

&lt;p&gt;It's out of the scope of this article to visit those in detail, but it's a good idea to research these patterns in depth as you are likely to encounter these issues if working on Microservice architectures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Microservice versioning
&lt;/h2&gt;

&lt;p&gt;Another common problem is having to update the event structure that Microservices use to communicate with each other.&lt;/p&gt;

&lt;p&gt;Given that services need to know how to parse a message from other services, when changes in that event are needed you need to find a way to keep the communication working until such services are back in sync.&lt;/p&gt;

&lt;p&gt;To solve this issue you probably need to use some form of versioning. In the case you can shutdown the Microservices completely, update them and put them back on, this is not an issue at all.&lt;/p&gt;

&lt;p&gt;When that's not possible the next best case scenario is adding new data to an event without affecting the older structure. This way you can upgrade your sender first to add the new field(s) and work on supporting the listeners later on.&lt;/p&gt;

&lt;p&gt;If that's not possible either, solving the issue becomes a tad more complicated. A good solution for this is to add versions on your listeners while you transition to the newest events. Then depending on the version of the message received you can parse it one way or another.&lt;/p&gt;

&lt;p&gt;There are multiple ways to solve these types of problems, and the solution will be different depending on the message restrictions; For example, having a hard type schema of your event will make it more complex.&lt;/p&gt;

&lt;h2&gt;
  
  
  Maintenance
&lt;/h2&gt;

&lt;p&gt;Large Microservice architectures are harder to maintain and to update. You can probably Dockerize the instances that are running the services and update all of the machinery at the same time, but if you have multiple services running different programming languages on different versions upgrading at different speeds, then keeping everything up to day becomes a repetitive and time consuming task.&lt;/p&gt;

&lt;p&gt;With this in mind, it's important to take as many steps as possible to ensure that domain functionality is not too tangled so services can be upgraded independently from each other as much as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Microservices architectures are a fantastic way to scale your system horizontally and to manage the growth of your business but it doesn't come cheap. There are tradeoffs to be aware of and having a solid understanding of the principles, patterns and benefits is important.&lt;/p&gt;

&lt;p&gt;There are also many different topologies to consider, and what works for me may not work for you, so make sure that you understand your business requirements when designing your system.&lt;/p&gt;

&lt;p&gt;Another thing to keep in mind is that this is a complex architecture, even though it sounds simple. You don't need to jump on it right away, especially if you're only getting started. This is a complexity trap. If you don't have to handle a high amount of traffic, it's probably best to start with a single monolithic app and slice and dice it as you grow. It will save you time and probably money.&lt;/p&gt;

&lt;p&gt;For more topics, check my &lt;a href="https://dev.to/ronald_arias"&gt;profile&lt;/a&gt; or visit &lt;a href="//rarias.dev"&gt;rarias.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy &lt;del&gt;coding&lt;/del&gt; designing? 🤔&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>basics</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Not writing automated tests? You have a problem waiting to happen</title>
      <dc:creator>Ron</dc:creator>
      <pubDate>Thu, 29 Apr 2021 07:51:48 +0000</pubDate>
      <link>https://dev.to/ronald_arias/not-writing-automated-tests-you-have-a-problem-waiting-to-happen-44o5</link>
      <guid>https://dev.to/ronald_arias/not-writing-automated-tests-you-have-a-problem-waiting-to-happen-44o5</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs44xxje28hm8qa5kflgh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs44xxje28hm8qa5kflgh.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unit testing, Integration testing, A/B testing, stress testing... you name it. There are many ways to ensure your software is working correctly in an automated way.&lt;/p&gt;

&lt;p&gt;The times of manually checking your functionality "runs fine" are long gone. In any Software development team, the testing part is (or should be) as integral as writing the code itself.&lt;/p&gt;

&lt;p&gt;I personally advocate testing so heavily that I reject PRs on the base of missing or having wrongly written tests. There's certain anxiety on the back of my neck when having to deploy code that's not through-fully tested. I just can't help it.&lt;/p&gt;

&lt;p&gt;For a better Software development world, you shouldn't tolerate it either.&lt;/p&gt;

&lt;p&gt;As applications and teams grow bigger, the needs for automatic testing suites grow with them.&lt;/p&gt;

&lt;p&gt;You may say "But Ron, we have a QA team to do the testing for us". &lt;/p&gt;

&lt;p&gt;Sure, having a QA team is a nice thing, and surely they will be able to test your features in due time, but the ownership of code should come from development. It is your responsibility as the person who writes the code to ensure it's working as best as possible, and to reduce the load on the QA team.&lt;/p&gt;

&lt;p&gt;Additionally, relying on your QA team promotes a "throwing over the wall" behaviour, in which developers don't follow up to make sure their code is production ready the moment it leaves their machines.&lt;/p&gt;

&lt;p&gt;The less tests you write, the more potential issues you're introducing. I've learnt this the hard way. It's almost like divine justice being served. Every time I've decided to skip testing certain features, I've introduced an error in production. Fortunately other measures like heavily alerting and small deploys usually had helped me find the issue quickly and roll it back, but it's still painful.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to best write automated tests
&lt;/h2&gt;

&lt;p&gt;There's this concept of a testing pyramid. It looks something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpur806lglwdkg68g91tc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpur806lglwdkg68g91tc.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea is that the majority of your tests are going to be unit tests. They're easy to write, they are fast to run and in general they should even help you clarify your functionalities. &lt;/p&gt;

&lt;p&gt;Afterwards you have integration tests, which are more complex and make sure the different parts of your system are interacting correctly.&lt;/p&gt;

&lt;p&gt;At last you have UI and potentially manual tests.&lt;/p&gt;

&lt;p&gt;There are many variations of this pyramid, with more detail or steps in between but the concept is the same. You go from less to more complex tests, moving up the pyramid.&lt;/p&gt;

&lt;p&gt;Your application should at the very least have the bottom of the pyramid covered. Unit tests are essential for every system.&lt;/p&gt;

&lt;p&gt;If you engage in practices like &lt;a href="https://en.wikipedia.org/wiki/Test-driven_development" rel="noopener noreferrer"&gt;TDD&lt;/a&gt; or &lt;a href="https://en.wikipedia.org/wiki/Behavior-driven_development" rel="noopener noreferrer"&gt;BDD&lt;/a&gt;, it's even better. The practice of writing your tests first helps you find functionality gaps and guide you through your feature building. You can consider the different scenarios your app needs to handle before you even start writing your first line of code.&lt;/p&gt;

&lt;p&gt;Additionally, you should make sure to pick the right testing framework for you. Pick something that makes your life easy. You don't want to be spending all your time figuring out how your tests are being set up, but writing them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do you need 100% test coverage?
&lt;/h2&gt;

&lt;p&gt;Simple answer is no. Test coverage is somewhat a useless metric.&lt;/p&gt;

&lt;p&gt;There it is, I said it!&lt;/p&gt;

&lt;p&gt;More often than not, test coverage can give you a false sense of security and make you sloppy when considering edge case scenarios. &lt;/p&gt;

&lt;p&gt;Entertain my idea with the following example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;debit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;account&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;credit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;account&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two over-simplistic functions to debit and credit a given amount from an account, similar to a banking transaction. &lt;/p&gt;

&lt;p&gt;Logically It is expected that you add the amount to the account in the credit scenario, and the opposite on the debit scenario, right? &lt;/p&gt;

&lt;p&gt;There are a lot of validations to be performed, like making sure the account is higher than 0 on debit for example.&lt;/p&gt;

&lt;p&gt;Now, consider we write the following tests&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"debits the amount"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;debit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"credits the amount"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;credit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our tests have now 100% coverage!&lt;/p&gt;

&lt;p&gt;See the problem here?&lt;/p&gt;

&lt;p&gt;Coverage in itself is a horrible metric, it doesn't consider edge cases, just that you've "covered" all parts of the code.&lt;/p&gt;

&lt;p&gt;The following logically incorrect situations won't be considered at all:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;debit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;
&lt;span class="n"&gt;credit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When considering the use of test coverage, bear in mind that it's not a substitute for logically and through-fully thinking about all your test cases, edge cases and impossibly looking cases.&lt;/p&gt;

&lt;p&gt;You can just as easily have an application with merely 70% test coverage but having a strong set of tests that make sure the code is handling all expected and most unexpected scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Drawbacks of writing tests
&lt;/h2&gt;

&lt;p&gt;Writing tests is time consuming. It doesn't move your application forward like, say, a new feature. When your line manager asks why that feature is not ready yet, and you say you've been spending a lot of time writing tests it's sometimes not pretty.&lt;/p&gt;

&lt;p&gt;It's a necessary time consuming task that needs to be included as an essential part of your development process. You and your team need to understand that if writing the code for a feature takes 1hr and your automated tests take 2hrs, that feature took 3hrs until done, not 1hr.&lt;/p&gt;

&lt;p&gt;Additionally, test scenarios need to be rewritten every time a feature is updated, and new scenarios need to be added every time a bug that wasn't considered in the tests is discovered. It's an ongoing time consuming process.&lt;/p&gt;

&lt;p&gt;That being said, do not think for a second that it's unnecessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  What test suite should you use?
&lt;/h2&gt;

&lt;p&gt;Use something that makes it extremely easy, even enjoyable to write tests. &lt;/p&gt;

&lt;p&gt;Sometimes writing automated tests is dragging and plainly boring. When pressed for time, you will hate having to take care of the tests, but with the correct testing framework, you'll make the process overall better.&lt;/p&gt;

&lt;h2&gt;
  
  
  What if I'm the only one writing tests on my team?
&lt;/h2&gt;

&lt;p&gt;Hold your teammates accountable, advocate the benefits. Be repetitive and annoying if necessary.&lt;/p&gt;

&lt;p&gt;The cost of letting untested issues into production is just too high. Once that broken feature reaches your users, it's going to negatively impact the business. It may even mean losing users altogether.&lt;/p&gt;

&lt;p&gt;When it comes to making sure everyone is pulling their weight and making sure all systems are operational, writing tests should be among your top priorities.&lt;/p&gt;

&lt;p&gt;An additional benefit is that you avoid regressions when collaborating on features. If a great testing suite is in place, you can guarantee that whatever you do is not going to affect your teammate's previous work if all tests are ok after you're done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Testing is as important as writing the features itself when it comes to Software development. Do not ignore them, or you have a problem waiting to happen. No matter how good you think your coding skills are, you increase your probabilities of making mistakes if there isn't an automated way to check everything is working correctly.&lt;/p&gt;

&lt;p&gt;In big and interconnected systems, the need is even bigger. As your platform grows in size and complexity, you need a mechanism that ensures you can safely build on top of what you already have, and that's automated testing.&lt;/p&gt;

&lt;p&gt;For more topics, check my &lt;a href="https://dev.to/ronald_arias"&gt;profile&lt;/a&gt; or visit &lt;a href="//rarias.dev"&gt;rarias.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>programming</category>
      <category>basics</category>
    </item>
    <item>
      <title>Kanban for Software Engineering</title>
      <dc:creator>Ron</dc:creator>
      <pubDate>Thu, 04 Mar 2021 11:19:40 +0000</pubDate>
      <link>https://dev.to/ronald_arias/kanban-for-software-engineering-12n4</link>
      <guid>https://dev.to/ronald_arias/kanban-for-software-engineering-12n4</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rLTVOfxc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/stsgfruzjkci44u06q90.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rLTVOfxc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/stsgfruzjkci44u06q90.jpg" alt="Photo by Eden Constantino on Unsplash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hi everyone,&lt;br&gt;
I'm in the process of &lt;strong&gt;refining our Kanban methodology&lt;/strong&gt; and I thought I'd try to reach to some of you in the community for help on best practices and what to look for.&lt;/p&gt;

&lt;p&gt;My team and I have been using Kanban for our Software development process for about a couple of years now, with some level of success but I'd like to know what's required to take it to the next level.&lt;/p&gt;

&lt;p&gt;If you or your team are using Kanban, what worked for you?&lt;/p&gt;

</description>
      <category>help</category>
      <category>discuss</category>
      <category>kanban</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>PyEnv &amp;&amp; Pipenv</title>
      <dc:creator>Ron</dc:creator>
      <pubDate>Fri, 26 Feb 2021 17:58:19 +0000</pubDate>
      <link>https://dev.to/ronald_arias/pyenv-pipenv-1cko</link>
      <guid>https://dev.to/ronald_arias/pyenv-pipenv-1cko</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hoFx2jKN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0j05c0d2lu8p4azn43he.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hoFx2jKN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0j05c0d2lu8p4azn43he.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If there's something I've learnt with experience is that there's almost always a simple way to do things. There are millions of people dealing with development problems the same way you are, so chances are someone already stumble with a way to simplify things.&lt;/p&gt;

&lt;p&gt;One of those simple things is putting together a Python development environments.&lt;/p&gt;

&lt;p&gt;I'm wouldn't say I'm a Python developer. I only use it for a specific subset of cases, mostly requiring large amounts of data for analysis, Machine Learning, etc.&lt;/p&gt;

&lt;p&gt;So intuitively, when setting up my development environment I try to make it as easy as possible, and coming from other programming languages and frameworks such as Ruby, Elixir, Node, etc where there's clear separation between version language and libraries almost by default, I'd expect Python to be no different.&lt;/p&gt;

&lt;p&gt;Wrong! 😭&lt;/p&gt;

&lt;p&gt;Python's setup is a mess. Python 2 is still around and it has no compatibility with Python 3. Python 3 at the same time has so many ways to be setup that it makes it so confusing. &lt;/p&gt;

&lt;p&gt;If you pick the wrong way to setup and tie too many things to the system, then you end up with incompatibilities across projects and all other sorts of issues.&lt;/p&gt;

&lt;p&gt;However, there's one type of setup that, in my opinion, seems to be the most similar to what I'm used to. And it's using &lt;a href="https://github.com/pyenv/pyenv"&gt;Pyenv&lt;/a&gt; along with &lt;a href="https://pypi.org/project/pipenv/"&gt;Pipenv&lt;/a&gt; to setup projects individually and isolated within their own Python and library versions.&lt;/p&gt;

&lt;p&gt;Let's go ahead and dig deeper into this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pyenv
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Pyenv&lt;/code&gt; is a Python version manager tool. It was based on the popular Ruby version managers &lt;code&gt;rbenv&lt;/code&gt; and &lt;code&gt;ruby-build&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Its functionality is quite simple. It lets you have different versions of Python in your environment, which are not dependent on each other or the system.&lt;/p&gt;

&lt;p&gt;There are many other tools that sort of do something similar, but I find Pyenv to be the most unintrusive of all. It does not require Python itself as it's built with shell scripts, and it does not need to be loaded into your shell.&lt;/p&gt;

&lt;p&gt;One additional thing to remember is that you don't want your system Python running the show. So the more you can stay away from it and use isolated environments the better.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;There are many ways to install Pyenv.&lt;/p&gt;

&lt;p&gt;By far the easiest if you're on MacOS or Linux is via Homebrew&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ brew &lt;span class="nb"&gt;install &lt;/span&gt;pyenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this, you need to let your bash initiate pyenv on start. For this you can add the following init script to whatever shell you're using. &lt;/p&gt;

&lt;p&gt;In my case for &lt;code&gt;zsh&lt;/code&gt; I need to add it to my &lt;code&gt;.zshrc&lt;/code&gt;  but for you it could be &lt;code&gt;.bash_profile&lt;/code&gt; or &lt;code&gt;.bashrc&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; pyenv &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;pyenv init -&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will allow Pyenv to manipulate your path and give itself priority inside pyenv environments.&lt;/p&gt;

&lt;p&gt;And it's done!&lt;/p&gt;

&lt;p&gt;For more installation instructions you can check their &lt;a href="https://github.com/pyenv/pyenv#installation"&gt;Github page&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Pyenv
&lt;/h3&gt;

&lt;p&gt;Next thing to do is install a new version of Python. You can install as many as you need, even from different distributions.&lt;/p&gt;

&lt;p&gt;To see what versions are available, use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ pyenv &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will give you a full list of available versions. &lt;/p&gt;

&lt;p&gt;Let's go ahead and install Python 3.9.1&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ pyenv &lt;span class="nb"&gt;install &lt;/span&gt;3.9.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like that, you're rolling on Python 3.9.1, yay!&lt;/p&gt;

&lt;p&gt;Last step is to tell your system the global version you want to use. You don't necessarily have to do this, but it makes things a bit easier down the line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ pyenv global 3.9.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations, you have Python in your system 🙂&lt;/p&gt;

&lt;h2&gt;
  
  
  Pipenv
&lt;/h2&gt;

&lt;p&gt;Pipenv works at a lower level than Pyenv, and they can work together very well.&lt;/p&gt;

&lt;p&gt;Pipenv is a tool, again sort of inspired in Bundler, Npm, Yarn etc, that aims to keep your project environment nice and tidy.&lt;/p&gt;

&lt;p&gt;It might be counter-intuitive and you may be tempted to just install everything at the global scale so it's available for every project you use, but don't! This is an easy way to depend on libraries that may not be available when using somewhere else.&lt;/p&gt;

&lt;p&gt;Additionally Pipenv makes collaboration really easy. Stakeholders all use the environment setup in the Pipfile and this guarantees everyone is on the same page.&lt;/p&gt;

&lt;p&gt;So what does Pipenv do exactly?&lt;/p&gt;

&lt;p&gt;It uses a &lt;code&gt;Pipfile&lt;/code&gt; and &lt;code&gt;Pipfile.lock&lt;/code&gt; to sort of snapshot the dependencies you use in a project. It allows you to work in an enclosed environment, without the fear of your work slipping out to your other project environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;Once you have Pyenv running and are on your preferred version of Python, run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-U&lt;/span&gt; pipenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pyenv sort of hijacks the &lt;code&gt;pip&lt;/code&gt; command, to make sure you're working in the correct environment.&lt;/p&gt;

&lt;p&gt;After this you're ready to start using &lt;code&gt;pipenv&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The library is meant to be used within a project or project folder/context, so go ahead and navigate to your preferred project directory and initialise pipenv in there&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ pipenv &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a &lt;code&gt;Pipfile&lt;/code&gt; containing your dependencies, and a &lt;code&gt;Pipfile.lock&lt;/code&gt; containing the versions and dependencies of those dependencies.&lt;/p&gt;

&lt;p&gt;Traditionally, another way to manage dependencies in Python projects is using a &lt;code&gt;requirements.txt&lt;/code&gt; file. If you already have one of those on an existing project, pipenv will transform it to a &lt;code&gt;Pipfile&lt;/code&gt; with the previous step and attempt to migrate your existing dependencies to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Pipenv
&lt;/h3&gt;

&lt;p&gt;From now on, you're good to start using pipenv to manage your dependencies.&lt;/p&gt;

&lt;p&gt;To add a new one you can let pipenv know what you want to install and it will update both the &lt;code&gt;Pipfile&lt;/code&gt; and the &lt;code&gt;Pipfile.lock&lt;/code&gt; for you&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Installing Jupyter notebooks&lt;/span&gt;
❯ pipenv &lt;span class="nb"&gt;install &lt;/span&gt;notebook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like that your new dependency has been added your your &lt;code&gt;Pipfile&lt;/code&gt; and &lt;code&gt;Pipfile.lock&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now to "enter" the environment that pipenv has created for you, you need to activate a new shell using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ pipenv shell
Launching subshell &lt;span class="k"&gt;in &lt;/span&gt;virtual environment…
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will load your current bash with the dependencies installed within your pipenv environment. Every command that you run within this shell will execute in the context of your Pipenv.lock.&lt;/p&gt;

&lt;p&gt;To exit the shell just type &lt;code&gt;exit&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;There's so much to learn about Pyenv and Pipenv, that you're better off just following the documentation and trying it yourself, but I guarantee you it will save you countless hours of configuration and figuring out what's going on with your project dependencies and why some projects are failing after updating other unrelated ones.&lt;/p&gt;

&lt;p&gt;If you want to know more about the different environment setups that Python has to offer and its differences, there's this really &lt;a href="https://stackoverflow.com/questions/41573587/what-is-the-difference-between-venv-pyvenv-pyenv-virtualenv-virtualenvwrappe"&gt;detailed StackOverflow&lt;/a&gt; post that explains it very well. Even though their recommendation is using &lt;code&gt;virtualenv&lt;/code&gt; + &lt;code&gt;pip&lt;/code&gt; instead, it's worth having a look at the different options summarised so you can make an informed decision of what you want.&lt;/p&gt;

&lt;p&gt;For more topics, check my &lt;a href="https://dev.to/ronald_arias"&gt;profile&lt;/a&gt; or visit &lt;a href="//rarias.dev"&gt;rarias.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>basics</category>
      <category>programming</category>
    </item>
    <item>
      <title>Learn how to deploy Elixir apps on Heroku</title>
      <dc:creator>Ron</dc:creator>
      <pubDate>Fri, 12 Feb 2021 08:45:37 +0000</pubDate>
      <link>https://dev.to/ronald_arias/learn-how-to-deploy-elixir-apps-on-heroku-47k0</link>
      <guid>https://dev.to/ronald_arias/learn-how-to-deploy-elixir-apps-on-heroku-47k0</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wYixOM2E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/so3bki7r18trxobkd2gf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wYixOM2E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/so3bki7r18trxobkd2gf.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With every app we decide to take out to the world, there's one important decision to make when the time comes.&lt;/p&gt;

&lt;p&gt;Where is the best place to deploy it?&lt;/p&gt;

&lt;p&gt;The short answer is: "It depends, probably there's no one best place actually".&lt;/p&gt;

&lt;p&gt;The long answer however, will depend on what your needs are, your budget, the setup of your current applications, company restrictions etc.&lt;/p&gt;

&lt;p&gt;Particularly, I think a really convenient way to deploy your apps in no time is using Platform as a Service (PaaS) options like &lt;a href="https://www.heroku.com/"&gt;Heroku&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Heroku is a platform that allows you to abstract yourself from all the complexity that comes from deploying and maintaining an app, and to focus your efforts on the app you want to build. Here's a &lt;a href="https://www.youtube.com/watch?v=_N8Zf_nPZkQ&amp;amp;feature=emb_logo&amp;amp;ab_channel=Heroku"&gt;video&lt;/a&gt; from Heroku's Greg Nokes explaining the concept behind their platform.&lt;/p&gt;

&lt;p&gt;Heroku has this idea of &lt;a href="https://devcenter.heroku.com/articles/buildpacks"&gt;buildpacks&lt;/a&gt;, which transform your code into a slug that can be run on their platform and abstract all the complexity.&lt;/p&gt;

&lt;p&gt;They support a small range of popular programming languages using these buildpacks, however Elixir is not one of them.&lt;/p&gt;

&lt;p&gt;But not all hope is lost, we have the ability to use custom buildpacks to support it ourselves. And there is &lt;a href="https://github.com/HashNuke/heroku-buildpack-elixir"&gt;one already available&lt;/a&gt; that Akash Manohar and his contributors built for us.&lt;/p&gt;

&lt;p&gt;If this is all new for you, don't worry, we're going to start putting up the pieces together in a bit.&lt;/p&gt;

&lt;p&gt;Let's build a very small app using Elixir that queries an open API and displays the data via HTTP in a JSON format.&lt;/p&gt;

&lt;p&gt;Before you get started, you'll need a Heroku account. You can create a new one for free at &lt;a href="https://signup.heroku.com/"&gt;heroku.com&lt;/a&gt;, and there's a free tier we can use for our development projects.&lt;/p&gt;

&lt;p&gt;If you're not too familiar with Elixir, you can check my &lt;a href="https://rarias.dev/hello-world-elixir/"&gt;hello-world-elixir&lt;/a&gt; article to give you an overview.&lt;/p&gt;

&lt;p&gt;This article will be divided into 5 parts&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creating your Elixir app skeleton.&lt;/li&gt;
&lt;li&gt;Writing the basic functionality.&lt;/li&gt;
&lt;li&gt;Testing it works locally.&lt;/li&gt;
&lt;li&gt;Creating your Heroku app.&lt;/li&gt;
&lt;li&gt;Deploying and testing your app.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Creating your Elixir app skeleton
&lt;/h2&gt;

&lt;p&gt;There are multiple ways to create an Elixir app. You could use one of the available frameworks or you could potentially create the files yourself one by one for example. In this exercise, we'll use the convenient &lt;a href="https://hexdocs.pm/mix/Mix.Tasks.New.html"&gt;mix new&lt;/a&gt; helper that will create most of the initial structure for us.&lt;/p&gt;

&lt;p&gt;Go to your project folder on your shell, then type &lt;code&gt;mix new simple_app --sup&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ mix new simple_app &lt;span class="nt"&gt;--sup&lt;/span&gt;
&lt;span class="k"&gt;*&lt;/span&gt; creating README.md
&lt;span class="k"&gt;*&lt;/span&gt; creating .formatter.exs
&lt;span class="k"&gt;*&lt;/span&gt; creating .gitignore
&lt;span class="k"&gt;*&lt;/span&gt; creating mix.exs
&lt;span class="k"&gt;*&lt;/span&gt; creating lib
&lt;span class="k"&gt;*&lt;/span&gt; creating lib/simple_app.ex
&lt;span class="k"&gt;*&lt;/span&gt; creating lib/simple_app/application.ex
&lt;span class="k"&gt;*&lt;/span&gt; creating &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="k"&gt;*&lt;/span&gt; creating &lt;span class="nb"&gt;test&lt;/span&gt;/test_helper.exs
&lt;span class="k"&gt;*&lt;/span&gt; creating &lt;span class="nb"&gt;test&lt;/span&gt;/simple_app_test.exs

Your Mix project was created successfully.
You can use &lt;span class="s2"&gt;"mix"&lt;/span&gt; to compile it, &lt;span class="nb"&gt;test &lt;/span&gt;it, and more:

    &lt;span class="nb"&gt;cd &lt;/span&gt;simple_app
    mix &lt;span class="nb"&gt;test

&lt;/span&gt;Run &lt;span class="s2"&gt;"mix help"&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;more commands.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a basic skeleton for your app, including a module called &lt;code&gt;SimpleApp&lt;/code&gt; and a basic supervisor.&lt;br&gt;
Make sure to check your version of Elixir. Syntax and structure might differ slightly on different versions. I'm using 1.11.3 for the following exercise.&lt;/p&gt;

&lt;p&gt;Let's go ahead and compile our app first to test the hello method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ &lt;span class="nb"&gt;cd &lt;/span&gt;simple_app
❯ mix compile
Compiling 2 files &lt;span class="o"&gt;(&lt;/span&gt;.ex&lt;span class="o"&gt;)&lt;/span&gt;
Generated simple_app app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use the interactive console to test manually or just use &lt;code&gt;mix test&lt;/code&gt; to use the test suite&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ iex &lt;span class="nt"&gt;-S&lt;/span&gt; mix
Erlang/OTP 23 &lt;span class="o"&gt;[&lt;/span&gt;erts-11.1.7]

Interactive Elixir &lt;span class="o"&gt;(&lt;/span&gt;1.11.3&lt;span class="o"&gt;)&lt;/span&gt; - press Ctrl+C to &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;type &lt;/span&gt;h&lt;span class="o"&gt;()&lt;/span&gt; ENTER &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="nb"&gt;help&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
iex&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; SimpleApp.hello&lt;span class="o"&gt;()&lt;/span&gt;
:world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By typing &lt;code&gt;SimpleApp.hello()&lt;/code&gt; we are invoking the &lt;code&gt;hello&lt;/code&gt; method created by the helper and we should get a symbol &lt;code&gt;:world&lt;/code&gt; in return if everything is set up correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Writing the basic functionality
&lt;/h2&gt;

&lt;p&gt;For this app, we'll use the public &lt;a href="https://www.coindesk.com/coindesk-api"&gt;API of Coindesk&lt;/a&gt; to query the price of Bitcoin today. If you'd rather prefer to use a different API, you can find a list of public ones on this &lt;a href="https://github.com/public-apis/public-apis#cryptocurrency"&gt;Github repo&lt;/a&gt;. The data that we're getting is really not that important for the purpose of this exercise.&lt;/p&gt;

&lt;p&gt;Before continuing however, you may want to check the API you choose is operational and to check the format of the returned data. I'd use &lt;code&gt;curl&lt;/code&gt; in my shell, but &lt;code&gt;wget&lt;/code&gt;, Postman or any other UI client should do the trick.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ curl https://api.coindesk.com/v1/bpi/currentprice.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To integrate the API via Elixir let's use the HTTP wrapper &lt;a href="https://github.com/teamon/tesla"&gt;Tesla&lt;/a&gt;. There are many good options out there, such as the good old &lt;a href="https://github.com/edgurgel/httpoison"&gt;Httpoison&lt;/a&gt;. However, Tesla has some added benefits. I won't go into details as it's not the purpose of this article, but it's worth checking out.&lt;/p&gt;

&lt;p&gt;To install Tesla, we need to first add the dependency to our &lt;code&gt;mix.exs&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;deps&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:tesla&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 1.4.0"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:hackney&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 1.16.0"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:jason&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 1.0.0"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that I also included &lt;code&gt;hackney&lt;/code&gt; and &lt;code&gt;jason&lt;/code&gt;. We'll use Hackey as the adapter to actually perform our http calls. Tesla uses &lt;code&gt;httpc&lt;/code&gt; as the default adapter, but Hackney is far better in many aspects.&lt;/p&gt;

&lt;p&gt;We'll need &lt;code&gt;jason&lt;/code&gt; too as it's a required JSON parser for our middleware. It's also more performant than other JSON parsers so it's good to have anyway.&lt;/p&gt;

&lt;p&gt;Go back to your shell and install the newly added dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ mix deps.get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may not have &lt;code&gt;hex&lt;/code&gt; installed in your system yet, so if you get prompted an option to do it, just say yes.&lt;/p&gt;

&lt;p&gt;The last part of the Tesla setup is adding the adapter to our config file. If you haven't created the file yet, just put it under &lt;code&gt;config/config.exs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can then add the Hackney adapter so your config file should look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Mix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Config&lt;/span&gt;

&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="ss"&gt;:tesla&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;adapter:&lt;/span&gt; &lt;span class="no"&gt;Tesla&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Adapter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Hackney&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it, we're done configuring. Throw in a &lt;code&gt;mix compile&lt;/code&gt; for good measure, to make sure we're still good to go and we haven't made any typos.&lt;/p&gt;

&lt;h3&gt;
  
  
  The API calling class
&lt;/h3&gt;

&lt;p&gt;To query the Coinbase API via Tesla, we're going to create a model.&lt;/p&gt;

&lt;p&gt;I like to have business logic inside a models folder because it helps me keep things organised on larger projects. Go ahead and create &lt;code&gt;lib/models/coinbase.ex&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Inside it we'll need 3 things, our module definition, our Tesla middleware configuration and the method(s) we want to abstract.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Coinbase&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@moduledoc&lt;/span&gt; &lt;span class="sd"&gt;"""  
  A module abstraction used to interact with the coinbase http API  
  """&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Tesla&lt;/span&gt;

  &lt;span class="n"&gt;plug&lt;/span&gt; &lt;span class="no"&gt;Tesla&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Middleware&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;BaseUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"https://api.coindesk.com"&lt;/span&gt;
  &lt;span class="n"&gt;plug&lt;/span&gt; &lt;span class="no"&gt;Tesla&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Middleware&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
  &lt;span class="n"&gt;plug&lt;/span&gt; &lt;span class="no"&gt;Tesla&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Middleware&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;JSON&lt;/span&gt;

  &lt;span class="nv"&gt;@doc&lt;/span&gt; &lt;span class="sd"&gt;"""  
  Returns the Bitcoin Price Index from coinbase  
  """&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;bpi_current_price&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/v1/bpi/currentprice.json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can test this right away in our &lt;code&gt;iex&lt;/code&gt; console&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ iex &lt;span class="nt"&gt;-S&lt;/span&gt; mix
Erlang/OTP 23

Interactive Elixir &lt;span class="o"&gt;(&lt;/span&gt;1.11.3&lt;span class="o"&gt;)&lt;/span&gt; - press Ctrl+C to &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;type &lt;/span&gt;h&lt;span class="o"&gt;()&lt;/span&gt; ENTER &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="nb"&gt;help&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
iex&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; Coinbase.bpi_current_price
&lt;span class="o"&gt;{&lt;/span&gt;:ok,
 %Tesla.Env&lt;span class="o"&gt;{&lt;/span&gt;
   __client__: %Tesla.Client&lt;span class="o"&gt;{&lt;/span&gt;adapter: nil, fun: nil, post: &lt;span class="o"&gt;[]&lt;/span&gt;, pre: &lt;span class="o"&gt;[]}&lt;/span&gt;,
   __module__: Coinbase,
   body: ...,
   headers: &lt;span class="o"&gt;[&lt;/span&gt;
     ...
   &lt;span class="o"&gt;]&lt;/span&gt;,
   method: :get,
   opts: &lt;span class="o"&gt;[]&lt;/span&gt;,
   query: &lt;span class="o"&gt;[]&lt;/span&gt;,
   status: 200,
   url: &lt;span class="s2"&gt;"https://api.coindesk.com/v1/bpi/currentprice.json"&lt;/span&gt;
 &lt;span class="o"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Displaying the data
&lt;/h3&gt;

&lt;p&gt;With our base model done, the last thing we need is something to display the data in an easy to read format.&lt;/p&gt;

&lt;p&gt;We are going to be using the light http server &lt;a href="https://github.com/ninenines/cowboy"&gt;Cowboy&lt;/a&gt; and the adapter &lt;a href="https://github.com/elixir-plug/plug"&gt;Plug&lt;/a&gt; to return our data.&lt;/p&gt;

&lt;p&gt;Exploring the different server options and frameworks along with their pros and cons is out of the scope of this article, so we'll stick with the simplest solution.&lt;/p&gt;

&lt;p&gt;Let's go back to our &lt;code&gt;mix.exs&lt;/code&gt; file to add Plug and Cowboy to our dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; defp deps &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;:tesla, &lt;span class="s2"&gt;"~&amp;gt; 1.4.0"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;{&lt;/span&gt;:hackney, &lt;span class="s2"&gt;"~&amp;gt; 1.16.0"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;{&lt;/span&gt;:jason, &lt;span class="s2"&gt;"&amp;gt;= 1.0.0"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="o"&gt;{&lt;/span&gt;:plug_cowboy, &lt;span class="s2"&gt;"~&amp;gt; 2.0"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="c"&gt;# NEW!&lt;/span&gt;
        ...
    &lt;span class="o"&gt;]&lt;/span&gt;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Get those deps, compile the project and we're ready to move forward&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ mix deps.get
❯ mix compile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, without caring for organisation too much, let's add a little router file that will expose our endpoint to the world and call the API we've created previously.&lt;/p&gt;

&lt;p&gt;Go ahead and create &lt;code&gt;lib/router.ex&lt;/code&gt; and define a basic Plug endpoint&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;SimpleAppRouter&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Plug&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Router&lt;/span&gt;

  &lt;span class="n"&gt;plug&lt;/span&gt; &lt;span class="ss"&gt;:match&lt;/span&gt;
  &lt;span class="n"&gt;plug&lt;/span&gt; &lt;span class="ss"&gt;:dispatch&lt;/span&gt;

  &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s2"&gt;"/bpi"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;send_resp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"BPI price coming soon..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;send_resp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Wrong place mate"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're not familiar with it, feel free to check the inner workings of Plug in their &lt;a href="https://github.com/elixir-plug/plug"&gt;documentation&lt;/a&gt;. For now, the code above is fairly self-explanatory I hope. All we need to know is that we're using the &lt;code&gt;Plug.Router&lt;/code&gt; capabilities and exposing an endpoint &lt;code&gt;/bpi&lt;/code&gt; which we're going to use to retrieve our data and to show it.&lt;/p&gt;

&lt;p&gt;We can now proceed to tell our supervision tree that our Router is ready to roll.&lt;/p&gt;

&lt;p&gt;Go to the &lt;code&gt;lib/simple_app/application.ex&lt;/code&gt; where you'll find the application file created by the &lt;code&gt;mix new&lt;/code&gt; helper. Here we will ask our application to start the router under the supervision tree.&lt;/p&gt;

&lt;p&gt;Your resulting file will look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;SimpleApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Application&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="c1"&gt;# See https://hexdocs.pm/elixir/Application.html&lt;/span&gt;
  &lt;span class="c1"&gt;# for more information on OTP Applications&lt;/span&gt;
  &lt;span class="nv"&gt;@moduledoc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Application that starts the http router for `SimpleApp`.
  """&lt;/span&gt;

  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Application&lt;/span&gt;

  &lt;span class="nv"&gt;@impl&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Plug&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Cowboy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;scheme:&lt;/span&gt; &lt;span class="ss"&gt;:http&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;plug:&lt;/span&gt; &lt;span class="no"&gt;SimpleAppRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;options:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;port:&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# See https://hexdocs.pm/elixir/Supervisor.html&lt;/span&gt;
    &lt;span class="c1"&gt;# for other strategies and supported options&lt;/span&gt;
    &lt;span class="n"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;strategy:&lt;/span&gt; &lt;span class="ss"&gt;:one_for_one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="no"&gt;SimpleApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can go ahead and test it all works fine by running your server with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="err"&gt;❯&lt;/span&gt; &lt;span class="n"&gt;mix&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;halt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To display the Coinbase data, all we need to do is go back to our &lt;code&gt;SimpleAppRouter&lt;/code&gt; and add the Coinbase call. Your router function will then look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s2"&gt;"/bpi"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;send_resp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Coinbase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bpi_current_price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you remember the format of the &lt;code&gt;bpi_current_price&lt;/code&gt; function response, you may have noticed that it includes not only the body of the response but also headers, process status etc which we don't necessarily want to display. So to fix this, go back to &lt;code&gt;lib/models/coinbase.ex&lt;/code&gt; and modify the function to only return the response body instead&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;bpi_current_price&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/v1/bpi/currentprice.json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bear in mind we're not doing any sort of validations or error considerations for the sake of simplicity.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Testing it works locally
&lt;/h2&gt;

&lt;p&gt;Now with the app finally ready, we can test it works in our local environment.&lt;/p&gt;

&lt;p&gt;Go ahead and run your server again&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ mix run &lt;span class="nt"&gt;--no-halt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in your browser or curl client, you should be able to obtain the results on &lt;a href="http://localhost:8080/bpi"&gt;&lt;code&gt;http://localhost:8080/bpi&lt;/code&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ curl http://localhost:8080/bpi
HTTP/1.1 200 OK
...
server: Cowboy

&lt;span class="o"&gt;{&lt;/span&gt; ...&lt;span class="s2"&gt;"chartName"&lt;/span&gt;:&lt;span class="s2"&gt;"Bitcoin"&lt;/span&gt;,&lt;span class="s2"&gt;"bpi"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"USD"&lt;/span&gt;:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"code"&lt;/span&gt;:&lt;span class="s2"&gt;"USD"&lt;/span&gt;... &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Creating your Heroku app
&lt;/h2&gt;

&lt;p&gt;Before we move entirely into the Heroku app creation, there's one last thing we need to change in the code. &lt;/p&gt;

&lt;p&gt;Notice how we used port &lt;code&gt;8080&lt;/code&gt; as the default, but once in Heroku our app port will be dynamic and determined by them. For this reason, we need to read the port from the environment variables.&lt;/p&gt;

&lt;p&gt;To do this, go ahead and update the port 8080 inside the application file with one taken from the system environment variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;Plug&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Cowboy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="ss"&gt;scheme:&lt;/span&gt; &lt;span class="ss"&gt;:http&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="ss"&gt;plug:&lt;/span&gt; &lt;span class="no"&gt;SimpleAppRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="ss"&gt;options:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;port:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"PORT"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;"8080"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_integer&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This has the added benefit of defaulting to 8080 if the &lt;code&gt;PORT&lt;/code&gt; environment variable does not exist, which is convenient when using it locally.&lt;/p&gt;

&lt;p&gt;To create our Heroku app we're going to be using the &lt;a href="https://devcenter.heroku.com/articles/heroku-cli"&gt;heroku-cli&lt;/a&gt;. However, if you feel more comfortable using an UI, you can go to your &lt;a href="https://dashboard.heroku.com/apps"&gt;Heroku dashboard&lt;/a&gt; and the steps are pretty straightforward.&lt;/p&gt;

&lt;p&gt;The first thing you need is a Heroku account, which I'm going to assume you already have. If you don't, just sign up on their &lt;a href="https://www.heroku.com/"&gt;website&lt;/a&gt; using your preferred email and password.&lt;/p&gt;

&lt;p&gt;PRO TIP: If you happen to have an existing Heroku account that you do not want &lt;br&gt;
to use for this exercise, you can use the &lt;a href="https://github.com/heroku/heroku-accounts"&gt;heroku-accounts&lt;/a&gt; plugin to manage&lt;br&gt;
multiple accounts easily.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;PRO TIP: If you happen to have an existing Heroku account that you do not want 
to use for this exercise, you can use the &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;heroku-accounts&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://github.com/heroku/heroku-accounts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; plugin to manage
multiple accounts easily. 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a new Heroku app using the cli, just go to the root directory of your app in the shell and type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ heroku create simple-app-elixir
Creating ⬢ simple-app-elixir... &lt;span class="k"&gt;done
&lt;/span&gt;https://simple-app-elixir.herokuapp.com/ | https://git.heroku.com/simple-app-elixir.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;simple-app-elixir&lt;/code&gt; is a unique name you want to give to your app.&lt;/p&gt;

&lt;p&gt;Because Heroku doesn't have any default buildpack for Elixir at the time of writing, we need to set our app's buildpack to HashNuke's version of it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ heroku buildpacks:set &lt;span class="se"&gt;\&lt;/span&gt;
  https://github.com/HashNuke/heroku-buildpack-elixir.git &lt;span class="nt"&gt;-a&lt;/span&gt; simple-app-elixir
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this buildpack to work in production, we need to specify a default configuration on our Heroku app. In the root of the project go ahead and create a file named &lt;code&gt;elixir_buildpack.config&lt;/code&gt; and fill it with your versions of the OTP and Elixir.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;erlang_version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;23.0
&lt;span class="nv"&gt;elixir_version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.11
&lt;span class="nv"&gt;always_rebuild&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false
&lt;/span&gt;&lt;span class="nv"&gt;runtime_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last thing we need to do is to tell Heroku what process to run when deploying the app. For this we can use a &lt;code&gt;Procfile&lt;/code&gt;. In our Procfile we will specify that we want &lt;code&gt;mix&lt;/code&gt; to run our app which in turn will run the Cowboy server.&lt;/p&gt;

&lt;p&gt;Create another file at the root of your project called &lt;code&gt;Procfile&lt;/code&gt; (without any file extension), and add the following inside it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;web: mix run &lt;span class="nt"&gt;--no-halt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice this is the same command that we use to run our server locally. The buildpack will actually use this same command as default if no Profile is found, but it's good practice to define it ourselves anyway.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Deploying and testing your app
&lt;/h2&gt;

&lt;p&gt;Now we're ready to deploy. Heroku has a &lt;code&gt;git&lt;/code&gt; based deployment system, which is really convenient because all we need to do to deploy our app is to &lt;code&gt;git push&lt;/code&gt; our code.&lt;/p&gt;

&lt;p&gt;In your shell, at the root of your project, go ahead and commit your code to Heroku as if it was another regular git repository. &lt;br&gt;
You may need to add your Heroku remote using your own git URL&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; ❯ git remote add heroku &lt;span class="o"&gt;[&lt;/span&gt;https://git.heroku.com/simple-app-elixir.git]&lt;span class="o"&gt;(&lt;/span&gt;https://git.heroku.com/simple-app-elixir.git&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yours was printed when creating the app, or it can also be found in the settings of your Heroku app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# If you haven't initialised the repository yet&lt;/span&gt;
❯ git init
Initialized empty Git repository

&lt;span class="c"&gt;# Commit your code&lt;/span&gt;
❯ git add &lt;span class="nb"&gt;.&lt;/span&gt;
❯ git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"SimpleApp initial commit. Coinbase API"&lt;/span&gt;
❯ git push heroku master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should've deployed your app if your setup is correct, SSH keys are set and there aren't any additional configuration issues.&lt;/p&gt;

&lt;p&gt;Once your code is deployed, Heroku will assign a subdomain to your app, something like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;https://simple-app-elixir.herokuapp.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on the time you're reading this article, mine may or may not be active. Either way, once yours is deployed you should be able to check it out.&lt;/p&gt;

&lt;p&gt;You can go ahead and test our &lt;code&gt;/bpi&lt;/code&gt; endpoint in the browser or via curl.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ curl https://simple-app-elixir.herokuapp.com/bpi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This endpoint should return a json object with the Coinbase Bitcoin exchange rates and your deployment would be complete. Congrats! 👏&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As you can see, it's fairly simple to deploy Elixir apps in Heroku. The platform allows for scaling as you go and it's able to handle Elixir's performance requirements very well.&lt;/p&gt;

&lt;p&gt;Another advantage of Heroku is that you can have apps in multiple languages running all under the same umbrella platform, which lets you have complex microservices architectures servicing different needs without any additional platform knowledge required.&lt;/p&gt;

&lt;p&gt;I've put a full working version of the code on this &lt;a href="https://github.com/ronald05arias/simple-app-elixir"&gt;Github repository&lt;/a&gt;, in case you want to compare with it or simply clone it and test it.&lt;/p&gt;

&lt;p&gt;For more topics, check my &lt;a href="https://dev.to/ronald_arias"&gt;profile&lt;/a&gt; or visit &lt;a href="//rarias.dev"&gt;rarias.dev&lt;/a&gt;.&lt;br&gt;
Happy coding!&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>computerscience</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Why you should learn multiple Programming Languages</title>
      <dc:creator>Ron</dc:creator>
      <pubDate>Fri, 05 Feb 2021 16:40:29 +0000</pubDate>
      <link>https://dev.to/ronald_arias/why-you-should-learn-multiple-programming-languages-26k6</link>
      <guid>https://dev.to/ronald_arias/why-you-should-learn-multiple-programming-languages-26k6</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftnsxcxl7yeh9s02684n5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftnsxcxl7yeh9s02684n5.jpg" alt="Why-learning-programming-lang"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Disclaimer: This is not an article to teach you a quick hack on how to learn multiple programming languages, but an analysis on its advantages. Soz!&lt;/p&gt;

&lt;p&gt;If you have a career as a Software Developer, chances are you already know more than one programming language. If you're a specialised Frontend Developer, you may know Javascript and Typescript for example. If you're a specialised Backend Developer, you may prefer Java but know a thing or two about Python or C++. If you're a "Full Stack" Developer your odds of knowing more than one are higher.&lt;/p&gt;

&lt;p&gt;My point is that you may already fit the basic definition of knowing more than one programming language.&lt;/p&gt;

&lt;p&gt;For the purpose of this article, I want to extend this definition a little bit to focus on not just knowing but actively seeking to solve problems with more than one programming language.&lt;/p&gt;

&lt;p&gt;This is what it's commonly known as being "Programming Language Agnostic".&lt;/p&gt;

&lt;p&gt;The idea behind it is that as Software Engineers we are meant to solve the problems we encounter using the best tool for the job. It makes sense if you think about it. Why would you limit yourself to only a few available options?&lt;/p&gt;

&lt;p&gt;Before I carry on to explain why this approach is better in my opinion, I want to make a few clarifications:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;There are plenty of scenarios in which expertise and knowing the intrinsic details of a particular technology is the best approach. If you want to build a career as a consultant and target a very specific market for example, it makes sense for you to not look around much.&lt;/li&gt;
&lt;li&gt;Not everyone has the flexibility to choose the programming language they want to work with a lot of times. There are real infrastructure or cost limitations that may prevent you from doing so.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, for the rest of you out there, here's the approach I'm talking about.&lt;/p&gt;

&lt;p&gt;With the growth in popularity of microservice architectures and cloud hosting, it's easier than ever to have hybrid infrastructures, which allows you to pick different tools to solve the problems at hand.&lt;/p&gt;

&lt;p&gt;I'm not entirely sure how many people out there take advantage of this flexibility, but my wild guess would be that most don't fully consider the possibilities of this setup.&lt;/p&gt;

&lt;p&gt;What is the solution going to look like if you only know one or two programming languages? As the saying goes "If you only have a hammer, everything looks like a nail".&lt;/p&gt;

&lt;p&gt;Let's see how a potential problem solving session might look like in a scenario when we're open minded about picking the best tool for the job, independently of how familiar or comfortable we feel with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Suppose you want to build an algorithmic trading application. This app will need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gather data from different financial APIs in real time.&lt;/li&gt;
&lt;li&gt;Parse, process and store this data.&lt;/li&gt;
&lt;li&gt;Retrieve this data to apply backtesting strategies.&lt;/li&gt;
&lt;li&gt;Run your strategy in real time and trigger alerts for your users to trade.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NOTE: This is just an educational example. The solutions suggested are for illustration purposes and may not be the most optimal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approaching the problem
&lt;/h2&gt;

&lt;p&gt;If you want to have a monolithic application, there's less flexibility around the tools you can use, but if you decide to work in a microservices environment, approaching the problem gives you a lot of options and freedom.&lt;/p&gt;

&lt;p&gt;If you are a Python developer for example, or Python is your preferred programming language, you can potentially build this whole application in a Python stack.&lt;/p&gt;

&lt;p&gt;Similarly if you're a Java developer, a Ruby developer, a Golang developer etc. You get the point.&lt;/p&gt;

&lt;p&gt;But approaching the problem without thinking about the language will let you pick the best one that fits the criteria.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gathering &amp;amp; storing the data
&lt;/h3&gt;

&lt;p&gt;In our little language agnostic world, our problem of gathering the data becomes one that requires a lot of concurrency.&lt;/p&gt;

&lt;p&gt;If you hit the APIs sequentially, this will be incredibly slow. So you'll need a tool that's really good at concurrency and parallelism but also allows you to deal with HTTP requests and data manipulation easily.&lt;/p&gt;

&lt;p&gt;Perhaps you've heard of &lt;a href="https://rarias.dev/hello-world-elixir/" rel="noopener noreferrer"&gt;Elixir&lt;/a&gt;. It is known that this language was built thinking about powerful concurrency, so it makes sense for us to consider it. This is not the only one of course, so keep your options open.&lt;/p&gt;

&lt;p&gt;Now, we can perhaps build a small application with Elixir, that leverages the concurrency and hits the APIs with a high number of threads and collects that data for us at regular intervals.&lt;/p&gt;

&lt;p&gt;At the same time we're collecting the data, we can either store it right away, or send it down a pipeline for someone else to process it. This will depend on how scalable you want to be.&lt;/p&gt;

&lt;p&gt;For now, let's say we send this data down a pipeline using something like &lt;a href="https://kafka.apache.org/intro" rel="noopener noreferrer"&gt;Apache Kafka&lt;/a&gt; as soon as we've retrieved it. This will reduce the efforts of the API crawler and delegate the storing of the data to someone else.&lt;/p&gt;

&lt;h3&gt;
  
  
  Backtesting
&lt;/h3&gt;

&lt;p&gt;This is the most passive option of all. You do not need anything with great real time performance, but a language or tool that's really good at data manipulation.&lt;/p&gt;

&lt;p&gt;Perhaps &lt;a href="https://rarias.dev/hello-world-python/" rel="noopener noreferrer"&gt;Python&lt;/a&gt; is a great option here? You can use it to a great extent to read large amounts of data and apply mathematical models and test different strategies with it. Depending on the amount of data you have you can even throw in tools like &lt;a href="https://spark.apache.org/" rel="noopener noreferrer"&gt;Apache Spark&lt;/a&gt; in the mix to help you out.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running your strategy in real time
&lt;/h3&gt;

&lt;p&gt;Here's where you need a language that is very good with IO operations. You want to be as real time as you can to let your users make the best decisions.&lt;/p&gt;

&lt;p&gt;You then may decide that a combination of Javascript/Nodejs with a tool like &lt;a href="https://firebase.google.com/" rel="noopener noreferrer"&gt;Firebase&lt;/a&gt; for example might do the trick.&lt;/p&gt;

&lt;p&gt;If you design your infrastructure the right way, you can perhaps even read the events from your Kafka queue straight away and send it to the users connecting 2 completely different technologies via the Kafka events queue.&lt;/p&gt;

&lt;p&gt;As you can see, at a higher level we can already start including many different programming languages in the mix to build the best possible solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  How much of each language do you need to know?
&lt;/h2&gt;

&lt;p&gt;You may be wondering now that building that whole stack will require a team of developers, with expertise in different areas and each one specialised in each of those technologies.&lt;/p&gt;

&lt;p&gt;But the reality is far from it.&lt;/p&gt;

&lt;p&gt;To be able to build hybrid infrastructures like these, you only need to know about the capabilities of a language very well. Of course, you'll have to learn the actual specifics of the language at some point, but for starters the capabilities are more than enough. You can get by with building your solution if you know what's possible and then replace parts conveniently later.&lt;/p&gt;

&lt;p&gt;I am particularly bad at remembering things for example, but I routinely work and build apps on top of at least 3 or 4 very different programming languages almost daily. What allows me to do so is a combination of&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Knowing what the language is capable of.&lt;/li&gt;
&lt;li&gt;Always having the documentation at hand. I don't have to remember the exact syntax and methods libraries as long as I can look it up.&lt;/li&gt;
&lt;li&gt;Best practice guides.&lt;/li&gt;
&lt;li&gt;Good understanding of the basic paradigm of the language, is it OO or functional? How far can I push it? How performant is it? At what point does it start to break?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Just like Scott Adams, creator of Dilbert says, you don't have to be a world class expert on any particular one skill, but a combination of many average skills can turn you into someone awesome.&lt;/p&gt;

&lt;p&gt;Same applies for programming languages, you don't have to be an expert in one or all of them. For the average Software Engineer, being fairly good in a few will give you far more leverage to build great applications that you imagine.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to know you've made the right choice
&lt;/h2&gt;

&lt;p&gt;After you've picked the programming language that best suits your solution, you need to start thinking about implementation.&lt;/p&gt;

&lt;p&gt;If you've never used the language you picked, it's better to start by testing a few of the principles you want to exploit first. Interactive shells are great for this purpose and most languages have them.&lt;/p&gt;

&lt;p&gt;Another thing to consider is the way you build your application, how far into the future can you see? Even though you've made (or think you've made) the right choice, it won't necessarily continue to be the right choice as time passes. &lt;/p&gt;

&lt;p&gt;Perhaps you picked Ruby as your general purpose language because you only needed to get a small amount of data processed and needed a solution fast and simple. This fits your purpose very well, but if you start seeing heavy growth in traffic and Ruby starts getting memory problems, then it's time to consider a replacement to better fit the new scenario.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is it difficult to change your mind and pick another language later?
&lt;/h3&gt;

&lt;p&gt;This will depend on how you've built your system. The best way is to have services (or micro-services) as isolated as possible with a common interface between them.&lt;/p&gt;

&lt;p&gt;For example, if you use an HTTP API to exchange JSON messages, or a Kafka queue, you should design your service in a way that the data coming in and going out doesn't get influenced by the programming language underneath.&lt;/p&gt;

&lt;p&gt;This way, if your service needs replacing with a completely different programming language, you can basically plug and play without disrupting other dependencies.&lt;/p&gt;

&lt;p&gt;Even though you may make an effort of reducing dependencies between your services, you can get away with the better approach of abstracting communication instead, and finding a common efficient way to exchange messages that doesn't depend on the underlying language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There's no one single solution to every problem, and there's no need to use a single programming language to find that solution.&lt;/p&gt;

&lt;p&gt;Learning more than one language gives you the tools to think about possibilities you didn't consider previously.&lt;/p&gt;

&lt;p&gt;Limitations of a technology are no longer a limitation. This way, you start looking at programming languages as great tools with pros and shortcomings.&lt;/p&gt;

&lt;p&gt;There's almost always going to be a preferred language, particularly for general purpose applications, and that's fine as long as you know when it's ok to use it and its shortcomings, and more importantly, you're willing to pick a better one when it's appropriate to do so.&lt;br&gt;
Happy coding!&lt;br&gt;
For more topics, check my profile or visit &lt;a href="//rarias.dev"&gt;rarias.dev&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>computerscience</category>
      <category>beginners</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Hello World - Python</title>
      <dc:creator>Ron</dc:creator>
      <pubDate>Fri, 29 Jan 2021 11:58:21 +0000</pubDate>
      <link>https://dev.to/ronald_arias/hello-world-python-4me0</link>
      <guid>https://dev.to/ronald_arias/hello-world-python-4me0</guid>
      <description>&lt;p&gt;Python is a programming language that has been around for quite a while and that has so much to offer. Since its inception about 30 years ago Python has come a long way, as well as being on and off fashion in many opportunities.&lt;/p&gt;

&lt;p&gt;Nowadays, Python has experienced a big boom due to the rising popularity of Machine Learning and the introduction of easy to use tools aimed at exploiting Python’s capabilities in this area.&lt;/p&gt;

&lt;p&gt;So, what’s Python about anyway?&lt;/p&gt;

&lt;p&gt;Python is actually a general purpose programming language, it’s interpreted and object oriented and its syntax is quite easy to read. It has a huge community behind it, for which it’s easy to find a solution to basically any problem you encounter with it.&lt;/p&gt;

&lt;p&gt;You may find that there’s a lot of chatter focused on the specific version you use, whether it’s Python 2 or Python 3. That’s because in the late 2000s Python 3 was introduced, which represented a major jump from its predecessor line Python 2.x and it came with actual incompatibilities.&lt;/p&gt;

&lt;p&gt;A lot of things were deprecated, and a bunch of others were introduced. Unfortunately for the Python community this caused a lot of issues. There were already many apps running Python 2, and the transition wasn’t as easy as you may have wanted.&lt;/p&gt;

&lt;p&gt;To this day, there are still a lot of apps and libraries running and depending on the previous version, and developers need to keep this in mind when using the language.&lt;/p&gt;

&lt;p&gt;Fortunately for us, just like in many other languages like &lt;a href="https://rarias.dev/hello-world-ruby/#ruby-version-manager"&gt;Ruby&lt;/a&gt; or &lt;a href="https://rarias.dev/hello-world-elixir/#elixir-version-manager"&gt;Elixir&lt;/a&gt;, Python also has version and environment managers nowadays, which helps keeping track of different versions and sets of libraries within our projects.&lt;/p&gt;

&lt;p&gt;This article is going to be divided into 3 sections: Installation, Basics and Capabilities. Within the capabilities however, there's an incredibly long list, especially in the Machine Learning and Lambda architecture areas that I will discuss in more detail later in different posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;How easy or simple the installation process is will depend on your operating system and what other dependencies you may already have in your system.&lt;/p&gt;

&lt;p&gt;If you’re a developer like me who uses other programming languages and tools, or if you’re on an older version of MacOS, you may already have installed dependencies that require either Python 2 or 3.&lt;/p&gt;

&lt;p&gt;I will describe the installation process of one of the simplest methods I know, but be aware that you may encounter some resistance on the way. Should you do so, feel free to &lt;a href="https://rarias.dev/about-me/#:~:text=email%3A-,contact%40rarias.dev,-Find"&gt;drop me a line&lt;/a&gt; and I'll do my best to help you get up and running.&lt;/p&gt;

&lt;p&gt;First thing to keep in mind is that you do not want any of the built-in installations of Python running the show underneath, so the best approach is to use a version manager.&lt;/p&gt;

&lt;p&gt;Probably the less intrusive Python version manager out there is &lt;a href="https://github.com/pyenv/pyenv"&gt;Pyenv&lt;/a&gt;. Unlike others, Pyenv does not depend on Python itself as it's built entirely with shell-scripts. This is a nice thing to have.&lt;/p&gt;

&lt;p&gt;There are multiple ways to install Pyenv, you can check their &lt;a href="https://github.com/pyenv/pyenv#installation"&gt;installation&lt;/a&gt; page for more information. If you're on MacOS, the easiest way is to use &lt;a href="https://brew.sh/"&gt;homebrew&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can install Pyenv using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; brew &lt;span class="nb"&gt;install &lt;/span&gt;pyenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can verify the installation was done correctly by typing &lt;code&gt;which pyenv&lt;/code&gt; in your shell.&lt;/p&gt;

&lt;p&gt;After this, you need to let your bash initiate pyenv on start. For this you can add the following init script to whatever shell you're using. &lt;/p&gt;

&lt;p&gt;In my case for &lt;code&gt;zsh&lt;/code&gt; I need to add it to my &lt;code&gt;.zshrc&lt;/code&gt;  but for you it could be &lt;code&gt;.bash_profile&lt;/code&gt; or &lt;code&gt;.bashrc&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; pyenv &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;pyenv init -&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will allow Pyenv to manipulate your path and give itself priority inside pyenv environments.&lt;/p&gt;

&lt;p&gt;With all these done, we can now set the global pyenv we want to work with.&lt;/p&gt;

&lt;p&gt;To see the available versions we have for installation, we can use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; pyenv &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--list&lt;/span&gt;
Available versions:
2.1.3
2.2.3
...
3.9.0
3.9-dev
3.9.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So let's go ahead and install version 3.9.1 and set it globally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; pyenv &lt;span class="nb"&gt;install &lt;/span&gt;3.9.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before you set it globally however, have a look at your current installation of python (if any) so you can see how the global version of Python is changed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; python &lt;span class="nt"&gt;--version&lt;/span&gt;
Python 2.7.16 &lt;span class="c"&gt;# You may see something well different, this is my MacOS system default&lt;/span&gt;

&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; pyenv global 3.9.1
&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; python &lt;span class="nt"&gt;--version&lt;/span&gt;
Python 3.9.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't see a version change, it may be that the init script hasn't been executed. You can try reloading your bash and checking again. &lt;/p&gt;

&lt;p&gt;That's it, now you have a fully running and updated Python interpreter, with the added ability of installing multiple different versions.&lt;/p&gt;

&lt;p&gt;Within projects however, it's best to also use environment managers like &lt;a href="https://pypi.org/project/pipenv/"&gt;pipenv&lt;/a&gt;. I will write in more detail about it in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basics
&lt;/h2&gt;

&lt;p&gt;Python is a really intuitive language, where most code (if done right) can be easily read as if you were reading a textbook.&lt;/p&gt;

&lt;p&gt;One main thing to consider is that Python does not have opening and closing blocks in the same way other programming languages do. For this, the language relies on indentation, so if a block is meant to be nested within another block, we indent it a tab further than the parent block. An example of this would be a typical function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;say_hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the print is a tab space within the function header and there's no closing statement like &lt;code&gt;end&lt;/code&gt; or &lt;code&gt;}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s test a few things in Python’s interactive console. Like other languages, Python offers an interactive console you can use to test things out. I particularly love them, as it saves me time when I’m unsure about a particular syntax or method. Often-time it’s faster to test it in the console rather than run tests, execute the program you’re writing or browse the documentation.&lt;/p&gt;

&lt;p&gt;However, when using recent development tools like &lt;a href="https://jupyter.org/"&gt;Jupyter notebooks,&lt;/a&gt; which are heavily used in Machine Learning, you get immediate feedback within the cells. This makes it faster than going back and forth from your development environment to the console.&lt;/p&gt;

&lt;p&gt;To start the interactive console, go to your shell and just type &lt;code&gt;python&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;
&lt;span class="n"&gt;Python&lt;/span&gt; &lt;span class="mf"&gt;3.9&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="s"&gt;"help"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"copyright"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"credits"&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="s"&gt;"license"&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;information&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bear in mind that the console should start in the version of Python that you've previously set as global default via &lt;code&gt;pyenv&lt;/code&gt;. If it doesn't, you may want to exit the console using the &lt;code&gt;exit()&lt;/code&gt; command and revise the reason why it's not selecting the right version.&lt;/p&gt;

&lt;p&gt;The built-in function in Python for console output is &lt;code&gt;print&lt;/code&gt;. That makes our first Hello World fairly easy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Hello&lt;/span&gt; &lt;span class="n"&gt;World&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python data types and operations don't differ much from other languages&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# There's simple arithmetic operations
&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="mi"&gt;10&lt;/span&gt;

&lt;span class="c1"&gt;# There are String concatenations
&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"World"&lt;/span&gt;
&lt;span class="s"&gt;'HelloWorld'&lt;/span&gt;

&lt;span class="c1"&gt;# And there are of course String-Integer operations
&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="s"&gt;'HelloHelloHelloHelloHello'&lt;/span&gt;

&lt;span class="c1"&gt;# Hold on, what?
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last one wasn't too intuitive, but it's pretty cool. Python is really flexible and allows you to use nifty tricks like multiplying a string against an integer to obtain many of them. There are plenty of cool examples like these, especially when you start using the &lt;a href="https://numpy.org/"&gt;numpy&lt;/a&gt; and &lt;a href="https://pandas.pydata.org/"&gt;pandas&lt;/a&gt; libraries, which supercharge Python into greatness.&lt;/p&gt;

&lt;p&gt;Functions in Python are also pretty similar to other languages, and if you break them down enough it can make your code even more readable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="mf"&gt;2.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is particularly useful when simplifying complex math operations. A type of function called a lambda, which is just an anonymous function, plays a big part as well in simplifying (or complicating if overusing) your code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;variance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;mean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;([(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;variance&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="mf"&gt;10.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may have noticed the way the values are processed in that last variance function, where the &lt;code&gt;for&lt;/code&gt; loop seems to have a very readable structure. That's a list comprehension and it's one of the easiest ways to go over lists in Python.&lt;/p&gt;

&lt;p&gt;The flexibility comes from being able to do mapping operations like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# The following will generate a new list in one pass of the array
&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but also to apply (usually more complex) functions to each value in the collection&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;addtwo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;addtwo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Capabilities
&lt;/h2&gt;

&lt;p&gt;I could write 100 articles listing Python capabilities (ok maybe not me, but someone really into the language), and it still won't be enough to cover it. It is such a versatile and powerful programming language that it can probably be used in any context.&lt;/p&gt;

&lt;p&gt;The most recent and popular uses for Python that I'm interested and fond of include Machine Learning and Serverless applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Machine Learning
&lt;/h3&gt;

&lt;p&gt;There are many reasons why Python has been chosen for Machine Learning. It's simple and easy to learn, which allows practitioners to focus on the problem rather than on the language, but at the same time there aren't many major tradeoffs in terms of performance.&lt;/p&gt;

&lt;p&gt;There's also a great amount of tools focused on Python that were recently open sourced, and allows for model building with ease.&lt;/p&gt;

&lt;p&gt;For many years as well, the Python community have been building Math oriented really powerful libraries that makes manipulating data, again, much easier than in other languages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Serverless applications
&lt;/h3&gt;

&lt;p&gt;Serverless gained popularity recently due to the fact that it offers a lot of abstraction and scalability to developers. In Serverless architectures, "servers" are not explicitly defined by the deployers, but rather we focus on particular functions that handle very specific events. &lt;/p&gt;

&lt;p&gt;Platforms such as &lt;a href="https://aws.amazon.com/lambda/"&gt;AWS Lambdas&lt;/a&gt; and &lt;a href="https://cloud.google.com/functions"&gt;Google Cloud Functions&lt;/a&gt; allow the writing and deployment of such functions with ease, and more importantly, they allow the systems to scale at will, providing more functions when needed (when server load increases for example) and being able to handle higher levels of concurrency without increasing code complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Python is a powerful yet simple language. There's a lot to learn within its environment, but having now an overview of the language and its capabilities, you can go ahead and get started experimenting with it.&lt;/p&gt;

&lt;p&gt;Whether you're interested in Machine Learning or building scalable applications, or simply scripting tasks with an easy to use programming language, Python has a lot to offer you and whatever path you decide to take, I'm sure it's going to be an enjoyable one.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;br&gt;
For more topics, check &lt;a href="https://dev.to/ronald_arias"&gt;my profile&lt;/a&gt; or visit &lt;a href="//rarias.dev"&gt;rarias.dev&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>python</category>
    </item>
    <item>
      <title>Hello World - Ruby</title>
      <dc:creator>Ron</dc:creator>
      <pubDate>Fri, 22 Jan 2021 12:27:07 +0000</pubDate>
      <link>https://dev.to/ronald_arias/hello-world-ruby-3daj</link>
      <guid>https://dev.to/ronald_arias/hello-world-ruby-3daj</guid>
      <description>&lt;p&gt;Because everything in the programming world starts with a &lt;code&gt;Hello World&lt;/code&gt;, I’ll come back to the very basics with a Ruby Hello World.&lt;/p&gt;

&lt;p&gt;Ruby is an Object Oriented programming language that’s been quite popular in the past years, specially within the Rails framework. I use it on my day to day basis for all sorts of scripting, micro-services and different production tasks.&lt;/p&gt;

&lt;p&gt;The thing most people like about Ruby is its simplicity. You can write code quickly as if you're writing plain text (almost), and you can use the interactive console to test things out.&lt;/p&gt;

&lt;p&gt;Many languages have adopted these practices and now it's even easier to get started with them as well. The likes of JavaScript, Python, PHP, etc have come a long way too.&lt;/p&gt;

&lt;p&gt;This article is going to be divided into 3 sections: Installation, Basics and Capabilities. In other posts I'll go deeper into the more complex and fun characteristics of the language.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;Installation is quite simple, nowadays Ruby can be obtained from many different sources and package managers. You can use &lt;code&gt;apt-get&lt;/code&gt;, &lt;code&gt;brew&lt;/code&gt;, download a binary or exec file etc.&lt;/p&gt;

&lt;p&gt;But for me, the best way is to use a version manager. This little tool allows you to have multiple versions of Ruby running seamlessly in the same machine, which is specially useful when having multiple apps, all running different versions (micro-services environment).&lt;/p&gt;

&lt;p&gt;My favourite one is &lt;code&gt;[chruby](https://github.com/postmodern/chruby)&lt;/code&gt;. There's also other popular ones like &lt;code&gt;rvm&lt;/code&gt; or &lt;code&gt;rbenv&lt;/code&gt; but I found &lt;code&gt;chruby&lt;/code&gt; works the best for me.&lt;/p&gt;

&lt;p&gt;The easiest way to install it is using &lt;code&gt;brew&lt;/code&gt;. You can check other installing options on their website. Depending on your OS, the tools will differ. &lt;/p&gt;

&lt;p&gt;Now for chruby, simply going to your shell and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; brew &lt;span class="nb"&gt;install &lt;/span&gt;chruby
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, you can install any version of Ruby you want by using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; ruby-install ruby-2.7.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will install the version 2.7.2.&lt;/p&gt;

&lt;p&gt;This is the absolute basics. You can test ruby installed correctly by using &lt;code&gt;ruby -v&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can also switch between installed versions using &lt;code&gt;$&amp;gt; chruby 2.7.1&lt;/code&gt; for example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Basics
&lt;/h3&gt;

&lt;p&gt;Ruby is a really descriptive programming language. You can find an extensive guide in the &lt;a href="https://www.ruby-lang.org/en/documentation/"&gt;official ruby documentation&lt;/a&gt;. I will only highlight certain basic aspects that I consider relevant or interesting.&lt;/p&gt;

&lt;p&gt;The easiest way to start playing around with Ruby is using the interactive console (irb - Interactive rb). To access it simply type &lt;code&gt;irb&lt;/code&gt; in your shell. It should already come installed with your ruby version.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; irb
irb&lt;span class="o"&gt;(&lt;/span&gt;main&lt;span class="o"&gt;)&lt;/span&gt;:001:0&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now as promised, the hello world. The &lt;code&gt;puts&lt;/code&gt; command is the equivalent of &lt;code&gt;print&lt;/code&gt; in other languages. It simply outputs the object that follows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; puts &lt;span class="s2"&gt;"Hello World!"&lt;/span&gt;
Hello World!
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; nil
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like that! &lt;/p&gt;

&lt;p&gt;Notice that the method itself executes the print, and then it returns a value nil. &lt;code&gt;nil&lt;/code&gt; is the special object reserved for &lt;code&gt;NULL&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;Now, everything in ruby is an object, even the less intuitive things. That's something to keep in mind, because this approach will help us accomplish really cool things.&lt;/p&gt;

&lt;p&gt;As an example, take the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; nil.class
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; NilClass

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;nil.nil?
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty straightforward, right?&lt;/p&gt;

&lt;p&gt;Now take the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; true.class
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; TrueClass

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; 1.class
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; Integer

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;.class
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; String
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this means is that what we call values in other programming languages, like &lt;code&gt;true&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;hello&lt;/code&gt; are objects in Ruby. This allow us to call methods directly on them without having to invoke the parent class &lt;code&gt;Integer&lt;/code&gt; or &lt;code&gt;String&lt;/code&gt; for example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; 1.odd?
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;.size
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 5

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; true.to_s
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"true"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may have noticed already that Ruby is also a loosely typed language, there's no need to declare types on variables; there's also no need to close the line with a semi-colon for example.&lt;/p&gt;

&lt;p&gt;Take the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Ruby will try to infer the data type based on the value (object) passed&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; a &lt;span class="o"&gt;=&lt;/span&gt; 100
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; b &lt;span class="o"&gt;=&lt;/span&gt; 200
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; a + b
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 300

&lt;span class="c"&gt;# But it will also let you override these types as you please&lt;/span&gt;
&lt;span class="c"&gt;# And it will apply validations when appropriate&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; b &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"200"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; a + b
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; TypeError &lt;span class="o"&gt;(&lt;/span&gt;String can&lt;span class="se"&gt;\'&lt;/span&gt;t be coerced into Integer&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Nevertheless, some other times it will try to infer what you want&lt;/span&gt;
&lt;span class="c"&gt;# Like concatenating Strings&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; a &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"100"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; a + b
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"100200"&lt;/span&gt;

&lt;span class="c"&gt;# Or transforming ints into floats&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; a, b &lt;span class="o"&gt;=&lt;/span&gt; 100, 200.0
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; a + b
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 300.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In case you missed it, Ruby is also capable of doing value destructuring. Check how &lt;code&gt;a&lt;/code&gt; gets assigned the value &lt;code&gt;100&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; the value &lt;code&gt;200.0&lt;/code&gt;. Ruby has very powerful one-liners. Which is at times a bless, but also a curse. Sometimes it can obfuscate the code, but others it can save you many lines.&lt;/p&gt;

&lt;p&gt;Have a look at a simple variable value swap for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; a &lt;span class="o"&gt;=&lt;/span&gt; 100
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; b &lt;span class="o"&gt;=&lt;/span&gt; 200

&lt;span class="c"&gt;# A typical value swap may include a third temp variable&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; c &lt;span class="o"&gt;=&lt;/span&gt; a
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; a &lt;span class="o"&gt;=&lt;/span&gt; b
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; b &lt;span class="o"&gt;=&lt;/span&gt; c

&lt;span class="c"&gt;# But in Ruby you can just change them in a one-liner&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; a, b &lt;span class="o"&gt;=&lt;/span&gt; b, a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are truly a battalion of cool things you can do with the language, and it takes more than a Hello World post to do it, so I'll cut it short here. I'll release a series of basic posts aimed at Ruby and other programming languages to discuss the many cool things I encounter in my day to day and comparisons between the different programming languages I use or learn.&lt;/p&gt;

&lt;h3&gt;
  
  
  Capabilities
&lt;/h3&gt;

&lt;p&gt;I like to believe that every programming language have a series of tasks that it does better than others. You have languages that are great for Math problems, others for Machine Learning, then there's the ones great to build amazing user interfaces, and the ones to build great distributed systems, etc.&lt;/p&gt;

&lt;p&gt;Personally, I put Ruby in the go-to simple category. It's readable enough to make my code super clean, but powerful enough to be used for a wide variety of applications. Hence I use it as my general purpose programming language.&lt;/p&gt;

&lt;p&gt;Within the Rails framework, you can build full websites really quickly and with little expertise. Once learning the conventions, it becomes an easy process. &lt;/p&gt;

&lt;p&gt;For scalable systems, you can use Ruby apps on top of the Sinatra Framework as part of a micro services architecture. This way you can ensure the memory load on particular apps can be managed easily, and you have a good separation of domains, apart from all other advantages you get from a generic micro services system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I hope I've interested you enough to do a little bit more reading on your own. Ruby is a great language if you're just getting started with programming or if you're experienced but looking for clean and readable solutions. It does cover the whole spectrum.&lt;/p&gt;

&lt;p&gt;Apart from being easy to learn, it has a good deal of use cases and a great community behind it, making it easier to learn and maintain.&lt;/p&gt;

&lt;p&gt;That's all for now, happy coding!&lt;/p&gt;

&lt;p&gt;For more topics, check my profile or visit &lt;a href="//rarias.dev"&gt;rarias.dev&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Hello World - Elixir</title>
      <dc:creator>Ron</dc:creator>
      <pubDate>Fri, 22 Jan 2021 12:20:54 +0000</pubDate>
      <link>https://dev.to/ronald_arias/hello-world-elixir-1f3o</link>
      <guid>https://dev.to/ronald_arias/hello-world-elixir-1f3o</guid>
      <description>&lt;p&gt;Here's a personal favourite. Elixir is a dynamic, functional programming language built thinking about scalability and parallelism. It is built on top of Erlang, so performance wise it's really powerful.&lt;/p&gt;

&lt;p&gt;It is not quite as popular as other programming languages out there and it has a relatively small community due to being still young, but its capabilities are still great. &lt;/p&gt;

&lt;p&gt;I think developers tend to favour GoLang for exploiting distributed tasks or Clojure and Scala on the functional aspect, yet Elixir seems to me like a nice place in the middle.&lt;/p&gt;

&lt;p&gt;Some of the issues around Elixir revolve around lack of popularity for functional languages, reduced compatibility in some hostings and sometimes poor error readability when things go wrong.&lt;/p&gt;

&lt;p&gt;This article is going to be divided into 3 sections: Installation, Basics and Capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Elixir can be installed in many different ways, you can find the way that best works for you on their &lt;a href="https://elixir-lang.org/install.html"&gt;installation page&lt;/a&gt;. My preferred way (on MacOS) is to use a package manager like &lt;a href="https://brew.sh/"&gt;homebrew&lt;/a&gt;. That way I can stay on top of updates and releases fairly easily.&lt;/p&gt;

&lt;p&gt;The installation using homebrew is fairly simple. You can use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; brew &lt;span class="nb"&gt;install &lt;/span&gt;elixir
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and brew will do all the heavy lifting for you. You can test your installation using &lt;code&gt;elixir --version&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using a version manager
&lt;/h3&gt;

&lt;p&gt;As with other programming languages, you may find yourself needing to use multiple versions of the same language on different apps, specially on microservice environments. To resolve this problem, you can either use &lt;a href="https://www.docker.com/"&gt;dockerized&lt;/a&gt; setups or use a version manager.&lt;/p&gt;

&lt;p&gt;There are multiple version managers available for Elixir. I particularly like and use &lt;a href="https://github.com/taylor/kiex"&gt;kiex&lt;/a&gt;. It's really simple to use and to be fair, it's the one I've had less trouble with.&lt;/p&gt;

&lt;p&gt;To install kiex, they provide an installation script you can run from your shell&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://raw.githubusercontent.com/taylor/kiex/master/install | bash &lt;span class="nt"&gt;-s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From there you can follow the instructions if necessary. This script will install kiex in your &lt;code&gt;$HOME/.kiex&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Usage is fairly simple as well, you can check the available versions installed on your system with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; kiex list
&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt; elixir-1.8.2

&lt;span class="c"&gt;# =&amp;gt; - current&lt;/span&gt;
&lt;span class="c"&gt;# =* - current &amp;amp;&amp;amp; default&lt;/span&gt;
&lt;span class="c"&gt;#  * - default&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or generate a list of available releases for you to download with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; kiex list known
Getting the available releases from https://github.com/elixir-lang/elixir/releases
Known Elixir releases:
    0.7.2
    0.8.0
    ...
        1.11.2
    1.11.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From where you can pick the version you want to install and let kiex do it for you&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; kiex &lt;span class="nb"&gt;install &lt;/span&gt;1.11.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When going around project folders, you can select the Elixir version you want to use (provided it's been installed), via kiex with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kiex use 1.8.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are other interesting things you can do listed in their &lt;a href="https://github.com/taylor/kiex#usage"&gt;documentation&lt;/a&gt;. For now, I'll stick to the simple usage commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basics
&lt;/h2&gt;

&lt;p&gt;Elixir is a functional programming language, so writing code in it may not be the most intuitive thing for everyone. There's so much to learn about it, so feel free to check their &lt;a href="https://elixir-lang.org/getting-started/introduction.html"&gt;documentation&lt;/a&gt; if you have specific doubts or are interested in learning more.&lt;/p&gt;

&lt;p&gt;To make it easy for ourselves to start testing things out, we'll use a really neat tool called the Elixir Interactive Console (iex - Interactive Elixir). Similarly to the ruby &lt;code&gt;irb&lt;/code&gt; or Python &lt;code&gt;interactive shell&lt;/code&gt;, it will allow us to test simple concepts first.&lt;/p&gt;

&lt;p&gt;If Elixir is correctly installed, you should be able to enter the iex from your shell by typing the &lt;code&gt;iex&lt;/code&gt; command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&amp;gt;&lt;/span&gt; iex
Erlang/OTP 23

Interactive Elixir &lt;span class="o"&gt;(&lt;/span&gt;1.8.2&lt;span class="o"&gt;)&lt;/span&gt; - press Ctrl+C to &lt;span class="nb"&gt;exit&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;type &lt;/span&gt;h&lt;span class="o"&gt;()&lt;/span&gt; ENTER &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="nb"&gt;help&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
iex&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once in the console we can start playing around with Elixir. &lt;/p&gt;

&lt;p&gt;Elixir has specific data types, but you don't have to explicitly declare them. The basic ones include&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;          &lt;span class="c1"&gt;# integer&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mh"&gt;0x1F&lt;/span&gt;       &lt;span class="c1"&gt;# integer&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;        &lt;span class="c1"&gt;# float&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;       &lt;span class="c1"&gt;# boolean&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:atom&lt;/span&gt;      &lt;span class="c1"&gt;# atom / symbol&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"elixir"&lt;/span&gt;   &lt;span class="c1"&gt;# string&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# list&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;# tuple&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These data types are pretty similar to other programming languages. So you can perform operations on them, pass them around in variables etc. There are a few important differences however, which will be mentioned towards the end of this section.&lt;/p&gt;

&lt;p&gt;Using these data types is also pretty similar to other programming languages&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Arithmetic operations behave the same&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="mi"&gt;25&lt;/span&gt;

&lt;span class="c1"&gt;# String interpolation behaves the same&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:world&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"hello &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="s2"&gt;"hello world"&lt;/span&gt;

&lt;span class="c1"&gt;# And you can print using the IO module&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"hello world"&lt;/span&gt;
&lt;span class="n"&gt;hello&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt;
&lt;span class="ss"&gt;:ok&lt;/span&gt;
&lt;span class="c1"&gt;# Notice the return value of the method is :ok. More on that later&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To perform operations on data types or variables, you will have to use the methods from its class. Take the &lt;a href="https://hexdocs.pm/elixir/String.html"&gt;String class&lt;/a&gt; for example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upcase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"hello world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="s2"&gt;"HELLO WORLD"&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"foo bar"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"foo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"bar"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"abcd"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="s2"&gt;"dcba"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are however, quite a few functions that are available in the global scope&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# To check whether a variable belongs to a data type&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;is_boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;true&lt;/span&gt;

&lt;span class="c1"&gt;# To check if a variable is NULL&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;is_nil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"hello world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pattern matching
&lt;/h3&gt;

&lt;p&gt;Now, here's something that might trip many, and it's the &lt;code&gt;=&lt;/code&gt; operator. In most languages this operator is used to assign values to a variable, and at first sight in Elixir it may look just the same&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hello world"&lt;/span&gt;
&lt;span class="s2"&gt;"hello world"&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;
&lt;span class="s2"&gt;"hello world"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But consider the following sequence&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hello world"&lt;/span&gt;
&lt;span class="s2"&gt;"hello world"&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"hello world"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;
&lt;span class="s2"&gt;"hello world"&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"goodbye world"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;MatchError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="n"&gt;hand&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt; &lt;span class="ss"&gt;value:&lt;/span&gt; &lt;span class="s2"&gt;"hello world"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What happened?&lt;/p&gt;

&lt;p&gt;It turns out that the &lt;code&gt;=&lt;/code&gt; is actually called the match operator, or pattern matching operator. Its goal is not to simply assign values but to compare the two sides of the equation.&lt;/p&gt;

&lt;p&gt;This is pretty useful in more complex situations, like destructuring expressions for example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="ss"&gt;:hello&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="s2"&gt;"world"&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But more interestingly when comparing specific types as a result of a particular operation.&lt;/p&gt;

&lt;p&gt;Consider the following example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;span class="mi"&gt;200&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;MatchError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="n"&gt;hand&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt; &lt;span class="ss"&gt;value:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that &lt;code&gt;:ok&lt;/code&gt; and &lt;code&gt;200&lt;/code&gt; are values being matched. When those values do not match, we have received unexpected data, and the operation will be invalid. Do the codes seem familiar to you? &lt;code&gt;200&lt;/code&gt; and &lt;code&gt;401&lt;/code&gt; are common http response codes, and you can use pattern matching to handle http responses in a neat manner&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Simple http request example for pattern matching response&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;http_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="no"&gt;HttpRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;HTTPoison&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;status_code:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;body&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;HTTPoison&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;status_code:&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"[ERROR] Authentication failed."&lt;/span&gt;
      &lt;span class="no"&gt;nil&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;HTTPoison&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;status_code:&lt;/span&gt; &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Unexpected http response: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="no"&gt;nil&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;HTTPoison&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;reason:&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Unexpected error: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="no"&gt;nil&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Process calls in Elixir typically return a status and the result. In the previous example you can see either the tuple &lt;code&gt;{:ok, response_object}&lt;/code&gt; or &lt;code&gt;{:error, error_object}&lt;/code&gt; for which we can pattern match accordingly and handle each scenario separately. The Pattern match can be as complex as you'd like.&lt;/p&gt;

&lt;p&gt;There's more much to talk about this complex, yet amazing programming language. I will release a series dedicated to Elixir soon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Capabilities
&lt;/h2&gt;

&lt;p&gt;The real advantages of Elixir come when you're trying to parallelise tasks. Concurrency, scalability and fault tolerance are built into the language.&lt;/p&gt;

&lt;p&gt;In Elixir, all code runs inside processes, which are isolated from each other and run concurrently and communicate passing messages between each other.&lt;/p&gt;

&lt;p&gt;These processes are quite lightweight, for which at any given time you may be running a great amount of them. &lt;/p&gt;

&lt;p&gt;This allows for incredible fault tolerance. Processes can be restarted quite quickly without big performance implications. In fact, Elixir's strategy for error recovery is simply killing the processes and starting it again. This is a "fail fast" strategy. Elixir developers made the design decision that letting a program fail and recover fast was a better strategy than defensive programming and trying to predict any possible error.&lt;/p&gt;

&lt;p&gt;Additionally to standard processes, Elixir has &lt;a href="https://hexdocs.pm/elixir/GenServer.html"&gt;GenServers&lt;/a&gt; and &lt;a href="https://hexdocs.pm/elixir/Supervisor.html"&gt;Supervisors&lt;/a&gt;. These are in charge or keeping state and monitoring other processes respectively. GenServers and Supervisors are the building blocks of server-client relationships.&lt;/p&gt;

&lt;p&gt;In terms of parallelism, Elixir has built-in modules like the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Supervisor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;async_stream_nolink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;TaskSupervisor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list_items&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;MyApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;process_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;max_concurrency:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In which we ask a supervisor to spawn 50 processes concurrently to deal with a list of items that need, well, processing. This is particularly useful in scenarios where we need to query external APIs or run particularly slow operations on each item.&lt;/p&gt;

&lt;p&gt;If we have a list of 1000 items and 50 concurrent processes working on it, it only takes 20 rounds to get your results, and more importantly you can have them all combined at the end without dealing with any of the concurrency yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There's much more to talk about Elixir, hopefully this brief introduction is enough to keep you interested. &lt;/p&gt;

&lt;p&gt;Every programming language has a thing for which they're good at. Elixir is great for concurrent processing and easy parallelism. There are, of course, other solutions like GoLang or if you need greater data scale, tools like Apache Spark are better suited for the job. But Elixir should be considered given its simplicity and functional approach. Remember there's no one way to solve a problem.&lt;/p&gt;

&lt;p&gt;For more topics, check my profile or visit &lt;a href="//rarias.dev"&gt;rarias.dev&lt;/a&gt;.&lt;/p&gt;

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