Ruby Algorithm Interview Challenge

I recently had a Junior Ruby Developer interview where I had to complete a coding challenge live. I didn’t finish in time and didn’t get the position, but I wanted to complete it anyway.

The Challenge:

Convert numbers into their word equivalent.

ie. 1 = “one”, 23 = “twenty three”, 1234 = “one thousand two hundred thirty four”


My Solution:

def convert_num(num)
	ones = {
		'1' => "one",
		'2' => "two",
		'3' => "three",
		'4' => "four", 
		'5' => "five",
		'6' => "six",
		'7' => "seven",
		'8' => "eight",
		'9' => "nine"
	}

	teens = {
		'11' => "eleven",
		'12' => "twelve",
		'13' => "thirteen",
		'14' => "fourteen",
		'15' => "fifteen",
		'16' => "sixteen",
		'17' => "seventeen",
		'18' => "eighteen",
		'19' => "nineteen"
	}

	tens = {
		'10' => "ten",
		'20' => "twenty",
		'30' => "thirty",
		'40' => "forty",
		'50' => "fifty",
		'60' => "sixty",
		'70' => "seventy",
		'80' => "eighty",
		'90' => 'ninety'
	}

	hundreds = {
		'100' => "one hundred",
		'1000' => "one thousand"
	}

big_num = []
#first check ones place
	string_num = num.to_s
	if ones.include?(string_num)
		ones[string_num]
#check teens
	elsif teens.include?(string_num)
		teens[string_num]
#check tens
	elsif tens.include?(string_num)
		tens[string_num]
#check hundreds
	elsif hundreds.include?(string_num)
		hundreds[string_num]
#split the number up 
	else
		num_array = string_num.split('')
		if num_array.length == 4
			big_num << ones[num_array[0]] + " thousand"
			big_num << ones[num_array[1]] + " hundred"
			big_num << tens[num_array[2] + '0']
			big_num << ones[num_array[3]]
		elsif num_array.length == 3
			big_num << ones[num_array[0]] + " hundred"
			big_num << tens[num_array[1] + '0']
			big_num << ones[num_array[2]]
		else
			big_num << tens[num_array[0] + '0']
			big_num << ones[num_array[1]]
		end
		big_num.join(" ")
	end
	
end

How I approached this challenge (my thinking process):
I was told that the highest number passed into this algorithm would be 9,999

  1. First I knew I needed to create a list of all the numbers and their written equivalent. Since the keys would not match an array index sequence, I decided to store the information in a hash.
  2. The ones place is its own hash because I knew I would need to use this hash again when dealing with hundreds and thousands.
  3. I placed the teens in their own hash because there’s no pattern to the written form and would only be used if one if the numbers in the teens hash appeared.
  4. Same goes for the tens. Twenty is different from two and thirty is different from three. So they get their own hash as well.
  5. If the number being passed matches exactly with any of the keys in these hashes, then I just need to use that key to grab the value and output it.
  6. If the number being passed does NOT match with any of the keys in my hashes, then I want to split the number up and search through the array created.
  7. If the length of the array is 4 (has 4 digits), then I know I need to add the word “thousand” after the first index (0), and “hundred” after the second index (1). I push these in order into a new array called big_num.
  8. The tens place is tricky as the numbers are all single digits. I add a ‘0’ to the end of the digit and search my tens hash for the matching key.
  9. I follow this same pattern for numbers that have a length of 3 and numbers with a length of 2.
  10. Then I join the elements in big_num together so that they form one string.

The following tests and outputs:

p convert_num(3)
  => "three"
p convert_num(15)
  => "fifteen"
p convert_num(90)
  => "ninety"
p convert_num(45)
  => "forty five"
p convert_num(202)
  => "two hundred two"
p convert_num(100)
  => "one hundred"
p convert_num(1200)
  => "one thousand two hundred"
p convert_num(9999)
  => "nine thousand nine hundred ninety nine"

Pretty sure that there can be some more refactoring, but will have to keep working through the logic to find a way to simplify it.

