<?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>Forem: Arandi López</title>
    <description>The latest articles on Forem by Arandi López (@arandilopez).</description>
    <link>https://forem.com/arandilopez</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%2F4009%2Fbe2bde65-11c6-45ae-91fd-ad8f522453ac.jpg</url>
      <title>Forem: Arandi López</title>
      <link>https://forem.com/arandilopez</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/arandilopez"/>
    <language>en</language>
    <item>
      <title>Install Tensorflow GPU 1.13 on Pop OS 18.04</title>
      <dc:creator>Arandi López</dc:creator>
      <pubDate>Wed, 10 Apr 2019 21:00:31 +0000</pubDate>
      <link>https://forem.com/arandilopez/install-tensorflow-gpu-1-13-on-pop-os-18-04-2ham</link>
      <guid>https://forem.com/arandilopez/install-tensorflow-gpu-1-13-on-pop-os-18-04-2ham</guid>
      <description>

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://arandilopez.dev/articles/2019/04/09/install-tensorflow-gpu-1-13-on-pop-os-18-04/?utm_source=devto"&gt;arandilopez.dev&lt;/a&gt;. Read it in &lt;a href="https://arandilopez.dev/articles/2019/04/05/instalar-tensorflow-gpu-1-13-en-pop-os-18-04/?utm_source=devto"&gt;spanish too&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Pop!_OS is an incredible Linux distribution based on Ubuntu. But what's more amazing about Pop!_OS is its support for the Nvidia and Tensorflow graphics cards, which is a great feature to opt for Pop!_OS as a distro. In this post I will show the steps to get Tensorflow GPU 1.13 with python3.&lt;/p&gt;

&lt;p&gt;Pop!_OS 18.04 supports the graphics card with &lt;a href="https://system76.com/pop"&gt;an ISO image&lt;/a&gt; that has the most current proprietary drivers that System76 maintains. The most current driver is version 418, you can check the version installed on your OS with the command &lt;code&gt;nvidia-smi&lt;/code&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.56       Driver Version: 418.56                              |
|-------------------------------+----------------------+----------------------+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Pop!_OS has a &lt;a href="https://support.system76.com/articles/install-tensorflow/"&gt;metapackage&lt;/a&gt; to natively install Tensorflow and CUDA, however this metapackage installs up to version 1.9 of Tensorflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Python 3
&lt;/h2&gt;

&lt;p&gt;First we install the necessary packages to start our development with python3, we will install pip and venv to manage the dependencies of our python projects.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;python3-dev python3-pip python3-venv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Install CUDA 10.0
&lt;/h2&gt;

&lt;p&gt;To install version 1.13, the last stable of Tensorflow, we need to have the Nvidia 418 drivers and install the following dependencies for CUDA and Tensorflow.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;autogen autogen-doc cmake cmake-data guile-2.0-libs libblas3 libgc1c2 libgfortran4 libjsoncpp1 liblapack3 libnvidia-compute-418 libopts25 libopts25-dev librhash0 libuv1 python3-numpy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now install the necessary CUDA packages.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;system76-cuda-10.0 system76-cudnn-10.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;There are CUDA packages with version 10.1, however they do not have support for Tensorflow 1.13. &lt;a href="Https://github.com/tensorflow/tensorflow/issues/26209#issuecomment-479127128"&gt;See here.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Install Tensorflow GPU
&lt;/h2&gt;

&lt;p&gt;We will create a new folder for our project&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; ~/test_tensorflow_gpu
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;test_tensorflow_gpu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We started a new virtual environment for our dependencies to this project.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Having activated the virtual environment already allows us to run both &lt;code&gt;python3&lt;/code&gt; and&lt;code&gt;pip3&lt;/code&gt; as &lt;code&gt;python&lt;/code&gt; and &lt;code&gt;pip&lt;/code&gt; respectively.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Install Tensorflow. The correct package to install Tensorflow with CUDA support is &lt;code&gt;tensorflow-gpu&lt;/code&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;venv&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--upgrade&lt;/span&gt; tensorflow-gpu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Test the installation of Tensorflow.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;venv&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;python &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"import tensorflow as tf; print(tf.test.is_built_with_cuda());"&lt;/span&gt;
True &lt;span class="c"&gt;# &amp;lt;-- expected output&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




