Ruby Programming – ODIN Project – 1

odinRuby Programming

You’ll learn a combination of Ruby programming fundamentals and best practices and you will get the chance to build a variety of different projects along the way.

You will learn Ruby, the language designed specifically with programmer happiness in mind. You will build various projects including Tic Tac Toe, Hangman, a real web server, and even Chess. You’ll  put together a Twitter spambot (that really spams!), save and open files, test out your code, separate your spaghetti code into nice modular classes, and even reproduce some basic algorithms and data structures for solving complex problems.


Basic Ruby

In this section, we’ll cover the basic building blocks of Ruby.  Everything else you’ll learn in programming builds on these concepts.

Step 1: How this Course Will Work

Rails is a framework built using Ruby and every piece of code in it is Ruby. When (not if) something in your project breaks, you’d better be able to debug it. And what happens when you want to stretch your wings and do something just a bit beyond what the vanilla tutorials show you how to do? The amount of time you’d spend googling your error messages and staring blankly at help docs was better spent learning Ruby.

This is also where the real project work begins. Some of the early material will be fairly straightforward and will rely on simple exercises to help reinforce understanding. You’ll learn using some Codecademy modules at first but the goal is for you to get a much deeper and more practical understanding of the material than that.

Format

Ruby‘s a big language so it’s been broken up into smaller chunks to make it more digestible.

In each lesson:

  1. We’ll introduce the topic briefly and provide you with a list of things you should pay attention to.
  2. You’ll be asked to do readings, watch videos, do online courses or otherwise consume content to initially learn the material.
  3. At the end of most lessons will be exercises to help you reinforce your knowledge of the material.
  4. Every few lessons you will be asked to build a larger project. These are best done with a friend.
  5. Finally, we’ll include additional helpful resources and other potentially useful materials at the end of each lesson.

Two Paths Forward

Everyone is coming into this with a different goal in mind, so to accommodate that, here’s two options for your path forward:

1. If you’re just trying to race ahead and put up some Rails sites as fast as possible (and worry about learning the fundamentals later), then your best bet is to first complete the Basic Ruby section, which uses primarily Codecademy as a resource, and then skip to the Rails course. Your knowledge won’t be complete but you’ll be in a pretty good position to start from if you’re in a hurry.

2. If you’re really looking for a solid, sustainable base of knowledge, just stick to the normal road-map. What we cover will give you a problem solving ability that you won’t otherwise have.


Primary Resources:

1. Codecademy‘s (https://www.codecademy.com/learn/ruby) Learn to program in Ruby has a lot of great introductory content to get you familiar with the Ruby language.

2. Chris Pine’s Learn to Program (https://pine.fm/LearnToProgram/) provides a good introduction to Ruby.

3. Peter Cooper’s Beginning Ruby (http://peterc.org/beginningruby/) is a solid introduction to Ruby that covers the majority of the language that you need to understand. It’s a bit outdated but Ruby hasn’t changed a lot since it was published. The goal of this project is to move BEYOND Codecademy and other simple, free resources.  This book will start covering some of the more intermediate/useful areas that you’ll need to know to create your own sites.

See http://bedford-computing.co.uk/learning/ruby-on-rails/web-development-101-odin-project/


 The (Free) Backup Resources

  • Another good book available in the older edition online for free is Programming Ruby 1.9, Third Edition (http://it-ebooks.info/book/59/).  . This, too, is a bit outdated.

 Step 2: Ruby Building Blocks

An in-depth look at the Ruby fundamentals like Variables, Data Types, Strings, and Methods.

Points to Ponder

Look through these now and then use them to test yourself after doing the assignment

Note: We recommend you read through the list, complete the tasks, and then test yourself by seeing if you can answer all these questions.

  • Numbers, Operators and Expressions:
    • What’s the difference between an Integer and a Float?
    • Why should you be careful when converting back and forth between integers and floats?
    • What’s the difference between =, ==, and ===?
    • How do you do exponents in Ruby?
    • What is a range?
    • How do you create a range?
    • What’s the difference between (1..3) and (1...3)?
    • What are three ways to create a range?
  • Strings:
    • What’s the difference between single and double quotes?
    • What is string interpolation?
    • What are escape characters?
    • What are line breaks?
    • How do you make other things into strings?
    • How do you concatenate strings?
    • How do you access a specific character or substring?
    • How do you split up strings into arrays?
    • How are strings and arrays similar?
    • How do you get and clean up user input on the command line?
    • What does it mean that strings are “mutable” and why care?
    • What is a symbol?
    • How is a symbol different from a string?
    • What is a Regular Expression (RegEx)?
    • How can you center or right-justify a string?
  • Arrays:
    • What are three ways to create an array?
    • How do you prepopulate the array with default data?
    • How do you access items in an array?
    • How can you access a specific group of items in an array?
    • How do you modify the items in an array?
    • How do you combine arrays?
    • How do you find the values in one array that aren’t in another?
    • How do you find values in both arrays?
    • What is the difference between push/pop and shift/unshift?
    • What is the shovel operator?
    • How is > arr.pop different from > arr[-1]?
    • How is pushing or <<ing another array into your array different from just adding them together?
    • How do you delete items in an array?
    • Why should you be careful deleting items in an array?
    • How can you convert arrays to strings?
    • How can you convert from other data types to arrays?
    • How can you figure out if an array contains a particular value?
    • How do you find the biggest item in an array?
    • How do you find the smallest item in an array?
    • How do you remove any duplicates from your array?
    • How do you find out how big an array is?
    • How do you put an array in order?
    • What are the naming conventions for arrays?
    • What should you store in arrays?
  • Hashes:
    • What is a hash?
    • What are keys and values?
    • How is a hash similar to an Array?
    • How is a hash different from an Array?
    • What are 3 ways to create a hash?
    • What is the hash rocket?
    • How do you access data in a hash?
    • How do you change data in a hash?
    • What types of data are good to store in a hash?
    • What are options hashes?
    • How do you delete data from a hash?
    • How do you add hashes together?
    • How do you list out all the keys or values?
    • How do you see if the hash contains a key or value?
    • What is a set?
  • Dates and Times:
    • How do you get the current date and time?
    • How do you find just the Year? Month? Hour? Second? Weekday?
    • How do you create a Time specifically for 12/25/2013?
    • How do you find how many days have passed between two Time‘s?
    • What’s the difference between UTC and GMT and Local times?
    • How would you find out the time that was 100 seconds ago? 10 days ago?
  • Other Random Stuff:
    • What is nil?
    • How do you check if something is nil?
    • What’s the difference between nil and blank and empty?
    • Are the following nil or empty?
      • " ", "", [], [""], {}
    • What’s the difference between puts and p and print?
    • What does inspect do?
    • What do +=, -=, *= and /= do?
    • What is parallel assignment?
    • What’s the easiest way to swap two variables?

Your Tasks:

1. Complete Learn to Program (https://pine.fm/LearnToProgram/)

See http://bedford-computing.co.uk/learning/ruby-on-rails/web-development-101-odin-project/

2. Complete Codeacademy’s Introduction to Ruby course (https://www.codecademy.com/courses/ruby-beginner-en-d1Ylq/0/)

3. Complete Codeacademy’s Introduction to Ruby project Putting the Form in Formatter

4. Read Beginning Ruby’s Chapter 2: Programming == Joy: A Whistle-Stop Tour of Ruby and Object Orientation (http://peterc.org/beginningruby/)

5. Read Beginning Ruby’s Chapter 3: Ruby’s Building Blocks: Data, Expressions, and Flow Control (http://peterc.org/beginningruby/).  Pages 31-50 (only the section on Numbers and Expressions and the section on Text and Strings)

6. Look at TutorialsPoint’s Date and Time in Ruby section.  No need to memorize all the Time Formatting Directives, just know what they are and where to find them.

7. Complete this RegexOne Regex interactive tutorial (http://regexone.com/) and the sample problems.

8. Look at this Escape Characters list : Escape Characters « String « Ruby (http://www.java2s.com/Code/Ruby/String/EscapeCharacterslist.htm) and keep it for future reference. You’ll probably only end up using \n newlines and \t tabs.

9. For a deeper look at certain sections of the above material, check out these posts from Erik Trautman:


 Test Yourself

Note: If you want to actually write and run your own Ruby code, you can either use IRB from the command line (type irb after the prompt), or run it from a script file using $ruby ./your_file_name_in_the_current_directory.rb, or use the online editor at repl.it (https://repl.it/languages/Ruby).


Additional Resources

Look up anything you do not understand in

  • If you still don’t understand certain topics or don’t like my summary, look them up in the
    The Bastards Book of Ruby – A Programming Primer for Counting and Other Unconventional Tasks (http://ruby.bastardsbook.com/)
  • Look again at Ruby Monk (https://rubymonk.com/)

See http://bedford-computing.co.uk/learning/ruby-on-rails/web-development-101-odin-project/


Project: Building Blocks

By now you should feel confident working with strings, arrays and hashes. We’ll do a couple of classic “intro to programming” problems here to help consolidate your knowledge and get warmed up for working on small projects.

You can do these in IRB or create a separate script file to run from the command line.

Note: If you want to actually write and run your own Ruby code, you can either use IRB from the command line (type irb after the prompt), or run it from a script file using $ruby ./your_file_name_in_the_current_directory.rb, or use the online editor at repl.it (https://repl.it/languages/Ruby).


 To begin with…

Build Codecademy’s simple User Input Word Counter (https://www.codecademy.com/courses/ruby-beginner-en-693PD/0/1)

In this project, you’ll build a program that takes a user’s input, then builds a hash from that input. Each key in the hash will be a word from the user. Each value will be the number of times that word occurs.


Project 1: Caesar Cipher

From Wikipedia (https://en.wikipedia.org/wiki/Caesar_cipher):

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.


Your Task

Implement a caesar cipher that takes in a string and the shift factor and then outputs the modified string:

    > caesar_cipher("What a string!", 5)
    => "Bmfy f xywnsl!"

Quick Tips:

  • You will need to remember how to convert a string into a number.
  • Don’t forget to wrap from z to a.
  • Don’t forget to keep the same case.

 Project 2: Stock Picker

Your Task

Implement a method #stock_picker that takes in an array of stock prices, one for each hypothetical day. It should return a pair of days representing the best day to buy and the best day to sell. Days start at 0.

    > stock_picker([17,3,6,9,15,8,6,1,10])
    => [1,4]  # for a profit of $15 - $3 == $12

Quick Tips:

  • You need to buy before you can sell
  • Pay attention to edge cases like when the lowest day is the last day or the highest day is the first day.

 Project 3:  Substrings

Your Task

Implement a method #substrings that takes a word as the first argument and then an array of valid substrings (your dictionary) as the second argument. It should return a hash listing each substring (case insensitive) that was found in the original string and how many times it was found.

    > dictionary = ["below","down","go","going","horn","how","howdy","it","i","low","own","part","partner","sit"]
    => ["below","down","go","going","horn","how","howdy","it","i","low","own","part","partner","sit"]

    > substrings("below", dictionary)
    => {"below"=>1, "low"=>1}

Next, make sure your method can handle multiple words:

    > substrings("Howdy partner, sit down! How's it going?", dictionary)
    => {"down"=>1, "how"=>2, "howdy"=>1,"go"=>1, "going"=>1, "it"=>2, "i"=> 3, "own"=>1,"part"=>1,"partner"=>1,"sit"=>1}

Quick Tips:

  • Recall how to turn strings into arrays and arrays into strings.

 Step 3: Advanced Ruby Building Blocks

This section looks further into the following topics – Control Flow, Looping, Arrays, Hashes, Blocks, Sorting. The projects in the Tasks section are good for doing on your own because Codecademy gives you all kinds of help with them.

Points to Ponder

Look through these now and then use them to test yourself after doing the tasks

  • Conditionals and Flow Control
    • What is a “boolean”?
    • What are “truthy” values?
    • Are nil, 0, "0", "", 1, [], {} and -1 considered true or false?
    • When do you use elsif?
    • When do you use unless?
    • What does <=> do?
    • Why might you define your own <=> method?
    • What do || and && and ! do?
    • What is returned by puts("woah") || true?
    • What is ||=?
    • What is the ternary operator?
    • When should you use a case statement?
  • Iteration
    • What does loop do?
    • What are the two ways to denote a block of code?
    • What is an index variable?
    • How do you print out each item of a simple array [1,3,5,7] with:
      • loop?
      • while?
      • for?
      • #each?
      • #times?
    • What’s the difference between while and until?
    • How do you stop a loop?
    • How do you skip to the next iteration of a loop?
    • How would you start the loop over again?
    • What are the (basic) differences between situations when you would use while vs #times vs #each?
    • What does nesting loops mean and when would you use it?
  • Blocks, Procs, and Lambdas:
    • How is a block like a function?
    • How is a block different from a function?
    • What are the two ways to declare a block?
    • How do you return data from a block?
    • What happens if you include a return statement in a block?
    • Why would you use a block instead of just creating a method?
    • What does yield do?
    • How do you pass arguments to a block from within a method?
    • How do you check whether a block was actually passed in?
    • What is a proc?
    • What’s the difference between a proc and a block?
    • When would you use a proc instead of a block?
    • What is a closure?
    • What is a lambda?
    • What’s different between a lambda and a proc?
    • What is a Method (capital “M”)?
    • What do Methods basically allow you to do that could probably be pretty interesting when you’re writing some more advanced programs later on?
  • Enumerable and Modules
    • What is a module?
    • Why are modules useful?
    • What does #each do?
    • What does #each return?
    • What does #map do?
    • What does #map return?
    • What is the difference between #map and #collect?
    • What does #select do?
    • What does #select return?
    • What is the difference between #each#map and #select?
    • What does #inject do?
    • When might you use #inject?
    • How do you check if every item in a hash fulfills a certain criteria?
    • What about if none of the elements fulfill that criteria?
    • What (basically) is an enumerator?
  • Writing Methods
    • How many things should a method ideally do?
    • What types of things should a method modify?
    • What should you name a method?
    • What does self mean?
    • What do you need to do to create your own Ruby script file?
    • How would you run a Ruby script from the command line?
    • How can you check whether your script was being run from the command line?
    • What is a shebang line?
    • What does require do?
    • What does load do?
    • What is the difference between require and load?
    • How do you access any parameters that were passed to your script file from the command line?
    • What does #send do?
    • When would #send be used that’s different from just running the method on an object ‘normally’?

Your Tasks

  1. Complete Codecademy’s Beginner’s Ruby course’s sections 2 to 6 (https://www.codecademy.com/learn/ruby)

2. Read Beginning Ruby (http://peterc.org/beginningruby/) Chapter 3: Ruby’s Building Blocks: Data, Expressions, and Flow Control (pages 50-76)

3. For a deeper look at certain sections of the above material, check out these posts from Erik Trautman:


Test Yourself

Make sure you can do the following quizzes from Code Quizzes (http://www.codequizzes.com/). They are quite short and should give you an idea of what you still need to brush up on.


(Optional) Extra Practice

  • Complete the Learn Ruby With the Neo Ruby Koans (http://rubykoans.com/) exercises.  You have to complete/debug the code it provides until it passes the tests before you can go on with the next exercise (TDD approach).

Additional Resources

Exercise 13: Parameters, Unpacking, Variables
Exercise 14: Prompting And Passing


Project: Advanced Building Blocks

Now you’ll get the chance to really apply what you’ve learned so far by building a simple cipher and rebuilding the Enumerable methods.

Project 1: Bubble Sort

Sorting algorithms are some of the earliest that you typically get exposed to in Computer Science. It may not be immediately obvious how important they are, but it shouldn’t be hard to think of some examples where your computer needs to sort some massive data-sets during everyday operations.

One of the simpler (but more processor-intensive) ways of sorting a group of items in an array is bubble sort, where each element is compared to the one next to it and they are swapped if the one on the right is larger than the one on the left. This continues until the array is eventually sorted.

1. Look at Harvard’s CS50x video on BubbleSort (http://cs50.tv/2012/fall/shorts/bubble_sort/bubble_sort-720p.mp4)

2. Read Bubble sort (https://en.wikipedia.org/wiki/Bubble_sort)

Bubble Sort


Your Task:

1. Build a method #bubble_sort that takes an array and returns a sorted array. It must use the bubble sort methodology.

    > bubble_sort([4,3,78,2,0,2])
    => [0,2,2,3,4,78]

2. Now create a similar method called #bubble_sort_by which sorts an array but accepts a block. The block should take two arguments which represent the two elements currently being compared. Expect that the block’s return will be similar to the spaceship operator you learned about before. If the result of the block is negative, the element on the left is “smaller” than the element on the right. 0 means they are equal. A positive result means the left element is greater. Use this to sort your array.

    > bubble_sort_by(["hi","hello","hey"]) do |left,right|
    >   left.length - right.length
    > end
    => ["hi", "hey", "hello"]

Project 2: Enumerable Methods

You learned about the Enumerable module that gets mixed in to the Array and Hash classes (among others) and provides you with lots of handy iterator methods. To prove that there’s no magic to it, you’re going to rebuild those methods.

Your Task

1. Create a script file to hold your methods and run it in IRB to test them later.

2. Add your new methods onto the existing Enumerable module. Ruby makes this easy for you because any class or module can be added to without trouble … just do something like:

module Enumerable

def my_each

# your code here

end

end

3. Create #my_each, a method that is identical to #each but (obviously) does not use #each. You’ll need to remember the yield statement. Make sure it returns the same thing as #each as well.

4. Create #my_each_with_index in the same way.

5. Create #my_select in the same way, though you may use #my_each in your definition (but not #each).

6. Create #my_all? (continue as above)

7. Create #my_any?

8. Create #my_none?

9. Create #my_count

10. Create #my_map

11. Create #my_inject

12. Test your #my_inject by creating a method called #multiply_els which multiplies all the elements of the array together by using #my_inject, e.g. multiply_els([2,4,5]) #=> 40

13. Modify your #my_map method to take a proc instead.

14. Modify your #my_map method to take either a proc or a block, executing the block only if both are supplied (in which case it would execute both the block AND the proc).

Quick Tips:

  • Remember yield and the #call method.