Musings of an 8-bit Vet

A DaVinci Coders Student Tech Diary

Adding Git Branch to the Terminal Prompt

As you begin to work with branching in git, one of the first commands you learn is git branch, which gives output similiar to this:

1
2
3
  57933296_assignments_dropdown_master
* 6724_refactor_master
  master

The branch identified by the * on line 2 is the current branch.

In the heat of coding it can be useful to know what branch you are on lest you make a commit, push code, or pull from the wrong branch. Since branches are analogous to directories, wouldn’t it be nice if the terminal prompt could tell us not only what directory we were in, but what branch we were on?

As an example, my terminal prompt looks like this:

1
2
[~/workspace/blog]
(master) $

Line 1 is my current working directory, on line two in ( ) is the current git branch master. Pretty useful.

I cannot take any credit for this. The code I present below was passed on to me by another developer, who also had no idea where it came from. I would give credit if I knew who to give it to, but instead I give thanks.

In your .bash_profile you will need to add the following code snippet to enable parsing of the git branch from the environment:

1
2
3
4
5
# git prompt settings
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
export -f parse_git_branch

Now you can add parse_git_branch to your prompt settings in .bash_profile, like this:

1
2
# prompt
export PS1="[\w]\n\$(parse_git_branch) \$ "

Feel free to experiment, and an on-line search will yield many examples.

Weaving Code

I recently came across the most amazing piece of video footage while watching a documentary on the technology used during the Apollo missions of the late 1960’s.

That era was a little bit like an alternate decade of the 21st century that sort of just showed up in the middle of the 20th century. In addition to tremendous leaps in aviation and space-flight that decade gave us advances in medical, material, and computer science.

To put it in perspective, the working memory of the navigation computer for the Apollo missions was just 72 kilobytes! Things that we take for granted now had to be invented from scratch, including interrupt driven multi-processing algorithms and reliable data storage.

For a fascinating look at how the latter was solved, watch this video:

For more about this amazing and lost technology see the Wikipedia entry: Core Rope Memory

On a separate note, this is a fascinating and possibly forgotten example of diversity in coding.

Capture OMNIAUTH Failures in Development Mode

As part of a recent Rails project, I was implementing authentication using GitHub credentials via OmniAuth.

I came across an annoying problem with the way OmniAuth handles a failure to authenticate while in development mode. In normal deployment a failure to authenticate will redirect back to the requesting website.

However, while in development mode in Rails, the failure endpoint causes the controller to throw an error and brings the site to a halt. This is not particularly graceful.

After some Googling I found a solution:

Take a look at the omniauth.rb file under the initializers directory of your Rails app:

1
2
3
4
5
6
7
8
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET'],
            scope: "user:email"
end

OmniAuth.config.on_failure = Proc.new { |env|
  OmniAuth::FailureEndpoint.new(env).redirect_to_failure
}

The first line configures the Rails middleware to use OmniAuth and to pass various values to the provider, in this case GitHub.

The code on line 6-8 solves the development failure endpoint by allowing you to redirect to the page of your choice via routes.rb:

1
2
get '/auth/:provider/callback' => 'sessions#create'
get '/auth/failure', to: redirect('/')

Further actions would be handled by the sessions or other authentication controller.

This allows you to better test authentication, and to get an idea of how your application will behave without having to deploy it first. The code can remain in production, it does not need to be removed.

I’ll cover more on OmniAuth authentication in a later post.

Resources:

Intridea OmniAuth FAQ

Make Mine a Single: On the Use of Quotation Marks

Here are two lines of Ruby code:

1
2
puts 'Have a nice day!'
puts "Have a nice day!"

They both print the same string to the display. The first uses ‘single quotes’, the second uses “double quotes”. Now, any new Rubyist quickly learns that you use single quotes for simple or static strings, and double quotes for more complicated strings, with special characters, etc. You also use double quotes for so-called “interpolated strings”, where you want to be able to print a variable or other derived value in the string, e.g.

1
puts "Have a nice day, #{person_name}"

So if double quotes will perform the same function as single quotes, why not just use them all the time?

When I posed this question in class the other day it was suggested that whenever the Ruby interpreter sees single quotes it just prints the string, and doesn’t bother to check if there is anything possibly going on in between the ‘’’s. But when Ruby sees double quotes, it has to check each character to see if there is any interpolation required. This is time consuming, and computationally costly. If you are working with thousands of lines of code it can really add up.

So I wrote a quick benchmark to check just how costly this really is, the total time taken is displayed after real:

1
2
3
4
5
6
7
8
9
10
time ruby quote_test.rb   # puts 'Hello there!' * 1,000,000

real  0m5.130s
user  0m0.081s
sys 0m0.150s

time ruby quotes_test.rb  # puts "Hello there!" * 1,000,000
real  0m5.076s
user  0m0.081s
sys 0m0.152s

Huh? Turns out a million puts is actually slightly faster with double quotes. Maybe I need to give Ruby some more to do:

1
2
3
4
5
6
7
8
9
time ruby quote_test.rb   # puts 'Hello there!' * 3,000,000
real  0m15.246s
user  0m0.087s
sys 0m0.357s

time ruby quotes_test.rb  # puts "Hello there!" * 3,000,000
real  0m15.170s
user  0m0.088s
sys 0m0.347s

WTF? Double quotes is still slightly faster. Guess we need to dig a little deeper.

Turns out there is big discussion of this on Stack Overflow, click the link to read all about it.

The short version is this, Ruby doesn’t just pass over single quoted strings when it evaluates. It has to look at every character to render the string in memory, regardless of single or double quotes, even with interpolation. After some pretty extensive bench-marking there is no real cost to using double quotes, and it is often slightly faster.

I suspect that the real reason we use single quotes is one of style. It can’t be for code efficiency, and if you later need to update a string to use interpolation, you would also have to change the single quotes to double quotes.

I’m all about style, so make mine a single!

(But I reserve the right to change my mind later…)

Rails and TDD Screencasts Worth Watching

Just a quick post to describe two excellent on-line resources that I have found to be extremely helpful as we enter the mid-point of our training at DaVinci Coders.

The first is Ryan Bates’ excellent RailsCasts series of Ruby on Rails screencasts. While this is a subscription service, Ryan has generously made many of his older screencasts available for free. The amount of technical expertise and pro-level tips is absolutely amazing for me as a junior Rails dev. Prior to this I had no real notion of some of the topics that RailsCasts covers, but now that I’m working with Rails every day, this content is absolutely priceless.

The second is the CodeShip series called Testing Tuesday. As the name suggests, these are short video tutorials on various aspects of TDD and BDD tools and skills, like RSpec, Cucumber, and other languages beyond Ruby and Rails. Even better, these are free. They are also posted online at Vimeo.

The beauty of both of these resources – and I’m sure there are others – is that they are short and to the point. Each are about 10 minutes long, and address a problem or provide an overview of a technique that you can put to work right away.

Next time you are browsing the web and watching YouTube videos, take a look at one of these resources and learn something that will make you a better developer.

Tame Git Commits With Squash

In class we are working our way through the Ruby Koans. This is partly to learn Ruby, and partly to get us used to making git commits and doing pull requests.

While exploring the section “about_regular_expressions” and fixing each test and doing some Gitx practice, I found myself the proud owner of 27 separate commits!

At this point Jason Noble, our instructor, stepped in and said something like “Wow, that’s a lot of commits. You should git rebase -i and squash some of them.”

What is squash, you ask? It is where you take a number of commits and turn them into a single commit, combining the commit messages at the same time.

In the following example, lines 3-7 are five commits I performed:

1
2
3
4
5
6
7
8
9
[~/workspace/squash_reword]
(master) $ git log --oneline
d3d80ce Add README file
b209207 Include testing file
53ca0f5 Env >> file.txt
1962bf9 Add another_file.txt
44d0164 Initial commit
[~/workspace/squash_reword]
(master) $

Issuing the following command: git rebase -i HEAD~4 make the default editor editor open up git-rebase-todo with the following content:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
pick 1962bf9 Add another_file.txt
pick 53ca0f5 Env >> file.txt
pick b209207 Include testing file
pick d3d80ce Add README file

# Rebase 44d0164..d3d80ce onto 44d0164
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

I used HEAD ~4 to tell rebase to count four commits from HEAD. If you are rebasing against a remote you would use something like git rebase -i upstream/master.

The instructions on how to use all these features are in the comments below the list of commits. Change pick to squash on the commits you want to combine, and save your changes.

WARNING: Do NOT change the first line! Bad things happen.

1
2
3
4
5
6
pick 1962bf9 Add another_file.txt
squash 53ca0f5 Env >> file.txt
squash b209207 Include testing file
squash d3d80ce Add README file

# Rebase 44d0164..d3d80ce onto 44d0164