</description>
      <category>tensorflow</category>
      <category>popos</category>
      <category>python</category>
      <category>howto</category>
    </item>
    <item>
      <title>Efficent webhook handling with Ruby on Rails</title>
      <dc:creator>Arandi López</dc:creator>
      <pubDate>Sun, 03 Jun 2018 18:31:13 +0000</pubDate>
      <link>https://forem.com/arandilopez/efficent-webhook-handlig-with-ruby-on-rails-4pj</link>
      <guid>https://forem.com/arandilopez/efficent-webhook-handlig-with-ruby-on-rails-4pj</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published in &lt;a href="https://dev-knights.github.io/2018/06/03/efficient-webhook-handling-with-ruby-on-rails.html?utm_source=devto&amp;amp;utm_medium=blogspot" rel="noopener noreferrer"&gt;Dev Knights&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When implementing a payment system as Paypal or Stripe, the more tedious part is implementing webhooks. In this post I wil explain you a how you can optimize the webhook and get a clean and light implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  What are the Webhooks for?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Webhook" rel="noopener noreferrer"&gt;Webhooks&lt;/a&gt; are endpoints in your application where a service like Paypal or Stripe will inform you about the events happening in them. Paypal and Stripe use them to notify whether a charge was successful or not, for example. This mechanism is necesary given the charges proccess are asyncronous. Ergo, in the moment we create a charge using thier API we won't know until in the future if the charge was successful or not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Standard way
&lt;/h2&gt;

&lt;p&gt;The webhook is just an endpoint (route or path) which receives information through &lt;code&gt;POST&lt;/code&gt; method. In Rails a barebone implementation of Stripe webhook could be:&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="c1"&gt;# controllers/stripe_controller.rb&lt;/span&gt;
&lt;span class="c1"&gt;# Method responsbile for handling stripe webhooks&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;webhook&lt;/span&gt;
  &lt;span class="k"&gt;begin&lt;/span&gt;
    &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s1"&gt;'invoice.payment_succeeded'&lt;/span&gt;
        &lt;span class="c1"&gt;# handle success invoice event&lt;/span&gt;
      &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s1"&gt;'invoice.payment_failed'&lt;/span&gt;
        &lt;span class="c1"&gt;# handle failure invoice event&lt;/span&gt;
      &lt;span class="c1"&gt;# More events...&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;:json&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;:status&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Webhook failed"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;:json&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;:status&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;200&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;This &lt;code&gt;webhook&lt;/code&gt; method uses a &lt;code&gt;switch-case&lt;/code&gt; in order to determinate, with the event type that was received, which code block execute. Now imagine implement more events, this method will smell and get hard to maintain.&lt;/p&gt;

&lt;p&gt;Sure we can write more methods to put the logic of each event and call them into the &lt;code&gt;switch-case&lt;/code&gt;, however we can still improve this webhook method.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleaner way
&lt;/h2&gt;

&lt;p&gt;The cleanest webhook implementation I've seen is in &lt;a href="https://laravel.com/docs/5.6/billing#defining-webhook-event-handlers" rel="noopener noreferrer"&gt;Laravel Cashier&lt;/a&gt;. Cashier's Webhook Controller allows you to handle automaticaly by mapping each event to a method. The controller convention says that if you want to handle the event &lt;code&gt;invoice.payment_succeeded&lt;/code&gt; create a method in the controller whose name start with &lt;code&gt;handle&lt;/code&gt; and the &lt;code&gt;camelCase&lt;/code&gt; form of the event type: &lt;code&gt;handleInvoicePaymentSucceeded&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Laravel\Cashier\Http\Controllers\WebhookController&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;CashierController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WebhookController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CashierController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * Handle a Stripe webhook.
     *
     * @param  array  $payload
     * @return Response
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;handleInvoicePaymentSucceeded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Handle The Event&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;h2&gt;
  
  
  Refactoring
&lt;/h2&gt;

&lt;p&gt;How can we achieve this with Rails?. Easy, thanks to metaprogramming in Ruby. Refactoring the previous method could get like this:&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;webhook&lt;/span&gt;
  &lt;span class="k"&gt;begin&lt;/span&gt;
    &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"handle_"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'_'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;
  &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;JSON&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ParserError&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:status&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Invalid payload"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
  &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;NoMethodError&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
    &lt;span class="c1"&gt;# missing event handler&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;json: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:status&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;200&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;def&lt;/span&gt; &lt;span class="nf"&gt;handle_invoice_payment_succeeded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;#handle the event&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;handle_invoice_payment_failed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;#handle the event&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# and more...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the webhook method we need to parse the event type to the name of the method which will handle that event.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Translate all &lt;code&gt;'.'&lt;/code&gt; to &lt;code&gt;'_'&lt;/code&gt; and concatenate with &lt;code&gt;"handle_"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Then send the message to call the resultant method with the payload obtained.&lt;/li&gt;
