I had another baby or music.contrastandcompare.com is live

The software is beta, the simplicity is still all there, and there is still work to do.
However, I wanted to announce my success of http://www.music.contrastandcompare.com.
The goal was to have a site where I could host all my music (and my friends) easily and quickly.
The solution? Ruby on Rails, Dreamhost, and Amazon S3.
I basically had the whole site coded and up and running in about 6 or 7 hours. It would have been less if I hadn’t had to figure out some gem gotchyas on Dreamhost. Not to worry though, I’ll have an article covering that stuff in the near future.

Until then, check out the site… and if you don’t, at least look at this:

Lake Denman

The Car Goes Vrooooom!

Howdy Howdy Friends,

Today I am taking a few minutes to describe and explain a simple assignment that I completed with ruby.

The assignment reads as follows:

Using the following data, calculate and print out the average miles per gallon for each vehicle. Round the output to the nearest 10th gallon. Be sure to use variables with easily recognizable names.

The Data

Vehicle Miles Gallons
1970 VW Bug 286 9
1979 Firebird 412 40
1980 Subaru 361 18
1975 Cutlass 161 11

So now that we have our data, we should go ahead and model it with a class.

class Car
# Our car has some attributes, let's define them
attr_accessor :miles, :gallons, :model

# Lets setup our initializer. The initialize method is run before each new instance of the class Car
def initialize(model, miles, gallons)
  # here we set the instance attributes
  @model = model; @miles = miles; @gallons = gallons
end

# Now, let's calculate miles per gallon
def miles_per_gallon
  sprintf("%#1.1f", (miles.to_f / gallons.to_f))
end
end

# Now, let's instantiate our cars! VROOOOOM!
@volkswagon = Car.new("1970 VW Bug", 286, 9)
@firebird   = Car.new("1979 Firebird", 412, 40)
@subaru     = Car.new("1980 Subaru", 361, 18)
@cutlass    = Car.new("1975 Cutlass", 161, 11)

# We should but those cars into an array so we can iterate through each of them
cars = [@volkswagon, @firebird, @subaru, @cutlass]

# Begin our assigned output
puts “Kansas City Grand Prix”
puts “Miles/Per Gallon”
puts “”
cars.each do |car|
  puts “#{car.model} averaged #{car.miles_per_gallon} m/g”
end

Great! And when we run that, this is the output:

Kansas City Grand Prix
Miles/Per Gallon

1970 VW Bug averaged 31.8 m/g
1979 Firebird averaged 10.3 m/g
1980 Subaru averaged 20.1 m/g
1975 Cutlass averaged 14.6 m/g

This was an easy assignment, really. The only true black box method for me is the sprintf() or format() method.
I’ll try to explain what that method actually does.

# Say we wanted to format PI to show the decimals only to the hundreds place... I'll use format(). You can use sprintf(). They are the same
format("%#1.3f", Math::PI)

You can read all about the sprintf method here: http://www.ruby-doc.org/core/classes/Kernel.html#M001094

Have a better way of doing this? Tell me all about it! Leave a comment.

Adding Up Hours or The Road Less Traveled

Two roads diverged in a wood, and I—
I took the one less traveled by,
And that has made all the difference.

Robert Frost

I usually work around 40 hours a week, receiving my paychecks bi-monthly. Every two weeks I have to add up my hours and invoice them. I’d like to do this task as quickly as I can with the least amount of errors possible.

There are a couple of ways that I could go about solving this problem.
The first road that one may take might be to use the trusted calculator.
Another path one may choose would be to use google.com or Mac OS X spotlight.
Even more, one may choose to write a small script to add the hours.
Which way yields the fastest result? Which way yields the least amount of errors?

Let’s Have Some Fun!
Here are some made up hours:

8.13, 7.85, 8.00, 7.90, 8.30, 8.0, 7.5, 8.4, 8.0, 7.65

If I were the man who took the old fashion calculator route, it would take me about 35 seconds to add up these numbers. Usually if I use a calculator I like to check my answer once to make sure that it yields the same result twice. So, we could say that it would take a good 60 seconds.

So, 60 seconds isn’t bad. Hell, that’s only 1 minute of the day gone… not too much to sweat.

Let’s see how long it takes for us to type our numbers in the Google search.
I pasted my list of numbers into Google and inserted the plus symbol in between each number.
EX.)

8.13 + 7.85 + 8.00 + 7.90 + 8.30 + 8.0 + 7.50 + 8.4 + 8.0 + 7.65

That only took 23 seconds! That’s a nice increase from 60. You see, I trust that Google won’t make errors and I know that the risk of manually entered errors is much less than a manual calculator (especially since I copy and paste the numbers.)

For good measure let’s see how long Mac OS X spotlight will take. My guess is that it will be around 20-25 seconds. On second thought, let’s not use spotlight. It doesn’t seem that spotlight enjoys our method of copy and paste and insert plus symbols, so we’ll wave it goodbye!

Now, let’s try to write a few lines of ruby code to calculate our hours.