Advertisements

Making a Ruby Gem

I made my very first Ruby gem today! Check it out here!

You can make a Ruby gem! Make an account with Rubygems.org and then follow the following steps. These steps assume you already have some code that works and you want to package it as a gem. It’s always good to keep copies of your code on Github or Bitbucket

  1. First check if your gem name has been taken by doing a search on Rubygems.org.
  2. Next, run this in your Terminal:
    $ bundle gem <gem-name>

    This will create the files you need in your gem package.

  3. Open up the gem-name.gemspec file and replace all the items that start with ‘TODO’ with your own information. Also replace the push host link to rubygems.org. Mine was located on line 19:
    spec.metadata['allowed_push_host'] = "https://rubygems.org"
  4. Go into your lib/gem-name/version.rb file and add your version number in this format: MAJOR.MINOR.PATCH
    MAJOR: for big changes to your gem
    MINOR: for small additions to your gem
    PATCH: bug fixes and such
    Unnamed QQ Screenshot20160106224046
  5. Create a new file inside your lib/gem-name/ folder named gem-name.rb and add your classes and methods here.
  6. Inside a different file located at lib/gem-name.rb you can make any module specifications. In this file, the first line should be
    require 'gem-name/gem-name' to pull in the file located at lib/gem-name/gem-name.rb
  7. Add, commit, and push to Git
  8. $ rake install

    This will build and install locally

    * $ rake build

    will build the gem locally

  9. $rake release

    build and push to Rugygems.org

  10. $ gem bump --to minor
    $ gem bump --to major
    $ gem bump --to 1.1.1

To add another owner to the gem, type this in your Terminal

$ gem owner gem-name --add <owner@email.com>

 

Starting up SASS

SASS is a Ruby gem

I am using Windows 10 to play with SASS:

1. Install SASS from your Terminal:
$ gem install sass

2. Create a SASS file:
$ touch style.css.scss

3. Run this to compile your SASS into CSS file:
$ sass input.scss output.css

4. Watch changes to this file’s directory (optional):
$ sass –watch app/sass:public/stylesheets

5. Watch changes to the stylesheet files:
$ sass –watch input.scss:output.css

This is really great to keep running in a separate terminal so that your stylesheet.css file gets updated with your .scss changes automatically.

Some helpful links:
@mixins: http://www.sitepoint.com/sass-mixins-kickstart-project/

@media queries: http://thesassway.com/intermediate/responsive-web-design-in-sass-using-media-queries-in-sass-32

Main site: http://sass-lang.com/

Deploy Sinatra app on Heroku

This is for everyone who has finished their Sinatra application and wants to deploy it on Heroku.

FYI::You will need to have all your files uploaded on your Github repo to be able to deploy on Heroku. The following steps are assuming you have deployed to Heroku before. If you haven’t, follow this excellent tutorial.

Example app name: Hangman
app file: game/hangman.rb

Steps:

1. Create a Gemfile in your app directory that has the following:
The file path should look something like this: game/Gemfile where ‘game’ is the name of your app directory

source 'https://rubygems.org'
gem 'sinatra'
gem 'sinatra-contrib'

Be sure it list ALL gems you use in this Gemfile otherwise Heroku will give you an H10 – App Crashed error.

2. Create a config.ru file in your app directory:
The file path should look something like this: game/config.ru

require './hangman'
run Sinatra::Application

3. In your app file (ie. hangman.rb), require Sinatra:

require 'sinatra'

If you don’t have any content in the file, create a simple Hello World by adding the following below your require statement:

get '/' do
  "Hello World!"
end

4. Run Bundle Update
In your terminal (or Command Prompt):

$ bundle update

This will create and update your Gemfile.lock.
You can also manually create a Gemfile.lock and run bundle update after.

5. Commit your new files to Github and push to Heroku!

$ git add config.ru Gemfile Gemfile.lock
$ git commit -m "adding Heroku deployment files"
$ git push origin master
$ git push heroku master

