Saturday, May 24, 2014

A look at three different ways to implement QuickSort in ruby

I am teaching myself computer science concepts like Big Oh notation and different sorting algorithms. I found several ways of implementing quicksort that taught me some Ruby fun that I thought I'd share.

To quicksort an array, you pick one of the array elements to use as a pivot point. Then divide the array into two different arrays; the left array is very element less than the pivot and the right array is everything that is greater than the pivot.

Then recursively call quicksort on the left and right arrays until they are split into one element arrays. Join all the one element arrays into the final sorted array.

# Quick Sort
# Select element closest to middle (called pivot element)
# puts all elements <= pivot  to the left
# puts all elements > pivot to the right
# recursively call this method on the sublists

# solution one

def quick_sort(list)
   sl = list.clone
   return sl if sl.size <= 1
   pivot = sl.pop                                                  # last element of array
   left, right = sl.partition {|e| e < pivot}               # partion divides the array into two arrays
                                                                          # left = ( e < pivot) and right is ( e > pivot)
   quick_sort(left) + [pivot] + quick_sort(right)    # recursively divide and sort left and right arrays
end


# solution two
def qsort(list)
 return [] if list.size == 0
 # splat operator  splits list into x & xs
 # x is the pivot and first element in arrray, xs is the rest of the list
 x, *xs = list
 less, more = xs.partition{|y| y < x}
 qsort(less) + [x] + qsort(more)
end

#solution three
def quicksort(list)
   return if not list || list == []
    x, *xs = list
    # uses select to create array with elements where condition is true
    # recursively keeps checking
    quicksort(xs.select { |i| i <  x }) + [x] + quicksort(xs.select { |i| i >= x })
 end


list = [9,0,2,45,32,6,7,20,19,5]
p list
p quick_sort(list)
p qsort(list)
p quicksort(list)

Thursday, May 15, 2014

An RVM cheat sheet for newbies



RVM (aka Ruby Version Manager) is a very useful tool. It allows you to install and manage several different versions and implementations of Ruby on one computer, including the ability to manage different sets of RubyGems one each.
There is lots of good advice on how to use RVM (Ruby Version Manager) scattered all over the interwebs. I put together this cheat sheet as a learning aid for myself. I hope you find it helpful (and please ignore the wonky formatting).

Installing RVM (on a Mac)
# install development version
\curl -sSL https://get.rvm.io | bash  
# stable RVM with latest ruby
\curl -sSL https://get.rvm.io | bash -s stable --ruby
# stable RVM with latest rails
\curl -sSL https://get.rvm.io | bash -s stable --rails

Setting a new gemset for a project

1) Install ruby in the project directory

$ rvm install 2.1.2
# list the version of ruby in use, verify the version installed
$ ruby -v   

2) Create a gemset with the a particular version of ruby

$ rvm list
# generic syntax for creating a gemset                                  
$ rvm use ruby_version@project_name --create

3) Real life example:

$ rvm gemset list   # to verify things went well)
$ gem install rails # you install rails into that gemset              
$ rails -v          # to verify that rails installation went well
# ‘rvm use’ sets the gemset in use       

Dealing with incompatible versions of Ruby and Rails

Oh Noes ... time to reverse the process and de-install rails because it’s not compatible with the latest version of ruby at the time of this posting.

1) Uninstall rails in the project directory

$ gem uninstall rails -v 4.1.1

$ gem uninstall railties -v 4.1.1 # need to uninstall also

2) Uninstall ruby versions that are not compatible

$ rvm remove 2.1.2p95

3) Delete the gemset

$ rvm gemset delete super_tictactoe


Steps to update to a different version of Ruby and Rails

In this example we will be installing Ruby 2.1.1 and Rails 4.1.0.

1. Check for a gemset and delete if needed

$ rvm gemset list
$ rvm gemset delete <gemset name>

2. install desired version of ruby

$ rvm install 2.1.1

3. Create a sticky gemset


# check for hidden files
$ ls -lpa   
# delete hidden RMV files if they exist
$ rm .ruby*
$ rvm use ruby-2.0.0-p353@superTTT --create --ruby-version
$ gem install rails


