Fake user profiles

For a demo website I just built I needed a set of fake user profiles. I needed something with names, address and a profile picture. I didn't want to use any data from real existing people, but still needed something the looked real enough.

So I got a sample of fake profiles from randomuser.me, making sure that no two profiles had the same picture. I also added in the mix a few pictures from my coworkers at Algolia as an easter egg.

Everything is pushed to GitHub, along with the scripts used to generate the data. Everytime you launch the script, it will generate a new list of random profiles.

Here is a sample of what a fake user looks like:

{
  "email": "liam.walters@example.com",
  "gender": "male",
  "phone_number": "0438-376-652",
  "birthdate": 826530877,
  "location": {
    "street": "9156 dogwood ave",
    "city": "devonport",
    "state": "australian capital territory",
    "postcode": 7374
  },
  "username": "biglion964",
  "password": "training",
  "first_name": "liam",
  "last_name": "walters",
  "title": "mr",
  "picture": "men/50.jpg"
}

And the full dataset can be downloaded from GitHub as well, and all pictures referenced in the list are also available in the repo.

Testing several Jekyll versions

Maintaining a Jekyll plugin that must work for two major versions of Jekyll is a challenge.

I released the Jekyll Algolia plugin for Jekyll 2.5 (the version used by GitHub). Jekyll recently released their v3.0 and while the plugin is still working, it produces a huge number of deprecation warnings.

This is caused by the fact that Jekyll changed the place where some information were stored (at the root of an objet or in a sub data key). This was mostly a really easy fix to add but I wanted to make sure I wasn't adding any regression as well.

Testing multiple versions

That's when my journey into testing the plugin for two different major version began. I needed a way to launch my tests for Jekyll 2.5 as well Jekyll 3.0 and check that everything was green.

I used Appraisal, a wonderful tool by Thoughtbot. It lets you define your Gemfile like usual, but also named overrides on top of it.

# ./Gemfile
source 'http://rubygems.org'

gem 'algoliasearch', '~> 1.4'
gem 'appraisal', '~> 2.1.0'
gem 'jekyll', '~> 2.5'

group :development do
  gem 'appraisal', '~> 2.1.0'
  gem 'rspec', '~> 3.0'
  gem 'simplecov', '~> 0.10'
end
# ./Appraisals
appraise 'jekyll-v2' do
  gem 'jekyll', '~> 2.5'
end

appraise 'jekyll-v3' do
  gem 'jekyll', '~> 3.0'
  gem 'jekyll-paginate', '~> 1.1.0'
end

As you can see, I simply defined my dependencies in Gemfile, then override them in Appraisal, naming each group. jekyll-v2 will use Jekyll 2.5 while jekyll-v3 will use 3.0. Jekyll 3 no longer comes shipped with jekyll-paginate so I had to manually add it as well.

Once this is done, be sure to run appraisal install after the usual bundle install. This will create all the needed gemfiles in ./gemfiles.

gemfiles
├── jekyll_v2.gemfile
├── jekyll_v2.gemfile.lock
├── jekyll_v3.gemfile
└── jekyll_v3.gemfile.lock

Running tests in two versions

Running scripts in one version or the other is now as simple as prefixing the command with appraisal jekyll-v2 or appraisal jekyll-v3. Granted, with bundler and rake you end up typing stuff like appraisal jekyll-v3 bundle exec rake spec, but just put it all in a wrapper bash script and problem solved.

This is actually the content of some of my scripts in ./scripts:

#!/usr/bin/env bash
# ./scripts/test_v2
cd "$(dirname "$BASH_SOURCE")"/..

echo "Testing under Jekyll 2"
appraisal jekyll-v2 bundle exec rake spec
#!/usr/bin/env bash
# ./scripts/test_v3
cd "$(dirname "$BASH_SOURCE")"/..

echo "Testing under Jekyll 3"
appraisal jekyll-v3 bundle exec rake spec
#!/usr/bin/env bash
# ./scripts/test
cd "$(dirname "$BASH_SOURCE")"

./test_v2 && ./test_v3

Running some tests only for Jekyll 3

I had a couple of tests that made sense only for Jekyll 3, so I had to find a way to only execute them when the Jekyll loaded as a dependency was > 3.0.

Here is the little ruby method I added to my spec helpers:

def restrict_jekyll_version(more_than: nil, less_than: nil)
  jekyll_version = Gem::Version.new(Jekyll::VERSION)
  minimum_version = Gem::Version.new(more_than)
  maximum_version = Gem::Version.new(less_than)

  return false if !more_than.nil? && jekyll_version < minimum_version
  return false if !less_than.nil? && jekyll_version > maximum_version
  true
end

Gem::Version comes bundled with all the semver comparison you might need, so better to use it than coding it myself.

And an example of how I use it in the tests:

if restrict_jekyll_version(more_than: '3.0')
  describe 'Jekyll > 3.0' do
    it 'should not throw any deprecation warnings' do
      # Given

      # When
      post_file.metadata

      # Expect
      expect(@logger).to_not have_received(:warn)
    end
  end
end

Using it with Guard

This gem is even compatible with Guard. You do not have to change anything to your Guardfile, but simply prefix your guard call with appraisal like for bundler.

Here is my default config for rspec TDD:

# Guardfile
guard :rspec, cmd: 'bundle exec rspec --color --format documentation' do
  watch(%r{^spec/.+_spec\.rb$})
  watch(%r{^lib/(.+)\.rb$})     { |m| "spec/#{m[1]}_spec.rb" }
  watch('spec/spec_helper.rb')  { 'spec' }
end

notification :off
#!/usr/bin/env bash
# ./scripts/watch_v2
cd "$(dirname "$BASH_SOURCE")"/..

appraisal jekyll-v2 guard 
#!/usr/bin/env bash
# ./scripts/watch_v3
cd "$(dirname "$BASH_SOURCE")"/..

appraisal jekyll-v3 guard 

Unfortunatly, it is not possible to run both watch_v2 and watch_v3 at the same time, so you still have to do TDD on one version at a time.

Configuring TravisCI

Appraisal is also Travis-compliant out of the box. Just run appraisal generate --travis to get the config you need to add to your .travis.yml file.

This will simply output the matrix of Gemfiles to use. In my case it was nothing more than:

gemfile:
  - gemfiles/jekyll_v2.gemfile
  - gemfiles/jekyll_v3.gemfile

Conclusion

It took me way more time to configure the testing environment for multiple Jekyll version than "fixing" the initial bug. But in the end I'm now sure I won't cause any regression in one version when I fix a bug in another.

Everything is tested on Travis on all supported Jekyll and Ruby versions.

Cleaner code

In a previous job, I did a lot of code reviews with a team of more junior developers. My job was to help them write better, more readable and more maintainable code. There was something that came back really often in my reviews: simplifying the if flow.

I'll give you a code example, along with the modifications I suggested to it.

Note that the code is not the real code of the app, but one crafted for the needs of this blog post.

The original code

function isFormValid(inputs) {
  if (inputs.age < 50) {
    if (inputs.gender === 'M' && inputs.firstName !== '' && inputs.lastName !== '') {
      return true;
    } else if (inputs.gender === 'F' && inputs.firstName !== '' && inputs.lastName !== '' && inputs.maidenName !== '') {
      return true;
    } else {
      return false;
    }
  } else {
    return true;
  }
}

What does it do? It is a (simplified) form validation method. Given an age, gender, firstName, lastName and possibly maidenName, it checks if the form is valid.

The rules are:

  • firstName and lastName are mandatory fields.
  • If you're a woman, maidenName is then also mandatory.
  • The form is always valid if you're older than 50.

As it is currently written, the code works, but it is very verbose and not straightforward. Let's rewrite it.

Remove useless else

The more branching a code has, the more difficult it is to visualize in your mind. Bugs will sneak in more easily in a code that is hard to understand. As the saying goes: the less code you have, the less bugs you can have.

The first step I usually take is to remove all the cruft. The elses in this code are useless. Every preceding if does a return, so if the code goes inside that branching, the whole method would stop. The else is then useless and only adds noise.

Let's rewrite the method:

function isFormValid(inputs) {
  if (inputs.age < 50) {
    if (inputs.gender === 'M' && inputs.firstName !== '' && inputs.lastName !== '') {
      return true;
    } 
    if (inputs.gender === 'F' && inputs.firstName !== '' && inputs.lastName !== '' && inputs.maidenName !== '') {
      return true;
    } 
    return false;
  }

  return true;
}

What we have now is a simple test to see if the user is under 50 at the start, where we then test for the two only passing scenarios and return false otherwise. If above 50, we always return true.

We've changed a complex multi-level deep nesting of if/else into a simple branching and enumerations of valid cases. This is easier to grasp.

Return early, return often