Ruby | Conditionals and Flow Control

Answering Odin Project questions on Ruby Conditionals and Flow Control:

    • What is a “boolean”?
      A boolean is a binary variable that holds two possible values “true” and “false”
    • What are “truthy” values?
      Objects that are considered true in a boolean are truthy, false are considered falsey. What’s true and false varies across different languages.
    • Are nil, 0, "0", "", 1, [], {} and -1 considered true or false?
      nil -> false, 0->true, “0”->true, “”->true, 1->true, []->true, {}->true, -1->true
    • When do you use elsif?
      When you have more than two parts in an if statement.
    • When do you use unless?
      When you want to test for ‘false’.
    • What does <=> do?
      This ‘spaceship’ operator returns 1, 0, or -1 instead of 1, 0
      For example: a <=> b
      If a < b, return -1.
      If a = b, return 0.
      If a > b, return 1.2 <=> 5, returns -1 because 2 is less than 5.
    • Why might you define your own <=> method?
      When you are sorting an array. You can use it for both integers and strings. Strings are sorted according to the ASCII order and so is case sensitive. Uppercase letters come before lowercase letters.
    • What do || and && and ! do?
      || = logical ‘or’
      Evaluates the first operand. If true, returns true. Otherwise, returns the value of the second operand.

      && = logical ‘and’
      Evaluates the first operand. If false, returns false. Otherwise, returns the value of the second operand

      ! = ‘not’
      If the expression is true, returns false. If the expression is false, returns true.

    • What is returned by puts("woah") || true?
      true
    • What is ||=?
      a ||= b would mean if ‘a’ is false, then set it equal to ‘b’. Otherwise, leave it the same value before running the conditional.
    • What is the ternary operator?
      ? :
      boolean_expression ? true_expression : false_expression
      Returns the true_expression if boolean_expression is true. Otherwise, returns false_expression.
    • When should you use a case statement?
      You should use a case statement when you want to match a value to a manageable number of conditions.

||= explanation: http://ruby.zigzo.com/2013/02/01/wat-double-pipes-equals-in-ruby/
Spaceship Operator: http://www.evc-cit.info/cit020/beginning-programming/chp_07/custom_sort.html
Follow their Web Development course here: http://www.theodinproject.com/ruby-programming/advanced-ruby-building-blocks?ref=lnav

How to create links in Rails

Creating links can be confusing if you are just starting to learn Rails. It is important to understand how your views, controllers, and routes are connected.

If you already have an app you are working on, simply type:

$rake routes

This command will let you see all your routes, how your views connect to your controller, their URLs, and how to link them in your HTML.erb file.

For example, this is mine:
rake routes rails

The ‘Prefix’ column contains the name of the link path that you will use.

The ‘Verb’ column tells you what HTTP actions are connected to each path:

 REST verb GET POST PUT DELETE
Action show create update destroy

The ‘URI Pattern’ column is the URL link

The ‘Controller#Action’ column gives you the name of the controller and the name of the method action connected with the page.

Taking the above information, we can open our ‘views/articles/index.html.erb’ page and start adding links!

Before you start, it is important to understand the difference between <% and <%=. The difference is:

  • <%..%> is for items you DO NOT want to appear in the view (like if statements and iterations).
  • <%=..%> is for items you DO want to appear in the view (like images and links).

To create a link in your html.erb file, you can follow this example:

<%= link_to "Text to show", model_instance %>

It will generate html that looks like this:

<a href="http://www.url.com/model_instance">Text to show</a>

Let’s create our own using the routes listed in our $rake routes using the above example.

<% link_to "New Article", new_article_path %>

The HTML for the link will look like so:

<a href="/articles/new">New Article</a>

To add a class to the link, just include it at the end:

<% link_to "New Article", new_article_path, class: "btn btn-default" %>

To add an image, use the following code recipe:

<%= image_tag('image.jpg') %>

Ruby on Rails Resources

Ruby:

https://www.ruby-lang.org/en/news/2013/12/25/ruby-2-1-0-is-released/