&lt;li&gt;Otherwise, if there's no method implemented for that event, it will be rescued where we can make another action.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Laravel Cashier implementation looks wonderful to handle webhook events. Therefore this way you get a clean and maintainable controller.&lt;/p&gt;

&lt;h3&gt;
  
  
  ProTip
&lt;/h3&gt;

&lt;p&gt;As a next step you could write &lt;a href="http://api.rubyonrails.org/classes/ActiveSupport/Concern.html" rel="noopener noreferrer"&gt;concerns&lt;/a&gt; to group event handlers. Now you have a lighter controller.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Do you want to read this article in spanish? Check it &lt;a href="https://dev-knights.github.io/spanish/2018/06/03/manejo-eficiente-de-webhooks-con-ruby-on-rails.html?utm_source=devto&amp;amp;utm_medium=blogspot" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webhooks</category>
      <category>ruby</category>
      <category>rails</category>
      <category>ror</category>
    </item>
    <item>
      <title>What kind of programmer are you?</title>
      <dc:creator>Arandi López</dc:creator>
      <pubDate>Tue, 30 Jan 2018 21:59:19 +0000</pubDate>
      <link>https://forem.com/arandilopez/what-kind-of-programmer-are-you-2862</link>
      <guid>https://forem.com/arandilopez/what-kind-of-programmer-are-you-2862</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published in &lt;a href="https://dev-knights.github.io/2018/01/30/what-kind-of-programmer-are-you.html?utm_source=devto&amp;amp;utm_medium=blogspot" rel="noopener noreferrer"&gt;Dev Knights&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A year ago I read an &lt;a href="https://sg.com.mx/revista/53/el-caso-php-y-los-salarios#.WKdlaxIrKRv" rel="noopener noreferrer"&gt;article&lt;/a&gt; published in the software magazine Software Gurú by &lt;a href="https://sg.com.mx/sgvirtual/speakers/basilio-brice-o" rel="noopener noreferrer"&gt;Basilio Briseño&lt;/a&gt; where He stated that PHP is one of the least paid languages ​​in Mexico and why. In his article he also published a salary range based for every type of programmer made by the programming group "PHP Mexico".&lt;/p&gt;

&lt;p&gt;Although the salary range skill classification is aimed towards PHP programmer, the type of programmer classification &lt;br&gt;
can be applied outside php programming. The following list suggests what a Rookie, Junior, Senior and Master developer skills are expected to get into that classification.&lt;/p&gt;

&lt;p&gt;The salary range could be generalized as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rookie&lt;/strong&gt; usually writes code without consistency in indentation or conventions and usually copies and pastes anything found on the internet that seems to do what it was asked to deliver and that, according to the forums, is the solution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Apprentice&lt;/strong&gt; has accepted that he/she needs to improve and decides to learn the best practices and apply them. He/She consults forums not for searching code that he/she could simply copy/paste, instead he/she analyzes it and asks her/his issues after having investigated by his/her own.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Junior&lt;/strong&gt; knows what design patterns are and applies them, understands the basics of what MVC, REST, CRUD, ORM, SQL Injection, XSS, I / O Sanitization, etc. are, applies this knowdledge alogside other techniques; He/she is an excellent learner and uses third-party APIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Senior&lt;/strong&gt; is capable of developing his/her own tools and APIs, is aware of how his/her domain language works internally, is highly interested in the performance of applications beyond its ease of development, he/she is not satisfied with the functioning and design of all third-party tools and APIs as they come, and always seeks to innovate and create things that improve performance, facilitate their work and the speed of their deliverables; contributes with code in different projects and communities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Master&lt;/strong&gt; is capable of developing his own extensions, gems or libraries, and optimizing them for his/her best use; contributes to Open Source projects and he/she is normally dedicated to improving the performance of high performance applications. Knows the domain language its origin and differences with others languages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Core&lt;/strong&gt; contributes to the development of the core of the domain language; contributes in some extensions, gems or libraries and public tools; He/she is a frequent speaker at international conferences and it is usual to see his/her name in the credits of changes of version of his domain language.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So ... What kind of programmer are you?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Many developers are called Senior after years of work, or experts in some framework or language when they only do tutorials; however, your work and contribution and how it affects other's people work (not only in your workplace) tells vastly what type of programmer you are.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>php</category>
      <category>senior</category>
      <category>developer</category>
      <category>programmer</category>
    </item>
    <item>
      <title>How to get your code re-written</title>
      <dc:creator>Arandi López</dc:creator>
      <pubDate>Thu, 13 Jul 2017 16:32:04 +0000</pubDate>
      <link>https://forem.com/arandilopez/how-to-get-your-code-re-written</link>
      <guid>https://forem.com/arandilopez/how-to-get-your-code-re-written</guid>
      <description>

