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!