Upon closing the editor, you will be presented with the file COMMIT_EDITMSG containing all the messages from the squashed commits:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# This is a combination of 4 commits.
# The first commit's message is:
Add another_file.txt

# This is the 2nd commit message:

Env >> file.txt

# This is the 3rd commit message:

Include testing file

# This is the 4th commit message:

Add README file

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# HEAD detached from 1962bf9
# You are currently editing a commit while rebasing branch 'master' on '44d0164'.
#
# Changes to be committed:
#   (use "git reset HEAD^1 <file>..." to unstage)
#
# new file:   README.md
# new file:   another_file.txt
# modified:   file1.txt
# new file:   file_spec.spec

Edit the new single commit message, and remove any duplicated or extraneous text, and hit save and close the file. Git will update the files and adjust the commit. Your list of commits now looks like this:

1
2
3
4
5
(master) $ git log --oneline
5dd5037 Add README and testing files
44d0164 Initial commit
[~/workspace/squash_reword]
(master) $

Problem solved!

You can also use the same procedure to edit commit messages, only use the option reword instead of pick.

On TDD and Technical Hiring

Outside-in development often feels strange to newcomers. Most developers prefer to start with the “important” part of an application … Thinking like a server and not a client can lead to overengineering by implementing more than you need. Your resulting objects and their interfaces will also be less than optimal, or at least take longer to get quite right.

We have started exploring test drive development in class, which can be a bit of a conceptual shift. TDD goes hand in glove with Agile practices because it encourages rapid delivery of working code, in discrete steps. As a bonus it creates a living document of the development process that can be used further down the road of an applications life-cycle to make sure that no new code breaks any of the old code.

The quote above comes from an excellent blog entry by Jared Carroll, Beginning Outside-In Rails Development with Cucumber and RSpec. Jared gives an overview of how TDD should work. Anyone getting started in TDD should read it and let it sink in.

On another note, as aspiring junior web-devs, this recent thoughtbot podcast is worth listening to: podcast #59: Nowhere to Hide.

In the episode, Ben Orenstein speaks with thoughtbot CTO Joe Ferris about the technical interview process at thoughtbot, and more.

Thanx for reading, stay tuned for more from the frontlines…

Strings & Things

Two useful things I learned doing homework over the weekend:

USEFUL THING 1: git commit —amend

Lets say that your fingers get ahead of your brain, and that you write your

1
git commit -m "Mad code skilz"

and then realize that you forgot to add your modified file.

Well, go ahead

1
git add thatfile.txt

and then issue

1
git commit --amend

This will combine the last two commands together, your forgotten file will get linked with the commit message. Problem solved.

USEFUL THING 2: Control significant digits in Ruby float returns

While building our CashRegister class, I ran into the problem that Ruby floats return way more digits after the decimal point than you need to make change.

For example, if you pay for an $8.30 purchase with a $10 bill, you do not expect to get the message:

Your change is $1.6999999999999993

Thanks to a quick HipChat session with classmate Aron, I arrived at the following way to control float output:

1
puts "Your change is $#{sprintf("%0.2f",@reg_change)}"

Let’s break it down, the key part here is inside the string interpolation:

1
sprintf("%0.2f",float)

In particular, the “%0.2f” is telling sprintf that you want output to be offset by 0 digits, and include only .2 digits after the decimal point.

If you want to set the width of your float output, to say right justify, change the 0 to a larger number, 10 would include padding to make the field 10 digits wide. If you want more or less precision after the decimal, change the number after the . to any number you choose, say .1 or .5.

My final output: Your change is $1.70. Problem solved.

Thanx for reading. Stay tuned for more from the front lines…

Matters of Style

As we are starting to write code, it becomes apparent that some code just looks better than other code. I’m pretty sure the Ruby interpreter doesn’t care, but source code is really a document of the product that the code produces so it is important that it be readable and understandable to others.

Ruby is pretty expressive, and it seems to offer a lot of flexibility with the syntax. This could lead to a lot of variation in style. Just as there are standards for style in the production of written works, so there are for programmers.

For Ruby that style guide seems to be: BBatsov’s Ruby Style Guide.

It’s an envolving document with a lot of examples of good and bad coding style, some of which I am certain are parts of large philosophical debates. In any event as a new Rubyist I feel it is important to develop good habits. I read through the whole document and here some picks for new programmers to be aware of when writing code, based on the sort of code we are writing now.

All examples courtesy of BBatsov.

Limit lines to 80 characters.

Avoid trailing whitespace.