The --ruby-version argument creates two files, .ruby-version and .ruby-gemset, that   set RVM   every time we cd to the project directory. Without these two hidden files you need to enter the following command every time you work on your project if you close the console.

4. Install specific version of rails

$ gem install rails -v 4.1.0

5. Update the project Gemfile

$ gem 'rails', '4.1.0'
$ ruby "2.1.1"

6. Run bundle update to fix conflicts

$ bundle update

7. Read the output from 'bundle update' and update your .gemfile accordingly

∴ bundle update
Fetching gem metadata from https://rubygems.org/..........
Fetching additional metadata from https://rubygems.org/..
Resolving dependencies...
Installing rake 10.3.1                   # update entry in gemfile
............
Installing coffee-script 2.2.0        # update entry in gemfle
Using railties 4.1.0 (was 4.0.2)    # using existing gem, no update needed
Installing coffee-rails 4.0.1         # update entry in gemfile
Your bundle is updated!
Some other useful info

To install older versions of Ruby

$ rvm list known  
# lists all  rubies that can still be installed
# may need CC=/usr/bin/gcc to get the binary to compile
$ rvm install 1.8.7  # pick version you want to install     

Upgrading RVM

$ rvm get stable

Data for troubleshooting:

$ rvm info  # verbose listing of the ruby dev environment
$ gem list -dl   # lists all the gems installed

Wednesday, January 15, 2014

Ready to deploy my Rails App but there are last minute database changes - how to make everything work.

Sometimes things happen. A last minute change to the underlying database was made a week before I was ready to deploy my Ruby on Rails app. We are talking about terrabytes of data in the database and the change was made for speedy data transformation. This change was neccessary and needed. 

I thought to document this process for future reference. 

Make sure your code is checked into a source code control:

I use git so I would ran:
    git add .
   git commit -m "Snapshot before changing database schema"
   git push origin master

Dropping the current database & loading in the new development database dump:

I am using a MySQL client called Sequel Pro.  It's easy to "delete the database", "add" the database back (with the same database name so I don't have to change my database.yml file).  Then "import" the database dump file. 

     In MySQL admin tool:

        mysql> drop database [database name];
    mysql> create database [databasename];

   Then restore the database from a database dump file:

    mysql -u root -p[root_pwd] [database name] < dumpfilename.sql 

Create a new schema.rb file in rails:
  
    rake db:schema:dump
    (you may need to run: bundle exec rake db:schema:dump)



Add, Delete or Update models:

My app reads from the database so I only needed to add new models for the new tables in the database.  For example, if we had a new histories table I created a new file in the models directory:

      projectfolder/app/models/history.rb

Edit the history.rb file and add:

    class History < ActiveRecord::Bas
    end 

The table name is plural and the model name is singular (both are lowercase titles). The object name is capitalized and singular.

Now to work on the controller  to extract data from these new tables...

Monday, December 2, 2013

What is the difference between :name and name: ?

To be honest, I was always confused by name: and :name in Ruby. I never fully understood the differences until I read about it in the Hartl Tutorial.

The Michael Hartl Ruby on Rails Tutorial is an excellent way to learn Ruby on Rails. The tutorial has been updated to Ruby 2.0 and Rails 4.0. I've been working through this tutorial to get updated on the new features and differences in Rails 4.0.

There are several ways to define elements in a hash using a literal representation of key value pairs. We are going to define a hash called pairings that will pair a coffee with a dessert that goes well with this coffee. We will use 3 different ways to assign the key value pairs.

1. Using a string and a hashrocket. The "=>" is called the hashrocket because doesn't it look like one?

  pairings = { "coffee" => "Columbian", "dessert" => "Flan" }

  Use the string as a key in pairings["coffee"] to access the value "Columbian"

2. Using a symbol for the key and a hashrocket. In the previous example the key was the string "coffee". We will replace this string with the symbol :coffee. A symbol is a string without the extra baggage. Ruby will create an almost unlimited number of string instances for all your hash keys, but will only keep one copy of a symbol in memory at a time.

  pairings = { :coffee => "Columbian", :dessert => "Flan" }

  Use the symbol as the key in pairings[:coffee] to access the value "Columbian"