Rails:

http://guides.rubyonrails.org/4_0_release_notes.html

Rails Installation Guide:

http://railsinstaller.org/en
http://guides.railsgirls.com/install/
http://installfest.railsbridge.org/installfest/ I used this one to install on my Windows OS because I attended a RailsBridge event. I found it easy to follow. 

Ruby Gems:

https://rubygems.org/

Bundler:

http://bundler.io/
Bundler provides a consistent environment for Ruby projects by tracking and installing the exact gems and versions that are needed.

Learn Ruby:

TryRubyhttp://tryruby.org/levels/1/challenges/0 Really fun way to get introduced to the language. Great layout&design and user friendly.
Ruby on Codecademy: https://www.codecademy.com/tracks/ruby Very well written and easy to follow.
Ruby Programming on Odin: http://www.theodinproject.com/ruby-programming
Ruby Monk: http://rubymonk.com/learning/books/1-ruby-primer
Ruby the hard way: http://learnrubythehardway.org/book/ It really is hard. Especially if you don’t have a programming background.
Ruby in 100 minutes: http://tutorials.jumpstartlab.com/projects/ruby_in_100_minutes.html
Chris Pinehttps://pine.fm/LearnToProgram/chap_01.html
Master Ruby blockshttp://mixandgo.com/blog/mastering-ruby-blocks-in-less-than-5-minutes
Bastards book of Rubyhttp://ruby.bastardsbook.com/toc/
Ruby Newbie Odin Gisthttps://gist.github.com/brianllamar/11261930

Learn Rails:

Rails for Zombies: http://railsforzombies.org/ Really excellent lessons. Read more here.
Tech Talent South Rails Beginner Lesson:
http://techtalentsouth.slides.com/techtalentsouth/zero-to-heroku-workshop?token=r_LQ9_iu#/
Michael Hartl’s Tutorial: https://www.railstutorial.org/book/beginning
Ruby on Rails on Odin: http://www.theodinproject.com/ruby-on-rails

Ruby Help

http://ruby-doc.org/
https://www.codecademy.com/glossary/ruby/

Blogs:

http://www.jamesfend.com/learned-ruby-rails-12-weeks-launch-freelancify
http://www.codenewbie.org/blogs/ruby-roundup-1
http://www.smashingmagazine.com/2009/03/getting-started-with-ruby-on-rails/

Atlanta Ruby Users Group:

http://www.atlrug.com/

Jobs:

https://toprubyjobs.com/
https://www.jrdevjobs.com/jobs

Ruby Regular Expression Editor:

http://www.rubular.com/

Sandi Metz