Use spaces around operators, after commas, colons and semicolons, around {and before }. Whitespace might be (mostly) irrelevant to the Ruby interpreter, but its proper use is the key to writing easily readable code.

1
2
3
4
sum = 1 + 2
a, b = 1, 2
1 > 2 ? true : false; puts 'Hi'
[1, 2, 3].each { |e| puts e }

No spaces after (, [ or before ], ).

1
2
some(arg).other
[1, 2, 3].length

Use empty lines between defs and to break up a method into logical paragraphs.

1
2
3
4
5
6
7
8
9
10
11
def some_method
  data = initialize(options)

  data.manipulate!

  data.result
end

def some_method
  result
end

Use spaces around the = operator when assigning default values to method parameters:

1
2
3
4
5
6
7
8
9
# bad
def some_method(arg1=:default, arg2=nil, arg3=[])
  # do something...
end

# good
def some_method(arg1 = :default, arg2 = nil, arg3 = [])
  # do something...
end

Add underscores to large numeric literals to improve their readability.

1
2
3
4
5
# bad - how many 0s are there?
num = 1000000

# good - much easier to parse for the human brain
num = 1_000_000

Don’t use block comments. They cannot be preceded by whitespace and are not as easy to spot as regular comments.

1
2
3
4
5
6
7
8
9
# bad
== begin
comment line
another comment line
== end

# good
# comment line
# another comment line

That’s probably enough to get started. There is also a very useful gem RuboCop that will tell you where you are diverging from these recommendations.

Dates/Times Are Hard

Our instructor,Jason Noble, sent out an email this morning about the homework. In this homework we had progressed beyond the ubiquitous hello_world.rb, and had moved on to calculating how many seconds there were in various blocks of time. In particular, how many seconds are there between now and 20 or 100 years from now?

Turns out that dates and times are hard to get a handle on in programming. Especially since a leap year is every 4 years from 1804, but not every 100, and then again every 400 years. Confusing, I know. Not just for us, but for own programming tools, and a lot of other folks too.

Jason’s email addressed the issue that depending on how you do your calculations you end up with different answers:

Jason originally had these values as the specified output:

That means when you turn 20, you've been alive for 628992000 seconds,
and if you make it to 100, you will have lived 3144960000 seconds.

Classmate Aron was first to finish and his output was slightly different:

That means when you turn 20, you've been alive for 630720000 seconds,
and if you make it to 100, you will have lived 3153600000 seconds.

Calculation methods were to blame.

Jason:

86400 * 7 * 52 * 20  # seconds/day * 7 days/week * 52 weeks/year * 20 years
86400 * 7 * 52 * 100  # seconds/day * 7 days/week * 52 weeks/year * 20 years

365 days != 52 weeks * 7 days/week (364 days)

Aron:

86400 * 365 * 20  # seconds / day * 365 days / year * 20 years
86400 * 365 * 100  # seconds / day * 365 days / year * 100 years

(Aron is more accurate, but he forgot to account for leap years)

Another possibility from Jason:

86400 * 365.25 * 20  # seconds / day * 365.25 days / year * 20 years  => 631152000
86400 * 365.25 * 100  # seconds / day * 365.25 days / year * 100 years => 3155760000

(Looks like Jason is getting closer by trying to account for leap years. A year is actually = 365d, 5h, 48m, 47s. The fractional diffence is why we have leap year. That is an additional 20,927 seconds per year)

Jason used the Rails console to get a slightly better answer:

20.years is 631152000 seconds
100.years is 3155760000 seconds

Who has the right answer? Is there another algorithm?

My answer was also slightly different since I actually counted the leap years for 20 and 100 years from now, 5 & 24 respectively.

I then added in the additional days to yield:

20 years from now is 631152000 seconds,
100 years from now is 3155673600 seconds.

Notice that my 20 year number is the same as the Rails computation, and my 100 year number is much closer. In fact it’s off by exactly one day. Looks like Rails missed the fact that 100 / 4 = 25 is not an accurate way to count leap years.

I also tried using the Time function in Ruby:

1
2
3
4
5
6
7
8
9
# Seconds from now till twenty years from now.
irb> puts (Time.gm(2033, 7, 23, 11, 03) - Time.new)

>> 631130357.633387

# Seconds from now till 100 years from now.
irb> puts (Time.gm(2113, 7, 23, 11, 04) - Time.new)

>> 3155651903.756982

Again, slightly different answers. There are several gems to tackle this problem as well. But this is where I stopped. Hopefully this stimulates some conversation in class this week.