I Remember Now, Python is Awesome!

I’ve been brushing off my rusty Python skills this week by doing a Introductory Python course on Treehouse. I’m doing this because of the impressive things I’ve seen Cam Davidson-Pilon do with iPython.

Behold the fruits of my labour! A simple text based guessing game.

guessing_game.py

import random
 
def show_guesses():
  guesses.append(guess)
  print(str(guesses) + " {} more out of 5.".format(5 - len(guesses)))
 
def show_help():
  print("Guess a number between '1' and '10'")
  print("'DONE' quits and 'HELP' displays this help.")
 
def too_big():
  print("{} is too big".format(guess))
 
def too_small():
  print("{} is too small".format(guess))
  
def reset_game():
  global guesses
  global magic_num
  guesses = []
  magic_num = random.randint(1,10)
  print("Okay, ready! I've picked a number.")
  
 
guesses = []
magic_num = 0
reset_game()
show_help()
 
while True:
  if len(guesses) >= 5:
    print("Sorry, you lose. The number was {}.".format(magic_num))
    reset_game()
  response = input("> ")
  
  try:
    guess = int(response)
  except:
    if response == 'DONE':
      break
    elif response == 'HELP':
      show_help()
      continue
      
  if guess == magic_num:
    print("That's it! The number was {}. You win! Play again? (Y/n)".format(guess))
    play_again = input('> ')
    if play_again == 'n':
      break
    else:
      reset_game()
  elif int(guess) > magic_num:
    too_big()
    show_guesses()
  elif int(guess) < magic_num:
    too_small()
    show_guesses()
  continue

DRY Social Media Links

I went a little crazy with social media links last night. I wanted to make a nice nav element full of them. First I found a great github repository and site for the images called simpleicons.org.

With all those great icon options I ended up wanting to make nine links but I wanted to keep things DRY so I used an array and a loop. I was pretty pleased with the result.

_footer.html.erb

<footer>
  <% social_media = [
    ["Github", "github-256.png", "https://github.com/PareidoliaX"],
    ["LinkedIn", "linkedin-256.png", "https://www.linkedin.com/pub/alexander-miller/2b/909/62b"],
    ["CodeSchool", "codeschool-256.png", "https://www.codeschool.com/users/336826"],
    ["Treehouse", "treehouse-256.png", "http://teamtreehouse.com/alexandermiller"],
    ["Khan Academy", "khanacademy-256.png", "https://www.khanacademy.org/profile/PareidoliaX/"],
    ["WordPress", "wordpress-256.png", "http://pareidoliax.ca/"],
    ["Steam", "steam-256.png", "http://steamcommunity.com/profiles/76561198025305101"],
    ["Twitter", "twitter-256.png", "https://twitter.com/PareidoliaX"],
    ["Facebook", "facebook-256.png", "https://www.facebook.com/xander.miller"]
    ] %>
    <div class="row">
      <nav>
        <ul id="social-media">
          <% social_media.each do |media| %>
            <li>
              <%= link_to media[2] { image_tag("https://s3-us-west-2.amazonaws.com/xander-mind/#{media[1]}", alt: "#{media[0]} Logo")} %>
            </li>
          <% end %>
        </ul>
      </nav>
    </div>
  <div class="row">
    <p class="text-right">&copy; 2014 <em>Xander Miller</em></p>
  </div>
</footer>

This code is available in a github gist for easy copying. Happy Coding!

Making a Dynamic Navigation in your Rails 4 layout

Often it is helpful to have an indication on your site navigation of where you currently are. For example if you are on the About page, then the About button in the navigation should be a different colour than the other navigation buttons. On a static website this is easily done with a css class like selected or active. Here is the example of how it is done with the Twitter bootstrap design framework using the active class.

<ul class="nav nav-pills">
  <li class="active"><a href="#">Home</a></li>
  <li><a href="#">Profile</a></li>
  <li><a href="#">Messages</a></li>
</ul>

This is easy to accomplish on a static page. Just change the navigation accordingly on each page but things can be a bit more complicated when using a dynamic framework like Rails. In Rails your site navigation will be in your main layout so you need to make that navigation dynamically sensitive to controller and action that rendered it. You can do this with some helper methods. I’m going to be using Rails 4 helper methods but this can be done easily using more obscure methods in earlier versions of Rails. There is no helper method to my knowledge in Rails that gives you both the controller and the action so we are going to start by building that from the helpers that give use the controller name and the action name.