Sandi Metz(http://www.sandimetz.com/) at the Atlanta RailsConf 2015 talking about object-oriented design: https://youtu.be/OMPfEXIlTVE

Looks at Ruby code, how to simplify and reduce the amount of code you write.

Sandi Metz wrote a book called Practical Object-Oriented Design in Ruby.
A description of what the book is all about and how it’s changed the way people learn to code:

Practical Object-Oriented Design in Ruby (POODR) is a programmers tale about how to write object-oriented code. It explains object-oriented design (OOD) using realistic, understandable examples.   POODR is a practical, readable introduction to how OOD can lower your costs and improve your applications.

POODR will help you:

  • Decide what belongs in a single class
  • Avoid entangling objects that should be kept separate
  • Define flexible interfaces among objects
  • Reduce programming overhead costs with duck typing
  • Successfully apply inheritance
  • Build objects via composition
  • Design cost-effective tests
  • Craft simple, straightforward, understandable code

If your code is killing you and the joy is gone, POODR has the cure.

Read more or purchase here: http://www.sandimetz.com/products/

Ruby |Breaking down the Caesar Cipher

Caesar Cipher in Ruby

From Wikipedia:

In cryptography, a Caesar cipher, also known as Caesar’s cipher, the shift cipher, Caesar’s code or Caesar shift, is one of the simplest and most widely known encryption techniques. It is a type of substitution cipher in which each letter in the plaintext is replaced by a letter some fixed number of positions down the alphabet. For example, with a left shift of 3, D would be replaced by A, E would become B, and so on. The method is named after Julius Caesar, who used it in his private correspondence.

There’s a brief video about it from Harvard’s CS50 class.

Breaking down the following solution line by line:

1  puts "Word please: "
2  text = gets.chomp.downcase
3
4  puts "Number please: "
5  n = gets.chomp.to_i
6
7  def caesar_cipher(text, n)
8    alphabet = ('a'..'z').to_a 
9    key = Hash[alphabet.zip(alphabet.rotate(n))]
10   text.each_char.inject("") { |newtext, char| newtext + key[char] }
11 end
12
13 puts caesar_cipher(text, n)

Line 1:

  puts "Word please: "

Prompts the user to write a word.

Line 2:

  text = gets.chomp.downcase

gets takes the word the user writes and .chomp cuts off the end parameters (like “/n”). The new word is now referred to as ‘text’.

Line 4:

  puts "Number please: "

Prompts the user to write a number.

Line 5:

  n = gets.chomp.to_i

gets takes the input number (which is a string)

.chomp cuts the end parameters off, and then .to_i turns the number into an integer.

The new number is now referred to as ‘n’.

Line 7:

  def caesar_cipher(text, n)

def caesar_cipher(text, n) defines a new method called caesar_cipher that takes in two arguments text and n which are taken from Line 2 and Line 4 respectively.

Line 8:

  alphabet = ('a'..'z').to_a

Defines a new variable called alphabet that is equal to individual letters a all the way to z. These letters are each their own individual string. The .to_a turns the 26 letters into an array. This array is named alphabet.

Line 9:

  key = Hash[alphabet.zip(alphabet.rotate(n))]

A new variable key is defined. It is equal to Hash[alphabet.zip(alphabet.rotate(n))]

Let’s break it down.

alphabet.rotate(n) – What does this do?
.rotate is a method in Ruby that returns a new array by rotating the array elements.

For example:

       a = [ "a", "b", "c", "d" ]
       a.rotate #=> ["b", "c", "d", "a"]
       a #=> ["a", "b", "c", "d"]
       a.rotate(2) #=> ["c", "d", "a", "b"]
       a.rotate(-3) #=> ["b", "c", "d", "a"]

In this case, alphabet.rotate(n) takes the alphabet variable (the array of all 26 letters) and rotates the array n number of times. The n comes from what the user puts when prompted in the beginning (see Line 5).

alphabet.rotate(n) is inside alphabet.zip(). What does alphabet.zip() do?

.zip is a useful method for combining collections in an ordered way.

       [1,2,3].zip(['a', 'b', 'c'])
       #=> [[1, "a"], [2, "b"], [3, "c"]]

As you can see, the above two arrays are combined together so that each number is paired with each letter. The number 1 is associated with ‘a’ and so forth.

.zip can also take 2 (or more) arguments to zip into the first:

       ['a', 'b', 'c'].zip( [1,2,3], ['oogie', 'boogie', 'booger'] )
       #=> [["a", 1, "oogie"], ["b", 2, "boogie"], ["c", 3, "booger"]]

So going back to our code, alphabet.zip(alphabet.rotate(n)) is taking our rotated alphabet variable array and matching the new order with our original alphabet array. For example, if n was 2, our alphabet variable would match with the new rotated alphabet like so:

  n = 2
  alphabet = ['a', 'b', 'c', 'd', 'e'..'z']
  new_alphabet = ['c', 'd', 'e', 'f', 'g'..'b']  // new_alphabet = alphabet.rotate(2)
  alphabet.zip(new_alphabet) = ['a', 'c'],['b', 'd'], ['c', 'e'] ..['z', 'b']

Hash[alphabet.zip(alphabet.rotate(n))]
Hash turns each pairing into key => value pairings.

For example, alphabet.zip(new_alphabet) would be equal to [['a' => 'c'], ['b' => 'd'], ['c' => 'e']..['z' => 'b']]. So now the value for ‘a’ is ‘c’, and so on.

Line 10:

Let’s break down this, too:

  text.each_char.inject("") { |newtext, char| newtext + key[char] }

What exactly is this line of code doing??

  text

text takes the string entered by the user (See Line 2).

  text.each_char

each_char takes the string entered by the user (text) and separates the string into their separate characters. For example, if text were “apple”, each_char would make “apple” turn into “a”, “p”, “p”, “l”, “e”.

  text.each_char.inject("")

.inject("") sends each character through the block (the block being everything between the brackets {}).  Each character of text passes through the block in the argument place labeled char.

The ("") defines the default starting point. It means the first time we pass through the block, we are defaulting (starting) with an empty string (“”).

  { |newtext, char| newtext + key[char] }

This is a block. It is connected to the .inject enumerator method, which just means every time you use .inject, you will have a block following it. There are two arguments in this block ‘newtext‘ and ‘char‘ that are new.

newtext is the default (starting) string, which in the first go through, would be an empty string (“”) because that’s what we declared after the .inject method: text.each_char.inject("")

char is the individual characters from the text variable.

key[char] takes in the individual character [char] and assigns its value found from the key variable we defined in Line 9.

All the individual characters will be run through the block until there are no more characters in the text string. To see how this works, let’s use the example of “apple”.

     text.each_char.inject("") { |newtext, char| newtext + key[char] }

     text = "apple"
     n = "2"

     first run through => 
     "apple".each_char = "a", "p", "p", "l", "e"
     ("a", "p", "p", "l", "e").inject("") { |"", "a"| "" + key["a"] }
     key["a"] == "c"
1st  ("a", "p", "p", "l", "e").inject("") { |"", "a"| "" + "c" }
2nd  ("p", "p", "l", "e").inject("c") { |"c", "p"| "c" + [key["p"]=="r"] }
3rd  ("p", "l", "e").inject("r") { |"r", "p"| "cr" + "r" }
4th  ("l", "e").inject("r") { |"r", "l"| "crr" + "n" }
5th  ("e").inject("n") { |"n", "e"| "crrn" + "g" }

     "crrng"

Line 11:

  end

end is connected to our method caesar_cipher and means that we are done defining the method.

Line 13:

  puts caesar_cipher(text, n)

This writes the result of the caesar_cipher method for us.

Project located here: http://www.theodinproject.com/ruby-programming/building-blocks?ref=lnav


Rotate method: http://apidock.com/ruby/Array/rotate
Method arguments: http://www.skorks.com/2009/08/method-arguments-in-ruby/
Zip method: http://dfriedm.github.io/blog/2013/10/12/ruby-zip-method/
Hash: http://ruby-doc.org/core-1.9.3/Hash.html
Each_char: http://ruby-doc.org/core-2.1.0/String.html#method-i-each_char
Inject: http://ruby-doc.org/core-2.2.2/Enumerable.html#method-i-inject
https://blog.udemy.com/ruby-inject/

Codermanual – Part V finished

I’ve just finished Part V of Codermanual, the JavaScript & jQuery section. It was an oversimplification of the language, I feel, but the way it was explained, really helped me wrap my head around how programming languages work. The amount of information in this part was overwhelming, but I feel confident now that I can handle JavaScript.

I had tried to learn JavaScript on my own back in April but I was using Codecademy at that time and I think their JavaScript tutorial was way too advanced. Everything went over my head. It was my first time learning an object-oriented programming language. Around the same time, I kept hearing a lot about Ruby and Ruby on Rails so I tried Codecademy’s Ruby course instead and found it much easier to grasp so I stuck with it and am now working on Michael Hartl’s Ruby on Rails tutorial.

I’m halfway through and realizing that there are still many things about Ruby that I have questions about, so I’m going to pause Hartl’s tutorial as well as Codermanual and do The Odin Project’s Ruby Programming course (which is also free!).

The more I learn, the more I realize how little I know.