But this code is not yet clear enough. I don't like the big if surrounding almost the whole method. What we should do is revert the condition to discard the edge-cases earlier and leave the bulk of the method to test the common cases.

function isFormValid(inputs) {
  if (inputs.age >= 50) {
    return true;
  }

  if (inputs.gender === 'M' && inputs.firstName !== '' && inputs.lastName !== '') {
    return true;
  } 
  if (inputs.gender === 'F' && inputs.firstName !== '' && inputs.lastName !== '' && inputs.maidenName !== '') {
    return true;
  } 

  return false;
}

In the first lines of the method, we check for the easy validations, the one that can fit in one line and return quickly. This lets our mind quickly discard all the edge cases, and focus the code on the most common use-cases. This way, we do not have to mentally keep track of all the pending if/else the previous code was creating.

Shorter conditions

The code is getting more readable already, but there are still code duplication that we should avoid. We are testing for inputs.firstName !== '' && inputs.lastName !== '' twice. Let's move that into a carefully named variable.

function isFormValid(inputs) {
  if (inputs.age >= 50) {
    return true;
  }

  var mandatoryNamesDefined = (inputs.firstName !== '' && inputs.lastName !== '');
  if (inputs.gender === 'M' && mandatoryNamesDefined) {
    return true;
  } 
  if (inputs.gender === 'F' && mandatoryNamesDefined && inputs.maidenName !== '') {
    return true;
  } 
  return false;
}

This change has two benefits. First, the if reads better in plain english if you read it in your mind. This will help further contributors (or even you, in 6 months time) understand what the if is actually testing.

Second, if in the future you decide that only the firstName is mandatory, you'll only have to change the var mandatoryNamesDefined declaration and all your checks will be impacted.

Extracting this check into a variable was easy. The hardest part is correctly naming the variable. If you have trouble finding a nice name for your variable, this might be because you're trying to fit to many checks in one variable. Split it in several and then combine them.

One step further

There is still one change we can add. People can only chose a gender of M or F, so we can even reverse the way checks are made at the end by using the return early, return often rule again and inverting the conditions.

function isFormValid(inputs) {
  if (inputs.age >= 50) {
    return true;
  }

  var mandatoryNamesDefined = (inputs.firstName !== '' && inputs.lastName !== '');
  if (!mandatoryNamesDefined) {
    return false;
  } 

  if (inputs.gender === 'F' && inputs.maidenName === '') {
    return false;
  } 

  return true;
}

Now the code reads like a bullet point list, much closer to the original spec:

  • If older than 50, the form is valid.
  • If firstName and lastName are empty, the form is invalid.
  • If you're a woman and haven't filled your maidenName, the form is invalid.
  • All other cases are valid.

Conclusion

Code is like literature. Writing it is really easy, anybody can do it. You just have to learn the basic syntax and here you go. Writing code that reads well is harder, and you have to methodically re-read it several times and remove all the useless parts so the reader mind grasps everything easily.

Think of the next person that will read your code to add a new feature or fix a bug. That next person might well be you. You don't want to spend more time understanding the code than actually fixing it. Make your (future) self a favor, and write code that reads easily.

Nginx tweaks

I just realized I have a bunch of posts forgotten into my draft folder. I'll dust them up and publish them, using my 3 hours train journey the best I can.

So this one if about a few tweaks I did to the nginx config used on this very own blog.

Prevent access without a hostname

The first one is a small security measure to disallow serving files when accessing the server through its IP address. Only requests that specify a valid hostname will be honored. This will prevent people from accidentally browsing your tree structure.

http {
  [...]
  server {
    listen 80;
    return 444;
  }
}

Defining a custom 404 page

It is always better to serve a real 404 page than the default one. To be able to define a specific 404 page for each website hosted, you have to use the error_page directive.

server {
  [...]
  error_page 404 =404 /path/to/404.html
  # You can also use: 
  # error_page 404 /path/to/404.html
  # Which will do a 301 redirect and not a 404
}

Redirect root to www

Finally, one last trick to redirect all requests made to the root domain to its www counterpart. Hosting a website directly on the root domain will cause issues when you have to handle cookies. Cookies defined on a top domain will be send to all requests targeting a subdomain. By hosting your website on the top domain, you expose yourself to sending useless cookies to any subdomains you might create.

Therefore, it is better to host your website on a www subdomain and redirect any requests made to the root to the www subdomain.

server {
    server_name pixelastic.com;
    rewrite ^ $scheme://www.pixelastic.com$uri permanent;
}

Here was a short list of nginx tweaks. It's better published than sitting in my draft folder.

Memory techniques

I recently gave a talk about memory techniques that I use. I'm posting a summary here for those that could not attend.

The memory I talked about had nothing to do with RAM, but with the memory inside our brain. I read a book named Moonwalking with Einstein, by Joshua Foer and wanted to share what I learned from it.

Moonwalking with Einstein

It tells the story of a journalist that met a memory champion. Like me, he did not know that there were memory contests, and that one could become a champion of it. Nevertheless, he learned several techniques from this champion and in one year was able to enter the world contest himself.

The book is really easy to read, it flows like a novel. But everytime a new technique was explained, I tried it on my own brain, to see if this was working.

Mental images

The first one is not a technique in itself. It's the main brick upon which all other techniques are based. The idea is to understand what our brain can do effortlessly, and what is very hard for it to do. Once we know that, we'll stop asking it to do hard stuff, and only focus on what it is naturally good at.

There are three main elements that makes something easy to remember. First, if it's unique, rare or weird, you'll remember it much more easily than something common and mundane. Second, if you can see it, smell it, hear it, taste it or touch it, than it feels more real and you'll remember it better. Finally, if it makes you feel something, either joy, anger or sadness, you'll have personnaly lived it, so you'll remember.

Another really nice characteristic of our brain is that it can remember things that never happened. You can close your eyes and imagine that a giant dinosaure is walking down your street, breathing fire and burning buildings. This never happens (and never will), but you can picture it. In a few days you might even remember it.

Memory palace

The first real technique is called the Memory Palace. It uses one more thing for which our brain is very powerful: spatial representation. You just have to spend 30s in an apartment you don't know to have an accurate representation of the various rooms, their volume and how they are arranged together. For places you've visited often, this is even more powerful. You can just close your eyes and mentally navigate in your childhood home, your apartement, or your job place.

So the Memory Palace is a way to remember an ordered list of elements, like a grocery list. Instead of writing it down on a paper, close your eyes and mentally walk inside your appartement, and put one element of your list in each room. But do not simply picture you putting it in the room. Emphasize it. Extrapolate it. Make it unforgettable.

For example if you need to buy cheese and eggs, imagine that the walls and ceiling of your kitchen have melting cheese all over them, or that all your furnitures turned to Swiss cheese. Instead of putting 6 eggs in your living room, picture them seated in your sofa, having a drink and a chat. The weirdest, the better.

Then, instead of reading your list, picture yourself walking in your appartement, one room at a time, and the crazy mental images will pop from memory directly. Try it if you don't trust me, it really works even on the first try. The first time I did it I was able to remember a list of 20 elements easily (my appartement is not that big, you can put several elements per room). The best part is that I still remembered the list months later.

Spaced repetition

The second technique is called spaced repetition and is a way to not forget what you learn. We've all experienced it before. On an exam eve, you stay up late and learn as much as you can in a short time. You remember most of it for the exam, but then one week later, you've forgotten everything.

This happens because your short term memory will disappear if you do not call it. The spaced repetition technique lets you remember things right before you forgot them. I personnally use the AnkiDroid application for that.

Anki

You create (or download) a deck of cards on a subject (all the countries of the world and their flags for example). Each card of the deck is two-sided, with a question on one side and the answer on the other. When you draw the first card of the deck, you'll see the question. You mentally think the answer, then press the "Ok" button to see the real answer.

If you were right, we press the "Good" button and it will ask this same card again the next day. If you're still right tomorrow, it will ask you in a few days, then a week, a month, etc. But if you're wrong it will ask you again in 10mn until you got it right. Everyday it will add a few new cards to the one you've already seen.

The one you've trouble remembering will keep popping day after day until you remember them. The one you remember easily will not be asked often.

The best thing is not even that this works well, it's that it is really fun to do. In one month (20mn in the subway every morning), I learned the whole countries and flags decks. I found it so fun that I then started to learn their capitals and the USA states and capitals.

I would have loved to have known this technique when I was still a student. This would have made my learning so much quicker and enjoyable. Knowing this technique I am now confident that I can learn anything, given enough time, and without pain.

Conclusion

This book told me how to write stuff to my brain so I can easily pull it later. To be honest I rarely use this technique. I do my shopping online and can always check stuff on Wikipedia if I forgot. But I'm happy to know how my own brain is working.

Search