3. "Good Guy" Ruby let's us replace the ":symbol =>" with just 'symbol:'. I kinda miss the hashrocket but I don't miss typing  all those extra characters.

  pairings = { coffee: "Columbian", dessert: "Flan"}

  Use the symbol as the key in pairings[:coffee] to access the value "Columbian"


Easy peasy... the name: syntax simplifies hash construction.
TL;DR Use coffee: to replace ":coffee => " or " 'coffee' => " when creating key value pairs for hashes.

Friday, July 12, 2013

A few weeks in ....


I wrote this 5 weeks ago but was too busy to post. As you can read, we are covering a lot of material in a very short period of time. They really put the I in WDI... it is an intense, immersive experience. Totally worth it.

By the end of the first week of WDI  I wrote a program that accessed three different Ruby gems to display (1) daily stock quotes, (2) random images from the web and (3) movie data from IMDB in a web browser.   I was over the moon the first time I pulled stock quotes from the web thru a Ruby gem. I had no idea at the beginning of the week I'd be capable of this kind of programming after 4 days in the classroom.

The pre-work for the class was my only exposure to web development and Ruby.  (The pre-work was comprehensive, a lot of work and absolutely necessary)

This class is continuing to move rapidly.  On Monday morning we reviewed javasript and jQuery. In the afternoon we wrote an "ATM" web app with checking and savings withdrawal  (including overdraft protection) and deposits. We built this using javascript, jQuery, html and CSS. Tuesday we covered Twitter Bootstrap. I think the plan is to cover databases this week
Yesterday we were invited to the project presentations of the WDI class that is 9 weeks ahead of us. Their projects were amazing. You can see an example of a class project at http://cssstache.herokuapp.com/  (an app to share CSS snippets). It is inspiring to see what we have ahead of us

Sunday, July 7, 2013

Admissions Process - Getting into a developers bootcamp

From Getting accepted to getting ready to learn 




web school

Submitting applications to the right academy

Finding the right academy to apply to takes a bit of research. I was lucky that there are some great resources on the web. Michelle Glauser has been maintaining a very comprehensive list, with special interest in those that focus on women.

I used Michelle's excellent list to develop my own list of code bootcamps. I looked at the following factors:
  • location (needed to commute without needing a car)
  • timing (as soon as possible)
  • curriculum (comprehensive web development)
  • percentage of students that get hired after camp (> 90%?)
  • payment options (flexible)
  • length (longer than 9 weeks)
So I applied to 4 different camps. I interviewed with 3 (withdrew from the 6th because I accepted a position before the interview with their org was even scheduled). The interviews focused on whether I had the drive and the chops to make it through the process. I ended up enrolling in GeneralAssembly's WDI .. Web Development Intensive. More on that next time. 

Thursday, May 2, 2013

codeacademy.com

codeacademy.com
Note: The codeacademy.com team has no idea that I am blogging about them. I was not asked or paid to write about them. This only reflects  my experience and I am thankful this resource is available.

About a year ago, one of my colleagues told me about a intensive coding school that he was going to attend. He had a great idea for a startup and wanted to build the prototype.

I remember thinking to myself, is that even possible? How can you learn enough coding to be competent in such a short time? Sounds crazy, I thought.  But a seed had been planted.

About that time I was introduced to codeacademy.com. I wanted to leverage my python learnings at work and I was offered a project.  The slight obstacle was the application was to be written in javascript,  a language I did't know.  It was recommended to use codeacademy.com to come up to speed on javascript and I gave it try.

The online training experience was so different from the traditional learning model. No sitting in a lecture and then going off and trying to implement what you learned. You code and you code right away.

First you are  presented a completed project. Run the code, look at how it works. Then the program is deconstructed and rebuilt concept by concept until the project is recreated. You build the application step by step.  With each step you are practicing how to code and learning a concept at the same time.

I was never left a lesson feeling confused and uneasy.  If I needed help I could post a question to the forum or look up information in the glossary. I could also scroll back to previous lessons to review.  I was enjoying learning programming again. It was fun.

The work project never got off the ground but it was worth it to learn about online resources like codeacademy.com.  I would rely heavily on codeacademy.com later.

Fast forward 9 months and I read this blog post  by Michelle Glauser on resources for learning to code. She posted a fantastic spreadsheet listing quite a few coding bootcamps.  I'll talk about the admissions process in the next post.