I Quit Platzi. Here is why.

So, I finally decided to cancel, or rather pause my platzi subscription for the longest period of time they allow –3 months. In case you don’t know what platzi is, it is a mostly-Spanish learning platform that tries to be the leading learning platform for the Hispanic world in the tech industry. And they really try to do it. The key word there being “try”.

So, what is wrong with it? In my particular case I am what is wrong. I’m too picky; it’s easy for small things to bother me more than they should. I’m a really hard judge. But mostly because I have years of experience programming. I’m not their target audience.

I don’t pretend to know EVERYTHING they teach. That would be absurd given how they cover a large range of topics. But to be honest, the things they teach that I don’t know are the things I’m not interested on at the moment, otherwise I would have learned them by now as well.

I find their classes to be basic introductions that never really dive deep in any topic. Their professional courses teach how to do things, not the theory behind that how. That is to say, they don’t really tell you why, only how. In my experience, and given my somewhat obsessive personality, the why is just as important if not more than the how. Theory matters.

I don’t meant to say platzi is a bad option. It may really be the best option for the Spanish-speaking world. This reflects either that I don’t know how to recognize a good thing when I see it, or that there is a lack of higher quality competitors that keep pushing the boundary of what is considered a good option. I think it is the latter.

When I first started my subscription I was excited. I took a couple of great courses that kept the hype high, but as time progressed and I took more courses I started to realize that newer courses seem to be made in a hurry just for the sake of expanding their library of content; it was quite disappointing to see courses that could easily be replaced by reading a man page.

So, is platzi really that bad? NO. Introductory courses are not a bad thing, they are a necessity, and there is only so much you can cover in a single course. Platzi’s job is not to please my peculiar taste for advanced higher education in very specific topics. Their job is to introduce the tech world to people so they can aspire to a better life through well paid jobs in the industry. And they are doing it. There is a plethora of testimonies from people who have better their lives thanks to what platzi has to offer. And that is their mission. They are nailing it.

I can recognize the value in being able to access a large array of courses covering a variety of topics in design, engineering, economics, and personal growth. I would definitely recommend platzi to some people, but not to all people. I myself will continue to be a sporadic student there. But for now, I have better learning resources that I want to explore.

Control Characters in Sed

After that little fiasco with my sed practice file I decided to do a search and replace for the BS characters in the file to clean it up and be able to use it as I originally intended. Immediately the question arouse: How do I match control characters?

The sed man page in Mac OS tells you that “The re_format(7) manual page fully describes [the regexps] formats“, so my first stop was that man page:

man re_format

There is a section in there that says you can use \xx.. to specify a literal sequence using a hexadecimal number. But that didn’t seem to work. My guess is that it doesn’t work because sed doesn’t use enhanced regexps.

A quick search lead me to an article where it says you can use command substitution to enter the control character, which worked nicely:

sed -i'' -e 's/.'$(echo "\x08")'//g' input_file

The dot (.) before the command substitution is because we need to remove the character immediately before the BS character otherwise we will end up with garbage:

N^HNA^HAM^HME^HE

would result into

NNAAMMEE

if we didn’t remove the character immediately before the BS character represented as ^H here.

When in Sed Land, Read the Input File

A couple of days ago I was playing around with sed in Mac just for fun, and came up to a quite confusing issue: I could not match NAME using /NAME/ as a context address. In fact, trying to match anything using a longer-than-2-chars regexp would not work:

/NA/ would match NAME
/AM/ would match NAME
/ME/ would match NAME
/NAM/ would not match NAME
/AME/ would not match NAME

This was quite puzzling. After trying different things and looking around the internet I was still where I had started. Then I decided to try using small letters:

/th/ would match many different lines in the input file
/the/ would match many different lines in the input file

Woah! I could use longer-than-2-chars with small case letters, but not with capital ones. WTF? I continued trying with different combinations using capital letters, and anything with 1 or 2 chars would work, but more than 3 chars wold fail to match anything even though there seemed to be matches in the input file.

After a long time with this I decided to check the input file as a last act of hope. I found the problem.

At this point I should tell you how I got the input file. Remember how I said I was just practicing some sed. Well, I thought that an easy way to get a practice input file would be to put the contents of the man page for sed in a regular text file:

man sed > input_file