We need both because if we are using RESTful resource routes neither the controller or the action by themselves will uniquely identify a view. Post may have both an index and a show view so the controller alone is not enough. Comment and Post may both have show and edit actions so the action alone is not enough to identify a view either. Since we are practicing Test Driven Development, lets start with the RSpec example.

application_helper_spec.rb

# helper is an instance of ActionView::Base configured with the
# ApplicationHelper and all of Rails' built-in helpers

require "spec_helper"

describe ApplicationHelper do

  context '#controller_action_name' do
    it "calls #action_name" do
      helper.should_receive(:action_name)
      helper.controller_action_name
    end

    it 'calls #controller_name' do
      helper.should_receive(:controller_name)
      helper.controller_action_name
    end

    it 'returns a concatination of #controller_name and #action_name' do
      helper.stub(:controller_name).and_return('welcome')
      helper.stub(:action_name).and_return('about')
      helper.controller_action_name.should eq('welcome#about')
    end
  end

end

The actually helper will be a one-liner and since it will be used at the application layout level it will have to be an application level helper.

application_helper.rb

module ApplicationHelper

  def controller_action_name
    "#{controller_name}##{action_name}"
  end

end

Now that we have a helper that gives us both the controller and the action name. Lets use it to build the helper method we will use to add the active class to the appropriate element of our navigation. Again starting with the RSpec example.

application_helper_spec.rb

# helper is an instance of ActionView::Base configured with the
# ApplicationHelper and all of Rails' built-in helpers

require "spec_helper"

describe ApplicationHelper do

  context '#controller_action_name' do
    it "calls #action_name" do
      helper.should_receive(:action_name)
      helper.controller_action_name
    end

    it 'calls #controller_name' do
      helper.should_receive(:controller_name)
      helper.controller_action_name
    end

    it 'returns a concatination of #controller_name and #action_name' do
      helper.stub(:controller_name).and_return('welcome')
      helper.stub(:action_name).and_return('about')
      helper.controller_action_name.should eq('welcome#about')
    end
  end

  context "#display_active" do
    it "returns 'active' if the current controller action equals the argument" do
      helper.stub(:controller_action_name).and_return('welcome#about')
      expect(helper.display_active('welcome#about')).to match /active/
    end

    it "returns '' if the current controller action does not equal the argument" do
      helper.stub(:controller_action_name).and_return('welcome#about')
      helper.display_active('welcome#contact').should eq('')
    end
  end

end

And this method will also only be a one-liner in the application helper.

application_helper.rb

module ApplicationHelper

  def controller_action_name
    "#{controller_name}##{action_name}"
  end

  def display_active controller_action
    controller_action == controller_action_name ? "active" : ""
  end

end

Now we just use the display_active method to add a class to our app navigation like this.

_navbar.html.erb

<nav>
  <ul class="nav nav-pills">
    <%= content_tag :li, link_to("Portfolio", welcome_portfolio_path), class: display_active('welcome#portfolio') %>
    <%= content_tag :li, link_to("About", welcome_about_path), class: display_active('welcome#about') %>
    <%= content_tag :li, link_to("Contact", welcome_contact_path), class: display_active('welcome#contact') %>
  </ul>
</nav>

This example should work with bootstrap 3 but the principle should be easy to apply to Foundation or a custom design. I have put all the code snippets in a github gist for easy copying.

Keeping your RSpec Welcome Controller Spec DRY

I was writing controller specs for a personal project I started working on this week. I’m testing like the TSA because I would like the practice with RSpec. My code smell sense started tingling when I noticed myself repeatedly hitting the copy and paste short cut. Do you see the problem?

require "spec_helper"
 
RSpec.describe WelcomeController, :type => :controller do
 
  describe "GET home" do
    it "returns http success" do
      get :home
      expect(response).to be_success
    end
 
    it "renders the home template" do
      get :home
      expect(response).to render_template("home")
    end
  end
  
  describe "GET about" do
    it "returns http success" do
      get :about
      expect(response).to be_success
    end
  
    it "renders the about template" do
      get :about
      expect(response).to render_template("about")
    end
  end
  
  describe "GET contact" do
    it "returns http success" do
      get :contact
      expect(response).to be_success
    end
 
    it "renders the contact template" do
      get :contact
      expect(response).to render_template("contact")
    end
  end
 
end

