Ruby to Classes: Open up, we’re coming in!
June 12, 2007
Ruby has open classes. “Who cares?” you say. You should. Yes you! Open classes really simplify a lot of programming problems when you can learn to use them correctly. First and foremost, what does it mean to have open classes? Well, this means that you, the programmer, can crack open ANY class and add methods to your heart’s desire! And nothing is off limits. This means I can break into the Integer class, add a helpful method for my program, and sneak out again without anyone being the wiser.
So how would one use the the fiendishly clever practice of open classes in every day coding? Here’s an example of a problem I ran into while working on project euler problems:
I often found that I needed to know the number of digits in an Integer for solving these problems. Let’s say I want to get the sum of the number of digits in all the numbers 1..100. Here’s the old way:
Now this is all fine and dandy and the code works great. However, there is a logical conundrum here. Why is num_digits just hanging out there by itself? We know that this method will always be called on Integers and, therefore, it makes much more sense to add a new instance method to the Integer class. Ruby open classes to the rescue!
Super fabulous open classes way!
Ahh, I feel so much better, don’t you? The only subtlety here is that we’re using self inside our num_digits method. This simply references the instance of the integer we are currently dealing with. So remember, next time you find yourself writing a method that would be better suited as an instance method of a class, break on in there! Ruby classes aren’t shy.
Programming as a hobby
April 27, 2007
I enjoy programming quite a bit, but seeing as I currently work in consulting, I don’t always get to program at work. However, it’s important to me to stay sharp with these skills, and this means programming as a hobby.
But how the heck do you program as a hobby? Unless you have a specific project you want to work on or a specific problem you’re trying to tackle, programming doesn’t have much of a use. As I see it, you’ve got 2 options: think of a project you want to work on or check out the sites I’m going to tell you about.
The sites I’m talking about are Codegolf and RubyQuiz. Both sites are great and both have contributed to my learning ruby over the past 8 or so months. Each site takes a slight different approach.
Codegolf is more of a competition. As the name references, the goal here is the solve a given programming problem with the absolute least amount of characters possible. This leads to crazy, hard to read, but interesting solutions. However, there’s a catch here: you can not view other’s solutions. You can discuss them on the forums, but as of right now all submissions are closed. On the up side, this does mean all challenges are always open. Forcing yourself to be concise leads to learning a lot about a language very quickly, as well. You can submit solutions in Php, Ruby, Python and Perl.
Rubyquiz, on the other hand, is what I would think of as a collaborative learning community. Each and every Friday a new “quiz” is posted to the website as well as the Ruby mailing list. Everyone has 48 hours to come up with a solution (this is a no spoiler period, don’t spoil it!) and then solutions are posted on the ruby mailing list. The following Thursday, the site’s author writes a summary of the solutions and discusses the best approaches. Best of all, the solutions are available for downloading. This site has exponentially improved my code.
Hope you enjoy these two sites, and happy coding!
Intelligent code made easy
April 24, 2007
I find the topics of Artificial Intelligence and Machine Learning extremely intriguing. In fact, one of the reasons I decided to study Computer Science was my perception of these concepts. I viewed them as extremely complex and equally difficult to implement.
Well, this isn’t always the case. In fact, I’ll show you an easy way to add some AI to your applications using an example. Let’s look at a snipet of code from my rubyquiz submission this week. Now, please, don’t think that I have delusions of grandeur and believe this to be an actual example of true AI, but think of this as barely scratching the surface to simply introduce how to think about adding some type of intelligent behavior to your application.
Anyway, this week’s quiz focused on getting a bit of Morse code from the user and then presenting all the possible translations of the code. I decided to add a nifty little feature that would make a “best guess” at which of the many possible translations was the true intent of the sender. How did I do it? Simply put: word frequency.
Sounds scary, but it’s not. My program read through a text document of a Sherlock Holmes novel, counted the number of times each word appeared and then stored these word -> frequency pairs in a hash. Then, when presenting my possible translations to the user, I simply showed the words with the highest occurrence in the Holmes novel first.
This clever (and simple, I don’t flatter myself) trick gives my program a bit of intelligence. In fact, this is a very simple example of a Bayesian filter (check wikipedia for more info). I’ll post the “intelligent” code snipet below. And just think; if I can do something like this, so can you. And probably something way cooler.
The power of dynamic languages
April 11, 2007
From time to time, people talk about how dynamic languages aren’t suitable for “real” problems as they are quite a bit slower than static, compiled languages. However, I believe that the combination of dynamic languages’ expressiveness and speed more than make up for the lack of pure speed when compare to static languages. And guess what? Dynamic languages aren’t as slow as you think.
I ran across a perfect example today while reading the ruby mailing list. This post describes the implementation of a spelling correcter (much like the one wordpress is using now as a type this blog). Essentially, this application is given a word and then attempts to verify the correctness of it’s spelling. If the word is spelled incorrectly, it gives back suggestions for the word the user was trying to type. This type of technology is used by Google, among others. This problem seems to be quite daunting and, if one would attempt to solve it, it seems like the use of a static language for pure speed would be needed here. The truth is that this is not the case. Some folks who are much more clever than I am were able to write a 21 line Python script and a similarly sized Ruby script to accomplish this task. And they are fast (the Python script was able to process 10 lines per second, and the darn thing is not optimized at all).
Reading these solutions, I was struck with how completely expressive these languages truly are. Take a look at the post and I’m sure you’ll see what I mean. Reading solutions like this – programmed by obviously brilliant people in these two languages – lead me to believe that dynamic OO languages are the wave of the future.
Understand the program below…
March 30, 2007
…and you’ll be better than 99% of working programmers. At least, that’s what a recent digg article stated and then linked to this article. While I don’t really believe the numbers, I do believe that there are quite few “programmers” out there that do nothing but copy and paste code. But you and I won’t be one of those. We’ll walk through how to create this very simple (but maybe not for most?) program in Ruby. Let’s outline what it needs to accomplish:
This program, called FizzBuzz, needs to do the following for the numbers between 1 and 100: if the number is divisible by 5 and 3, print FizzBuzz. If the number is divisible by 5 only, print Fizz. If the number is divisible by 3 only, print Buzz. Otherwise, print the number itself. This reminds me of a drink…er…number game I used to play in college. Ok, so the hardest thing about writing this program is just understanding how the modulus operator works. Most languages have a mod command and in Ruby it happens to be %. The statement “x % y” would divide x by y and then return the remainder. So, to determine if a number is divisible by x, we check that when we mod it with x, the result is 0 (thus, no remainder). With this small piece of knowledge we can write the FizzBuzz program and break into the top 1% of programmers world-wide:
And that’s all there is to it. Ask any questions, otherwise enjoy and welcome to the top 1%.
Coming from a Java background, I’ve found arrays to be very “rigid”. And by rigid I mean they sort of suck. However, Ruby makes arrays flexible and a blast to work with. Let’s show by example rather than have me ranting about it. First, we assume we have an array with 100 random integers between 0 and 99. I would show you how to do this but typing the append symbol breaks wordpress (grr).
1. Summing elements: This is a fairly common task. We’ll use Ruby’s inject method to sum all the items in the array and then print out the sum:
puts my_array.inject(0){|sum,item| sum + item}
2. Double every item: This is a class of problem where we want to preform an operation on every element of the array. Again, this is fairly simple using Ruby’s map method. Think of performing a “mapping” from the first array to the second based on the function in the block. Keep in mind, this will return a new array and will NOT effect the original array. If we want to do a destructive map (change the initial array) we would use map!. This is a common convention in Ruby:
my_array.map{|item| item*2 }
3. Finding all items that meet your criteria: If you want to collect all the values in the array that meet some criteria, we can do this using the (duh) find_all method. Again, this will return an array. The code below finds all items that are multiple’s of three :
my_array.find_all{|item| item % 3 == 0 }
4. Combine techniques: Let’s now say we want to find the sume of all elements in our array that are multiples of 3. Ruby to the rescue! This is very simple because we can chain methods together gracefully in Ruby. Check it out:
my_array.find_all{|item| item % 3 == 0 }.inject(0){|sum,item| sum + item }
5. Sorting: We can sort items in an array quite easily. Below, I will show the standard sort and then a sort based on the negative value of the number. Both are so simple, my head just exploded:
my_array.sort
my_array.sort_by{|item| item*-1}
Bonus!: As a bonus for all of you lovely readers, I will show you how to filter an array of strings based on a pattern. Let’s say you have huge array of strings and you want to collect any string that looks like this: 555-555-5555. Assume that the 5’s could be any digit (we are looking for phone numbers). First, we create a regular expression that expresses this phone number jazz: /\d{3}-\d{3}-\d{4}/ (I’m not going into regular expressions here, but you can google them if you want to know more). Now, we simply use the find_all method discussed earlier combined with Ruby’s slick =~ operator. This will tell us if there is our string matches the regular expression. So, without further ado, here is how you would filter an array to find strings that contain phone numbers:
my_array.find_all{|item| item =~ /\d{3}-\d{3}-\d{4}/ }
Stay tuned, more Ruby goodness to come!
Don’t be shy, check out everything you can do with Ruby’s Array
CSV Manipulation w/ Ruby
March 13, 2007
Lately, I’ve been trying to follow why’s advice by using Ruby at work whenever possible. I love Ruby because it’s very friendly to those who have little (or no) programming background. However, some people feel they have no place to use programming in their jobs. Well, let’s look at the example of processing a csv file (something most of use have done). Suppose we have a file with categories and totals. Assume we want to find unique categories and the sum of the totals for each category.
1. Let’s first install the FasterCSV gem. It’s easier to use and faster (duh) than Ruby’s standard csv library. Install it by doing the following from the command line: gem install fastercsv
2. Ok, so we now have fastercsv installed. Assume our file is called “orig.csv”. Here’s a script that will do what we described above. Take a look at the code and I’ll describe it in detail below.
Description: In a nutshell, we include fastercsv in our code, read through our file and and stick the category-total pairs into a hash and then write out the totals to a new file. The only tricky part is line 11, where we check to see if an entry for the current category exists. If not, we create one with a total of 0, otherwise we do nothing. If you have specific questions, please post a comment and I’ll respond.
From Zero to Rails in 10 Steps (Windows)
March 12, 2007
Ok, so I know that there are other “getting started with rails” tutorials out there, but I thought I’d take a stab at it. I’m doing this from the “teach a 2 year old” point of view, so I’ll try to walk you through everything. And I’ll try to do it in 10 steps. Now, if you don’t know what Rails is, check out the rails website. Also, there is a solution out there called InstantRails for windows that will allow you to install rails from a single application. However, following the steps below will give you much greater flexibility in the future and you might actually learn something along the way! The goal is to end up with a rails development environment on your Windows box including ruby, rails, mysql (your database) and mogrel (your development web server). Don’t worry if you don’t know what these things are, just follow along. Here we go!
1. Download and install the ruby one-click installer.
2. Go to Start -> Run, type “cmd”. At the command line, type the following: gem update – -system (no space between the dashes, just for clarity’s sake).
3. Still at the command line, type: gem install rails – -include-dependencies (again, no spaces)
4. Again, at the command line type: gem install mongrel – -include-dependencies (do I have to say it again? no spaces)
5. Download and install MySql Server 5.0. Pick any mirror. Uncheck the option for changing the root password during the install. Make sure you check the option to run the service when you finish the installation.
6. Download and install HeidiSQL. This will let you view your MySQL database through a graphical user interface.
7. Create a database for our application. Start HeidiSQL, create a new connection, accept ALL the defaults (no password or anything else) and click connect. Create a new schema (right click on the left hand pane) named: myrailsapp_development. Exit the program.
8. Create your rails application. Go to Start -> Run. Type “cmd” and hit enter. At the command line, type: rails myrailsapp. Now, type: cd myrailsapp. You now have a new rails app and you are inside the directory!
9. Still at the command line type: ruby script/server. Your mongrel server is running!
10. Open up your internet browser and into the address bar type: http://localhost:3000. You’re rolling with rails! Yahoo!
Hope that all worked out for you! For more information, check out the rails website. There are also a ton of getting started tutorials out there and the rails site should point you to a lot of them. Good luck, and enjoy rails!
Pandora experiment
March 9, 2007
I would definitely consider myself into music. I also like a really bizarre range of musical genres including electronic, indy rock, 80’s rock, classic rock, ambient, etc. The most important thing to keep in mind is that I enjoy strange and weird music and that I am also weird myself.
Ok, onto the show. I’ve been having fun with Pandora for a while now. Pandora is this internet radio project that is driven by something called the “Music Genome Project”. Sounds scary. Basically it is a massive project to classify thousands of songs by hundreds of attributes. This allows Pandora to take a sampling of your musical tastes and then suggest new ideas for your listening pleasure. Well, as my musical preferences are sufficiently strange, I thought I’d give it a test run. I will be attempting to create a music station with “Funky Disco House” songs. I’ll give it the artists Daft Punk, Cassius and Mylo as starting points. Let’s see what the first 5 songs are:
1. Daft Punk – Musique: Ok, so they play a song by one of your artists chosen initially to give you a taste of the station. Needless to say, I like this song. Quick side note: Daft Punk is the best musical group of all time. Moving on.
2. Westbam – Hanging with the Machineheads: Pandora tells me it played this song because of disco influences and prevalent use of “groove”. I never even told Pandora anything about disco and it picked that up after one song. I’m slightly impressed. The song is decent, probably a 6/10, but we’re on the right track. I give it a “thumbs up” on the pandora interface.
3. Olympic Flame – DJ Tiesto: Ok, Tiesto is fine, but not what I’m looking for here. He is decidedly not “funky”. Although Tiesto is fine, I want to taylor this radio station correctly, so I give it a thumbs down.
4. Daft Punk – Something About Us – One of my favorite Daft Punk songs of all time. Good work Pandora. 10/10.
5. Room 5 – I Need U: I’ve never heard of this band or song. Although initially put off by the stupid use of the letter “U” in the title, I began to listen. It is definitely Funky Disco House. It’s quite good. I’m very impressed. I’d say 9/10.
Ok, so that’s the first 5. I must say, Pandora picked up on my strange station theme quite quickly and introduced me to a couple new, cool songs. I will be listening to this at work every day.
Read Up on Programming
March 6, 2007
I recently picked up Dreaming in Code, a pretty interesting book that follows the development of a software application over the course of 3 years. It focuses on why software is difficult to scope, build and deliver on time. Pretty neat to read as an avid programmer, I found myself thinking “I did that, but I thought it was just because I’m dumb.” However, I feel slightly better considering the fact that most of the developers followed here are icons in their respective niches.
I think about programming quite a bit and I have always felt that it would be really strange/awkard to manage the development of an application. Software seems sporadic and free-flowing while management…does not. Well, apparently I didn’t know the half of it. There’s lots in here about the mindset of developers, the open source software movement and “changing the world” with software. If you’re at all into technology, give it a browse the next time you’re in the bookstore.
PS – Is it sad that I take sick pleasure in the fact that this “difficult” project was implemented in Python?