&lt;h2&gt;
  
  
  This is one of the great skills that "Senior developers" have today and here I'll list the steps to follow in order to have your code re-written once it's done.
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Do not follow any convention.
&lt;/h2&gt;

&lt;p&gt;You are a Senior Developer, any convention from a geeky group of programmers won't  tell you how to code. Your code is beautiful by itself. Why do you need to correctly indent your code? It is not your fault that the IDE of others does not correctly format tabs and spaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not test your code.
&lt;/h2&gt;

&lt;p&gt;You do not need it. It's your code and it's perfect. The tests are only a waste of time and you do not have that time. If you were not taught about tests in school it's because they are not that important. Those software engineers are very suspicious about your standards (or lack thereof), your code does not need to be tested. Also the tests are not safe, there is no one like a user really testing it, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not use design patterns.
&lt;/h2&gt;

&lt;p&gt;Design patterns just make your code less understandable. We all know how the &lt;code&gt;switch&lt;/code&gt;, &lt;code&gt;if&lt;/code&gt;, and &lt;code&gt;for&lt;/code&gt; statements work, so deep nesting them won't hurt anyone. You don't have to improve that code structure. You're a Senior Developer and you know what you're doing and you're doing it right.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not extend libraries, take them and modify them.
&lt;/h2&gt;

&lt;p&gt;You are a great Senior Developer, so great that you could take jQuery and "improve" its methods. You don't have to plug anything. You can take the source and make your changes on it. You are so great.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do not use automated tools, or minify your files.
&lt;/h2&gt;

&lt;p&gt;We know that doing things manually is better than automating those repetitive tasks. Webpack and Gulp are tools you do not need.&lt;/p&gt;

&lt;h2&gt;
  
  
  You do not need to think thoroughly about your software solutions.
&lt;/h2&gt;

&lt;p&gt;You are a great Senior Developer, obsessed with that database without relational and use it in ALL, EVERYWHERE. Don't start any research about how much it will cost, Just use it, you know that "one size fits all", anyway that "relational" thing is so outdated. Anything you say MUST be used, and by now you already are  a Solution Architect.&lt;/p&gt;




&lt;p&gt;These are just some of the steps to follow in order to get someone to throw away all your code. A good Senior Developer should be open minded in order to increase the quality of the product in which he/she works.&lt;/p&gt;

&lt;p&gt;Unit testing and acceptance testing are part of the code, one without the other are not complete, so invest your time to know  the benefits of implementing tests methodologies in your projects. Do not ignore the Junior developers you have there. They just want to improve the code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally plublished on &lt;a href="https://medium.com/@arandilopez/c%C3%83%C2%B3mo-hacer-que-re-escriban-tu-c%C3%83%C2%B3digo-e94958ca553e"&gt;Medium&lt;/a&gt; in spanish&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href="https://twitter.com/mcoronelseg"&gt;Miguel Coronel&lt;/a&gt; for his revisions&lt;/p&gt;


</description>
      <category>softwaredevelopment</category>
      <category>sarcasm</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Hi, I'm Arandi Lopez</title>
      <dc:creator>Arandi López</dc:creator>
      <pubDate>Mon, 15 May 2017 17:21:22 +0000</pubDate>
      <link>https://forem.com/arandilopez/hi-im-arandi-lpez</link>
      <guid>https://forem.com/arandilopez/hi-im-arandi-lpez</guid>
      <description>&lt;p&gt;I'm a Software Engineer and I'v been coding for ~3 years&lt;/p&gt;

&lt;p&gt;You can find me on GitHub as &lt;a href="https://github.com/arandilopez" rel="noopener noreferrer"&gt;arandilopez&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I live in MÃ©rida, Mexico.&lt;/p&gt;

&lt;p&gt;I work for BoxFactura.com as Lead Software Engineer&lt;/p&gt;

&lt;p&gt;I mostly program in php, javascript, now moving to ruby and ruby on rails&lt;/p&gt;

&lt;p&gt;I am currently studying a Master degree in Data Science.&lt;/p&gt;

&lt;p&gt;Nice to meet you.&lt;/p&gt;

</description>
      <category>introduction</category>
    </item>
  </channel>
</rss>