# We need to define an array of hours
hours = %w(8.13 7.85 8.00 7.90 8.30 8.0 7.50 8.4 8.0 7.65)

# Whoops! The elements in the hours array are saved as strings!
# They really should be floats... Let's fix that!
hours.map!{ |hour| hour.to_f }

# Now, we need to add all the hours together using the inject method
total_hours = hours.inject() {|result, element| result + element}

I timed this path at a blazing 5 SECONDS!
Sure, it took me a little longer to write a script, but I have it forever now.

I might not have proven much in this post, but it is important to try new things.
So, either dust off your old calculator, head on over to Google, or type up a little Ruby script. There’s lots of ways to solve the problem, but which way solves the problem the fastest with the least amount of errors? Discuss it in the comments.

The Clean Array#Map Method

So, there is at least one way to solve my problem with Ruby.

The problem is that I have a bunch of hex color codes and I want to append the number sign before each one. Well, I say a bunch… But, I’ll only use 5. So here is our slick array:

colors = ["000000", "000033", "000066", "000099", "0000CC"]

Now, here is one way that I could solve this problem:
This puts the newly formed elements inside of the new_colors array.
This, however, is not the cleanest way to solve the problem.

new_colors = Array.new
colors = ["000000", "000033", "000066", "000099", "0000CC"]
colors.each do |color|
  new_colors << "\##{color}"
end
puts new_colors #=> ["#000000", "#000033", "#000066", "#000099", "#0000CC"]

We can look deep inside the Array class for a method called “Map” AKA “Collect”.

/*
* call-seq:
* array.collect! {|item| block } -> array
* array.map! {|item| block } -> array
*
* Invokes the block once for each element of _self_, replacing the
* element with the value returned by _block_.
* See also Enumerable#collect.
*
* a = [ "a", "b", "c", "d" ]
* a.collect! {|x| x + “!” }
* a #=> [ "a!", "b!", "c!", "d!" ]
*/

Using this same method, we can do what we want in just ONE line.

colors = ["000000", "000033", "000066", "000099", "0000CC"]
colors.map! {|color| ‘#’+color} #=> ["#000000", "#000033", "#000066", "#000099", "#0000CC"]

This may seem trivial with a small number of hex codes, but when you have around, say, 216. This can be a great solution.

Do you have any good ideas to make this script better?
Add a little comment!

Downloading Videos From RubyPlus with Ruby (and unix)

When I discovered that I had an account at rubyplus.org and realized how many screencasts they had that were available for my viewing pleasure, I got excited… Real excited!

And then I noticed that I would have to click the download button for each and every one of the videos; I want the world, I want the whole world… 

I knew I could use Ruby to help me download every video with ease, so I made an ultra tiny script:

(1..69).each do |episode_number|
`wget http://ldenman:blindedyo@rubyplus.org/episodes/#{episode_number}/download`
end

There were 69 (meow) episodes created from RubyPlus, hence the (1..69).
Surely you know the range method:

(1..10).each {|num| print num} #=> 12345678910

A Range represents an interval—a set of values with a start and an end. Ranges may be constructed using the s..e and s…e literals, or with Range::new. Ranges constructed using .. run from the start to the end inclusively. Those created using … exclude the end value. When used as an iterator, ranges return each value in the sequence.

We are using our range as an iterator

so I specify the number I want to start with, episode 1 and I specify the number I want to end with 69 and then I join those two numbers together with.. (I could use to join the numbers together, but it would exclude the last number from the output.)

I then send the message each on our range. Now, each takes a block. A block is basically a chunk of code run between a do and an end keyword. so we have a block:

#Block with keywords
(1..5).each do |number|
 print number
end
#=>12345

#Block with brackets
(1..5).each {|number| print number}
#=>12345

That’s right, same answer… different syntax.

So, now we look at the code inside the block(line 2):

(1..69).each do |episode_number|
`wget http://ldenman:blindedyo@rubyplus.org/episodes/#{episode_number}/download`
end

For each number in our range, wget will be called with our specified url. And our episode_number will continue to increase until we have reached 69.
I guess I should say that you have to place any console code between these little `grave accents`

GNU Wget is a free software package for retrieving files using HTTP, HTTPS and FTP, the most widely-used Internet protocols. It is a non-interactive commandline tool, so it may easily be called from scripts, cron jobs, terminals without X-Windows support, etc.

Hey! Wget may be easily called from scripts!!! That’s What I Just Did Weeeeeeeee! And It Was Easy, Wasn’t It?!

Then, we finalize the script with our end keyword and then we run it in a directory we want it.

ruby download_all_files.rb

Whoomp There It Is!

Ruby

makes it easy to do stuff like this and it’s all fun and games too!

RailsCasts on my iPhone

Unless you aren’t in the know, Ryan Bates’ RailsCasts happens to be a really great series of short rails blurbs giving you good hints into anything from checking out your production log to refactoring your code to restful authentication and so on and on and on.

Last night I decided it would be a great night to fall asleep and sure enough, I couldn’t get to sleep. So I decided to think about ruby on rails. Some nights when I can’t fall asleep I think about that, among other things. Then, suddenly, I realized that my iPhone has the ability to stream MP4’s. And well, Ryan Bates already had it on the lockdown and decided to hook a brother up with railscasts in MP4. So I perk up on my pillow and go Railscasts.com. You should try it out!

Rspec: Which Matcher Should I Use?

I just installed RSpec for a project I’m working on. I may be doing things a little bit in reverse since I haven’t written much of any test code and my application is already over the halfway point… It’s a pretty huge project; The half-way point is like 10 miles long already. So now, I’ve got to catch my tests up to my code.

Anyways, I’m not so awesome at Rspec and am just getting a feel for how to do things. I’ve watched part of the Peepcodes, but the rspec ones really don’t hit a sweet spot with me for some reason. Major rails points go to Geoffrey Grosenbach… even though that song he plays during the topic change is annoying.I’ll move on.

After installing Err’s cheat gem, I wondered if there was a cheat for rspec. So i just ran the command:

cheat rspec

And not so much to my surprise, a whole heap of information came up.

Applying what I learned from the cheat sheet, I went ahead and generated an account spec controller. I was also very careful not overwrite my actual account controller by choosing “N” when terminal prompted me. I then went to the spec and decided I would test the methods that did not require authentication. So I picked the easiest one that I saw and the thing is, it stumped me for a few minutes… And then I prevailed.

The method looks like this:

def about_us
  @nav = 'about_us'
end

And my test looks like this:

it "should get about us" do
  get :about_us
end

Yeah, well that will obviously work because Ruby on Rails has been tested pretty thoroughly… But how do I test that the instance variable “@nav” is actually being set? Turns out there is a handy method that looks like this:

assigns[:nav]

After I figured that out, my spec looked like this:

it "should get about us" do
  get :about_us
  assigns[:nav]
end

I want more though! I want rspec to assert whether or not it is equal to the string I set in the controller action which is: “about_us”

The first method I tried was:

  assigns[:nav].should be(”about_us”)

I was sure that this would work, it made so much sense! But then, FAIL!!!
Why? Well, according to the rspec documentation, the method “be” returns true of false, not the object or the object value.

Given true, false, or nil, will pass if actual is true, false or nil (respectively). Given no args means the caller should satisfy an if condition (to be or not to be).

However, these could all be very good potentials:

  assigns[:nav].should_not be_nil   #Returns true because @nav is assigned
  assigns[:nav].should be_an_instance_of(String)  #Returns true because @nav evaluates to “about_us”, which is a string”
  assigns[:nav].should_not be_empty #Returns true because @nav has a length of eight characters!

So, in my search for peace with this problem I found that “be” was not going to “be” my solution.
I needed something different, something that acted like “be” but returned the object value. My next guess was “equal.”

  assigns[:nav].should equal(”about_us”)

To my dismay, this specification didn’t pass. It just waved it’s little middle finger right in my face. After consulting the documentation, it seems that the equal method really only passes if the expected object is the same as the one that it’s being matched again. IN MY FACE!

Passes if actual and expected are the same object (object identity).

So these could be valid:

  assigns[:nav].should equal(assigns[:nav])   #Passes because @nav is being matched against itself
  5.should equal(5)  #Passes because 5 is really 5 no matter what.
  @nav = assigns[:nav]; assigns[:nav].should equal(@nav); #Passes because @nav and assigns[:nav] both reference the same object!

And then, I saw it. The cute little method called “eql”. What was so different about “eql” than “equal”? It didn’t seem that there was a difference, that is, until I consulted THE DOCUMENTATION! This is what I wanted:

Passes if actual and expected are of equal value, but not necessarily the same object.

It seems that eql was the lucky charm I had been looking for all along. I went ahead and snapped in the code like so:

it "should get about us" do
  get :about_us
  assigns[:nav].should eql(”about_us”)
end

And to not so much my surprise, My First Test Passed!

Here is the stuff to remember:

equal: Matches Object to Object (@nav, @nav)
eql: Matches Object Value to Object (@nav,”about_us” )
be: Asserts truth or falsity of an obect (@nav, not nil)

Now I’m on to write more tests! Aren’t you supposed to take baby steps anyhow?

The Jing Project

The Jing Project is an interesting application that I stumbled upon the other day. I didn’t actually use the site stumble upon to find it, I actually just saw a group of pictures on Flickr that were watermarked: “Brought to you by the Jing Project.”

So, I didn’t think much of it at the time… I was just sort of annoyed at all the watermarked images. But then I actually went to the Jing Project site. After reading the three main features on the website, I decided to give it a whirl. To my surprise, when I opened the application a cute logo came up and then fancilly set itself up in the upper right corner of my screen. It resembles a small sun just ready to shine it’s goodness. However, if you don’t like the sun and think it’s too intrusive, you can add an icon to your menu bar instead. I like the menu bar, personally.

As soon as I opened the application I knew what to do. Just click the button and record an image or screencast. It’s dead easy; It’s Free. If you haven’t checked it out, do so. Just check out the site.