Well, that was not the best idea. My file ended up something like:

N^HNA^HAM^HME^HE

I didn’t notice that when I fist made the file because ^H is a BS control character, and doing

cat input_file

produces the expected text NAME because cat interprets those control characters, but opening the input file in vim revealed the control characters.

This is one of those life lessons that you never really forget, but if you do, you will feel stupid the next time you have to re-learn it. Read the input file in a text editor.

How to Whitelist an IP with IP Tables

I’ve had a server for a while now that I usually don’t use for much. From time to time I tell myself that I should start using it for some personal projects, but I never really do. Until now…

About a week ago I decided to finally do something with it besides hosting buzu.me. From some time now I’ve had a small app to manage a side business of mine. I had it running on a local host on a laptop that I could take anywhere to manage my business, but at times that became a little problematic for numerous reasons, including pure laziness to turn the computer on, or not being able to register a payment because I didn’t have the laptop close when visiting friends who had happen to purchase something “on credit”.

Last Saturday while at the store, which by the way opens only on Saturdays in a farmers market of sorts, I decided to take the time to start setting up the server for my app, and in the process I locked my self out of it after failing to login a couple of times. I contacted support to ask them to remove my IP from the blacklist, and was able to log in again just to lock myself out again trying to ssh into the server instead of using the control panel. I asked support to again remove my IP address from the blacklist, and to resend my SSH login information. It turns out it was different from my control panel information.

Since, in the past, this has happened to me a couple of times, I decided to just learn how to remove my IP from the blacklist so that if I ever lock myself out again on a certain IP because of a mistype or something I could just connect to another network and log in correctly to remove my original IP from the blacklist. Given how my server blocks any IP after only 3 failed attempts, it is not really unthinkable that at some point I will need to clear my IP from the blacklist.

It turns out that using iptables this is a really simple process:

  1. Find out the IP you want to clear out.
  2. Search the iptables filter table for that IP to get the rule number.
  3. Delete that chain/rulenumber

You can find the IP address that you want to remove by connecting to that network and using any of the services out there to check your IP.

To search iptables for that IP you can do this in the console:

iptables -L --line-numbers | grep "111.111.111.111"

using your ip instead of 111.111.111.111. That will return the lines where that IP is found. Those are the lines you need to remove, but before doing that you will need to find out the chain where those lines are. For this you can just list all the rules for the filter table, and look for the lines you got before:

iptables -L --line-numbers

You do not have to look at all the rules one by one, but rather at the line number you got before in each of the chains. Once you find a line that matches, just look a few lines before. Right before the first line in the current sequence of lines you should see a line with no number that starts with “Chain ” and then it says the chain name. In my specific case searching for my IP in iptables got me 2 results in  DENYIN, and DENYOUT respectively.

Once you have this information all you have to do is delete those lines:

iptables -D DENYIN NNN

Where NNN is the line number you want to remove, and DENYIN is your chain name which may be different.

You should do this with care as it relates to the security of your server.

If you would like to learn more about iptables​ you can read the manual:

man iptables

The Asterisk Next to the Filename in Vim’s Netrw

Yesterday I was opening up a file, but since I didn’t quite remember the name of it, I decided to instead open the containing directory in Vim:

:vsp ../dir-name

This worked as expected, opening the file browser, which I learned is called Netrw. However, I noticed that one of the files had an asterisk next to its name:

my-file.php*

I immediately started to wonder what that was about, but a quick search on duckduckgo.com produced no satisfactory results, so I hit F1 in vim, and the help page came up. Then I searched for *