I’m basically running the same two specs three times, once for each controller action so I decided to keep things DRY by using a loop instead. This is what I came up with:

require "spec_helper"
 
RSpec.describe WelcomeController, :type => :controller do
 
  welcomes = %w{portfolio about contact}
 
  welcomes.each do |welcome|
    describe "GET #{welcome}" do
      it "returns http success" do
        get welcome.to_sym
        expect(response).to be_success
      end
 
      it "renders the #{welcome} template" do
        get welcome.to_sym
        expect(response).to render_template(welcome)
      end
    end
  end
end

I’m sure this is nothing new for RSpec veterans and an even better solution would be to write my own RSpec matcher. Nonetheless I was proud of myself for coming up with this today so I decided to share. The specs are based on the examples for controllers in the rspec-rails repo and I have put the code snippets you see in this entry in a gist for easy copying and pasting.

What version of RSpec should I use?

This is the kind of blog post that goes out of date almost the day it is written, which happens to be August 6th, 2014. However not knowing the version of RSpec to use cost me two productive hours today so I thought despite the perishability, the current answer is worth mentioning. If you are starting a new Rail 4.1 app any time soon the most compatible and stable version of RSpec to use is 2.14.x, both version 2.99.x and 3.0.x aren’t well supported by other gems yet. Capybara, pundit and FactoryGirl all didn’t support rspec 3.0.x.

Beginner Rails Environment in a Vagrant Box

One of the hardest parts of getting started in Rails development is setting up your computer. One of the hardest parts of teaching rails development is dealing with the all the special case problems that arise when students are running different development environments on different operating systems. One solution I’ve heard proposed from a couple different sources is to have all beginners develop in a vagrant virtual machine, that way the teacher only has to deal with the peculiarities of one environment and students can follow one simple set of instructions to set up their computers.

The problem is that poking around the Internet, I couldn’t find a beginner friendly simple set of instructions anywhere or a vagrant vm box setup specifically for Rails development beginners. This blog entry will hopefully provide Rails beginners with both simple instructions to get started and virtual machine to download. Continue reading

Using Partials to make controller specific navigation in Rails

I’ve been playing with partials lately and while I am still a Rails newbie. I stumbled upon what I think it is a pretty cool trick. I like to render my navigation in a partials to modularize my layout. I noticed that when I do do this I have to specify the layout view directory in the render call because the controllers are rending the layout  so the code has to be like this:

<%= render "layouts/nav" %>

Then I realized I could use this to render controller specific partials by placing _nav.html.erb partials in the specific view directories and adding a little logic using the params hash. So I changed my layout nav code to this:

<% if lookup_context.exists?("nav", params[:controller], true) %>
  <%= render "nav" %>
<% else %>
  <%= render "layouts/nav" %>
<% end %>

So now if the controller view directory has a _nav.html.erb it renders that and if not it defaults to the one in the layout directory. Of course the same thing could be achieved using content_for methods but I find this way is much more intuitive and less cluttered.

Addendum

Chris Saunders rightly pointed out that in MVC conditional logic should not be in the views, ideally it should be in an object like the controller itself. That wouldn’t work in this case, but it is still better to put the conditional logic in the Application Helper to get it out of the view like this:

module ApplicationHelper
  def navigation
    if lookup_context.exists?('nav', params[:controller], true)
      {partial: 'nav'}
    else
      {partial: 'layouts/nav'}
    end
  end
end

And then call it from the layout.html.erb like this:
<%= render navigation %>

Today’s Itinerary

  • Swimming {from 9:00}
  • Read Ruby on Rails 4.0 Guide  {unti 11:30}
  • Yoga {noon – 13:15}
  • Complete 2 Bloc.io Checkpoints
  • Take Alisa Swimming [4:00]
  • Darren’s for Darren’s bookclub {20:00-22:00}

Done Dashing (for now…)

I was so good for a couple days last week about updating this blog and then I disappeared off the face of the Interwebz. I was Dashing, errr, working on a widget for Shopify’s Dashing gem for Shopify’s Dashing Widget Contest.

Well I put in a lot of effort, learned a lot, had a lot of fun but I didn’t get it done in time. But I nonetheless did get done. I called my widget Ntile. It is ready to be used and downloaded.

Ntile – A widget for Shopify's Dashing gem
Ntile – A widget for Shopify’s Dashing gem

In the future I have some refactoring I want to do on the code and some features I want to add but for the time being I’m back to learning Ruby on Rails double full time.