/*

which, of course, started to find a lot of asterisks because it seems vim uses them a lot in the help pages, but at some point I finally came to a section that explains that

“The |getftype()| function is used to append a bit of filigree to indicate filetype to locally listed files:”

Those indicators are as follows:

directory : /
executable : *
fifo : |
links : @
sockets : =

So there you have it; an asterisk next to a filename in Netrw means the file is executable.

The Netrw man page seems to be full of really nice information, so I now owe it to myself to give it a good read. You should too if you are into Vim.

Solving a Mysterious Case of Empty Eloquent Model in Laravel

I’m working on a Laravel application that basically lets users make collections of eBay products. For those collection I use a model called ProductList. I initially wanted to call that model simply List, but that is a php reserved word.

Because I wasn’t happy with how wordy Product List sounds, I decided to name my route simply lists. I can view all lists going to GET /lists, or POST to that same url to make a new list, but when I tried to got to GET /lists/1 to view the first list, I would not get what I expected. Instead of a populated ProductList model in my controller, I was getting an empty model. The first symptom I saw was that trying to output the list name in my blade template resulted in nothing being printed out.

This got me scratching my head for a little bit. The controller’s method was well declared, so I referred to the documentation to see what might be going wrong. None of my previous experiences working with Laravel had had this kind of issue, but looking at the docs is always a good start.

The documentation states “Laravel automatically resolves Eloquent models defined in routes or controller actions whose type-hinted variable names match a route segment name”. The important part here is “whose type-hinted variable name match a route segment”. The show method of the controller created using artisan had a variable type-hinted as ProductList named $productList. Now I just had to check if the route segment matched that name. For doing that, since my routes file uses the resource method to declare the lists route which means I can’t see the route in the routes file, all I had to do was php artisan route:list on the command line, and the list of all routes was printed out. Sure enough the route segment, and the type-hinted variable didn’t have a matching name. All I had to do now was edit the show method’s signature so that the type-hinted variable had a matching name with the route segment. After doing that, everything worked just fine.

The Case of the Drupal Form that Would Not Post

This is the story of a Drupal form that would not handle data submissions correctly when a large number of fields were present.

Working on a Drupal site, I came across the strange case of a settings form that would not save its values when a large number of fields were present. The form helps site admins associate certain vehicle model numbers to their appropriate model name, class, and group. A class is basically a collection of similar models, and a group is a collection of similar body types such as sedan, coupe, or SUV. We have many model numbers, most of which have no actual inventory on existence, so we don’t really display those in the settings form, but yesterday we found a bug that requires us to display all model numbers. When all model numbers are being displayed in the form, the form stops working properly, and no submission is ever saved.

The form submission process in Drupal is rather complex, but all you need to know at this point is that Drupal sets an element process_input in the $form_state array that it passes around the functions that handle form processing. If process_input is set to true, then the form submission is handled, otherwise it is not. This happens in the form_builder function defined in includes/form.inc. In order for process_input to be set to truethe form must either be a programmed form, or the $form_state['input']['form_id'] variable must be defined and equal to the $form_id variable that Drupal passes around the form processing functions.

In my case the form was failing to process because the $form_state['input']['form_id'] variable was set to null. At this point, you need to know that $form_state['input'] is set to the value of $_POST for forms submitted using the POST method. Looking at both, the form, and the parameters it sent in the request, I could see that there was a form_id input, and that it was being sent with a value equal to $form_id but PHP had no knowledge of it. It turns out the request wasn’t being fully caught by PHP.

At this point, my guess is that the request is too big for my server settings, or there are too many fields being sent. PHP has settings for both, the maximum size of a POST request that it handles, and the maximum number of input variables. As far as I know there are two places were you can modify these settings: the php.ini file, and the .htaccess file. The preferred way would be to modify the php.ini file, but depending on your host you may not have access to that. In that case, using an .htaccess file would be your best option.

In this stackoverflow question you can get an idea of how to go about modifying the values in case you ever encounter the same issue.

CSS Margin VS Padding

Today, while working on a tiny project, I suddenly wondered why I usually favor margins instead of paddings to create space around elements in CSS. At the moment, given that there are deadlines, I decided to push aside the question, but before that I did a quick search, and opened a Stack Overflow question about the matter so I would not forget about this existential question of mine.

At some point during that tiny project, I came up with a situation that definitely required paddings, and not margins to solve. The situation was this: I had two elements in a sort of lightbox effect. I wanted the “lightbox” to close whenever the user clicked on the element that was sitting behind covering the full window, but not when the user interacted with the element sitting in front, ie the content of the lightbox. The solution was simple, add a click event handler on the back element that closed the lightbox, and a click event handler in the content element that only stopped the propagation of the event. That way whenever the user interacted with the content element the click event would never reach the back element, thus not closing the lightbox.

This method worked well, but I wanted users to have a little room around the content where they could safely click without closing the lightbox. For this, using a padding on the content element was the way to go. In this situation a margin would not have worked because you can ‘t click the margin of an element. Clicking the element was required because only that way could we prevent the click event from bubbling up to the back element.

In the stack overflow question, someone mentions that they usually use padding only when they want to increment the space inside a visible box. I’ve now presented you with another case, although this ones is more of an edge case.

I think most of us prefer margins, but there are cases where padding is the right and maybe only way to go.

orWhereHas in Laravel 5.3

I was recently tasked with updating a project from laravel 5.2 to 5.3. I know even 5.3 is an old version now, but the project has fallen behind on laravel versions for some reason. The update was rather simple, and most of what I had to do was make sure that request validations were properly defined given how laravel 5.3 changed the way validations are handled. However, a couple of days ago I received a notification that something wasn’t right on the platform, and it was returning the wrong results for certain filtered assets.

Since the recent work that had been done in the files that were involved in the broken feature had nothing to do with the problem, the first suspect was the laravel update. After much digging I found out that a rather complex database query had an ‘AND’ in laravel 5.2, but an ‘OR’, when using laravel 5.3. For some reason that I still ignore a model scope was being initialized with orWhereHas. Laravel 5.3 changed how Eloquent handles those cases, and it “now respect[s] the leading boolean of scope constraints” according to the upgrade guide.

In laravel 5.2 the leading boolean wasn’t respected, and scope constrainst were always constructed using AND. This was problematic in most cases where people wanted to start their scopes with OR. However, in this case, AND was the correct way to construct the query. The fact that the program worked before the update was mere coincidence. An unintentional use of a ‘feature’ in laravel 5.2 that was changed (should I say a bug that was fixed?) in laravel 5.3.

Given the fact that I ignore why the original developer felt it was necessary to use orWhereHas in the (rather complex) scope, I decided to pass the issue along the chain to the original developer in hopes he would have a better ideas of whether changing the orWhereHas for a simple whereHas would have other implications.

You can read the upgrade guide, or this stack overflow question about leading booleans in eloquen scope constraints, or the original pull request for the change in laravel’s eloquent to learn more about the change that laravel 5.3 introduced in regards to how it constructs queries when eloquen scopes are used.

Ruby Bundler Install Error on Mac OS

I migrated a project a couple of days ago from Fedora to Mac OS. The project uses bundle to install the required ruby gems, and I ran bundle install when I migrated the project, so today I expected it to just work. But it did not.

One of the gems the project uses is sass, and it also uses a watch task in grunt to compile sass files automatically, However, when I edited a file, I got an error. Sass was not installed. I ran bundle install again, and noticed that the command was returning some errors about certain files not being writable. This is because of the ‘rootless‘ feature in Mac OS, which prevents anybody, even root, from writing to certain locations. One of those locations is /usr/bin, which bundle was trying to write to to add the gem executable files. No wonder I was getting a not-istalled error for sass. However, I hadn’t really realize that just jet.

I decided to investigate the issue, and found that some people who had the same problem fixed it by adding certain location to their path. This is when I actually understood what was going on, because even though I had seen the bundle errors, I hand’t really understood the issue. As I said before, bundle was trying to write to a location where it could not. I.e. /usr/bin.

I did some more researching and found some information about the gemrc file, and how it can be used to tell gem where it should install gems. I created a gemrc file, and tried bundle install. The error didn’t get fixed.

I decided to look for the documentation for bundle install, and there I found that you can specify where gems should be placed, and where the executable files should be placed. I finally ran the command

bundle install --force --path=~/ --binstubs=~/bin

It failed with error

Errno::EACCES: Permission denied @ rb_sysopen – /Users/me/bin/bundle
An error occurred while installing bundler (2.0.0), and Bundler
cannot continue.

AT this point I was loosing hope, and getting frustrated, but I continued looking for an answer. That is how I found that I probably had the wrong permissions for bundle. I listed the contents of my ~/bin directory, and found that the bundle file was owned by root. I changed ownership of the file to me, and this finally got everything working correctly.

It may seem like I fixed this issue in no time, but the reality is that I spent over two hours trying until finally being able to make it work. I should say, though, that I am no ruby developer. This project is the only place were I’ve ever used bundle, and gems that I can think of. Plus, I’m finding out that the ‘rootless‘ feature is at a minimum as annoying as selinux, but I would never, ever, advice anybody to disable it, nor would I do it in my own computer: