Intro to Ruby

Class 2

@gdiboston  

Welcome!

Girl Develop It is here to provide affordable programs for adult women interested in learning web and software development in a judgment-free environment.

Some "rules"

  • We are here for you!
  • Every question is important.
  • Help each other.
  • Have fun!

Girl Develop It is dedicated to providing a harrasment free learning experience for everyone.
For more information, see our Code of Conduct.

Homework Discussion

How was last week's homework?
Do you have any questions or concepts that you'd like to discuss?

The Homework was:

Command line: create a directory and a file in that directory.

Write a command line program that asks the user for the year they were born, then calculates their age in years, days, and seconds. Tell the user how old they are in these different formats.

Temperature conversion - Make a program that asks the user for the temperature in Fahrenheit and print out the temperature in Celsius and Kelvins.

Review

  • Lots of math
  • Variables, constants, literals
  • Data types: Numbers (fixnum), Strings
  • Text editor, command line, and ruby shell

Review

Let's create a directory for all of our GDI work.

What we will cover today

  • More things with Strings
  • Some new data types: Arrays, Booleans, Ranges and Hashes
  • Controlling the flow of our programs with Conditionals and Loops

Some more on Strings


				          new_string = "The quick brown fox"

				          new_string[0]
				          => "T"

				          new_string.split(" ")
				          (irb)>>["The", "quick", "brown","fox"]

				          ["The", "quick", "brown","fox"].join(" ")
				          (irb)>>"The quick brown fox"
                  

Example use case: excel files, CSV's

Arrays

Arrays have square brackets [] and can be filled with any type of object: fixnum, strings, even other arrays or hashes.


                      new_array = [1, 3, 5, 89, 212, 7, -100]
                      arr = ["wow", "woooo", "zowie"]
                      array = Array.new #will have no elements inside it initially
                      varied_array = ["one", 2, "THREE", 0.4, ["five", 6]]

                      # methods to get information about an array
                      new_array.length
                      new_array.count
                      arr.include?("yee ha")
                    

Arrays are a great way to keep track of information that changes frequently.

Accessing Elements in an Arrays

Arrays are ordered and are integer-indexed, starting at 0.

Elements can be accessed by their position.


                      new_array = [1, 3, 5, 89, 212, 7, -100]
                      arr = ["wow", "woooo", "zowie"]

                      new_array[0]    # returns the zeroth element
                      arr[2]          # returns the third element
                      arr[-1]         # returns the last (1st from the end) element
                      new_array.last  # returns the last element
                      arr.first       # returns the first element
                    

Adding & Deleting From Arrays

Adding and removing items to an array can be done in a variety of ways. These are the most common.


                      arr = ["wow", "woooo", "zowie"]

                      #add
                      arr.push("hot diggity") # adds argument as last element
                      arr << "yikes"          # adds argument as last element

                      #remove
                      arr.delete("wow")       # deletes the element that matches argument
                      arr.pop                 # removes and returns the last element
                    

More Array Methods

Arrays are used a lot in Ruby.
There are a lot of cool methods available for them.


                      arr = ["dog", "cat", "turtle", "parakeet", "ferret"]

                      arr.index("dog")    # returns the index of the element that matches argument
                      arr.join            # returns a string made up of all the elements
                      arr.clear           # removes all elements from the array
                      arr.reverse         # returns new array with same elements, reversed
                      arr.shuffle         # returns new array with same elements, shuffled
                      arr.uniq            # returns a new array with only unique elements
                      arr.size            # returns the number of elements in the array
                      arr.empty?          # returns a boolean
                      arr.include?("dog") # returns a boolean
                    

Learn more about arrays here.

Let's Develop It

Write the following program in a new .rb file in your new GDI directory.

Set up an array to hold the following values, and in this order:
23, 6, 47, 35, 2, 14.

Print out the average of all 6 numbers. (You can use fixnum for this exercise, which will round down your answer.)

Using the above values, have your program print out the highest number in the array.


				              my_array = [23, 6, 47, 35, 2, 14]
				              total = my_array[0] + my_array[1] + my_array[2] + my_array[3] + my_array[4] + my_array[5]
				              average = total/my_array.size

				              print "The average is " + average.to_s

			                print "The max is "+ my_array.max.to_s
			                 

Booleans

A boolean is a basic data type. It can have only two values

true or false

(Boolean algebra - a branch of algebra first introduced by mathematician, philosopher, and logician George Boole. Boolean algebra is fundamental in electronics, set theory, statistics, and all modern programming languages.)

Boolean Expressions

Code that compares values and returns True or False is called a Boolean expression

  • Test for equality by using ==. (= is used for assignment)
  • Test for greater than and less than using > and <
a == b a is equal to b
a != b a does not equal b
a < b a is less than b
a > b a is greater than b
a <= b a is less than or equal to b
a >= b a is greater than or equal to b

Learn more about logical operators in Ruby here.

Boolean Expressions Practice


                      # try some of these out in IRB
                      a = 3
                      b = 4
                      a != b
                      a <= 3
                      a >= 4
                      a = 5
                      b = 5
                      a == b
                      c = a == b # Combine comparison and assignment
                      puts c
                      3 < 5
                    

Remember: Equals does not equal "equals equals"

Further reading on boolean expressions...

Boolean Expressions

A boolean expression evaluates to true or false. It can also have multiple parts, joined by AND (&&) or OR (||).

EXPRESSION EVALUATES TO
true && true true
true && false false
false && false false
true || true true
true || false true
false || false false
not (true && false) true

Further practice on boolean expressions...

Let's Develop It

Take a few minutes and experiment with boolean expressions in IRB. You can start with the examples below.


                      true && false
                      1 == 1 && 2 > 37
                      "boop" == "bip" || 7 == 8
                      false || true
                      89 > 88 || 89 < 90
                      true || not(1 == 1 || 2 == 65)
                    

Remember, the comparision methods are not giving us the strings 'true' and 'false'; they are giving us special objects true and false!

Putting Booleans to Work

So, what's the value of knowing if a statement is true or false? Often, you'll use that to control whether a piece of code will execute or not.


                      user_guess = gets.chomp.to_i
                      secret_number = 312

                      if user_guess < secret_number
                        puts "Too low!"
                      elsif user_guess > secret_number
                        puts "Too high!"
                      else
                        puts "You guessed it. Wow maybe you're psychic...."
                      end
                    

Can you tell what this code does?

Conditionals

When we want different code to execute depending on certain criteria, we use a conditional

We achieve this using if statements and boolean expressions.


                      if x == 5
                        puts 'x is equal to 5'
                      end
                    

Conditionals

We often want a different block to execute if the statement is false. This can be accomplished using else.


                      if x == 5
                        puts 'x is equal to 5'
                      else
                        puts 'x is not equal to 5'
                      end
                    

Conditionals


					            puts "I am a fortune-teller.  Tell me your name:"
					            name = gets.chomp
					            if name == "Chris"
						              puts "I see great things in your future"
					            else
						              puts "Your future is... Oh my!  Look at the time!"
						              puts "I really have to go, sorry!"
					            end
                    

Notice: indenting doesn't matter but it sure is pretty!

Conditionals

The following shows some examples of conditionals with more complex boolean expressions:


                      # And
                      if x > 3 && y > 3
                        puts 'Both values are greater than 3'
                      end

                      # Or
                      if x != 0 || y != 0
                        puts 'The point x,y is not on the x or y axis'
                      end

                      # Not
                      if not(x > y)
                        puts 'x is less than y'
                      end
                    

Branching: Chaining and Nesting conditionals

You can extend conditionals to make more decisions or branches

Chained conditionals use elsif to test if additional statements are true.
The single else action will only happen if all preceding conditions are false.

Nested conditions are simply more conditions inside your conditional (yo dog...)

For example:


                      if x > 10
                        puts "x is greater than 10"
                      elsif x < 20
                        puts "but x is less than 20"
                      elsif 0 < x && x <= 10
                        puts "x is a number between 1 and 10"
                      else
                        puts "Wow, don't be so negative, dude"
                      end

                      # Note!
                      # You must use separate expressions:
                      # You might be tempted, instead of  0 < x && x <= 10
                      # to write 0 < x <= 10 (like you might in math)
                      # This will cause errors.
                    

Let's Develop It

Adventure (1975)

Write a program that uses conditionals and user input to allow the user to play a SHORT adventure game.

  • Tell the user the story/plot, i.e. you are being chased by a dragon
  • Give the user some options, i.e. 1 - hide in a cave, 2 - climb the tallest tree
  • Give the user the results based on their choice

Let's Develop It Example


                        # adventure.rb
                        puts "A vicious dragon is chasing you!"
                        puts "Options:"
                        puts "1 - Hide in a cave"
                        puts "2 - Climb a tree"

                        input = gets.chomp

                        if input == '1'
                          puts "You hide in a cave. The dragon finds you and asks if you'd like to play Scrabble. Maybe it's not so vicious after all!"
                        elsif input == '2'
                          puts "You climb a tree. The dragon can't find you."
                        else
                          puts "That's not a valid option."
                        end
                      

Loops

It is often useful to perform a task and to repeat the process until a certain point is reached.

The repeated execution of a set of statements is called iteration, or, more commonly, a loop.

One way to achieve this, is with the while loop.


                      x = 10

                      while x > 0
                        puts "Loop number #{x}"
                        x = x - 1
                      end

                      puts 'Done'
                    

While Loops


                        x = 10

                        while x > 0
                          puts "Loop number "+ x.to_s
                          x = x - 1
                        end
                          

The while statement takes a condition, and as long as it evaluates to true, the code block beneath it is repeated. This creates a loop.

Without the x = x - 1 statement, to increment the value of x, this would be an infinite loop :( :( :(

IRL example: reading a file, and wanting to stop at the end of file.

While loops

Consider the following example that uses a while loop to sing you a song.


                      num_bottles = 99

                      while num_bottles > 0
                        puts "#{num_bottles} bottles of beer on the wall,
                              #{num_bottles} bottles of beer, take one down, pass it
                              around, #{num_bottles - 1} bottles of beer on the wall!"

                        num_bottles = num_bottles - 1
                      end
                    

#{num_bottles} is an example of string interpolation

this automatically calls .to_s, looks nicer, technically faster, but does the same thing as the +

Let's Develop It

  • Write a program that obtains user input and then prints out what the user chose.
  • This program should not exit until the user says it should (maybe by entering "quit"?)
  • Use a loop!
  • You can use the next slide as an example.

Let's Develop It: Example


                            # loopy.rb
                            loopy = true

                            while loopy == true
                              puts "Do you want to keep going around?"
                              puts "1 - Yes lets keep going"
                              puts "2 - Just keep swimming!"
                              puts "0 - Get me out of this thing!"
                              user_input = gets.chomp

                              if user_input == '0'
                                loopy = false
                              end
                            end
                            

Learn more about loops in Ruby here.

Each loops

The most commonly used type of loop in Ruby is an each loop.

It uses the each method to iterate over a collection of elements (like arrays!), doing work to each one.

First, we need a collection. Let's use a array of numbers to loop over.


				              my_array = [23, 6, 47, 35, 2, 14]

				              my_array.each do |i|
				                  puts "Value of i is #{i}"
				              end
                    

Each loops

The loop has three parts:


                      my_array = [23, 6, 47, 35, 2, 14]

                      my_array.each do |i|
                        puts "Value of i is #{i}"
                      end
                    
  • The collection that will be looped through, my_array
  • The name to give each element when the loop begins again - i - in the pipes |i|
  • The code to execute with the element - the puts statement

We will revisit the each loop when we have a better understanding of collections.

Let's (re-)Develop It

Set up an array to hold the following values, and in this order:
23, 6, 47, 35, 2, 14.

Print out the average of all 6 numbers. (You can use fixnum for this exercise, which will round down your answer.)

Use a loop to do the math!

Using the above values, have your program print out the highest number in the array.

Bonus: use a loop and conditonals to get the array from the user


                      my_array = [23, 6, 47, 35, 2, 14]
                      total = 0

                      myarray.each do |i|
                        total += i
                        average = total/my_array.size
                        print "The average is #{average}"
                        print "The max is #{my_array.max}"
                      end

			                 

Collections

There are three main types:

  • Arrays
  • Ranges
  • Hashes

                      new_array = [1, 3, 5]

				              new_range = (1..10)

                      new_hash = {"dog" => "snoopy", "bird" => "woodstock"}
                    

Ranges


                        inclusive_range = (1..3)  # contains 1, 2, 3
                        exclusive_range = (1...3) # contains 1, 2
                        letter_range = ('a'..'e') # contains 'a', 'b', 'c', 'd', 'e'
                        word_range = ('bar'..'bat').to_a #contains 'bar', 'bas, 'bat'
                        

Ranges are simply the range of values between
the given first and last elements.

Inclusive ranges have two dots, and include the last element.

Exclusive ranges have three dots, and do not include the last element.

Ranges need to be defined from lowest value to highest.

Ranges

Try out these range methods in IRB.


                      (1..99).max
                      (890..902).begin
                      (890..902).first(4)
                      (890..902).last(3)
                      (890..902).end
                      (28..22).min

                      (22..28).to_a

                      ('b'...'z').include?('j')
                      new_array[1..2] # returns the second and third elements
                    

Learn more about ranges here.

Using Ranges as Conditionals

The my_range===value does the same as my_range.to_a.include?(value)


                        if ((1..10) === 5)
                        puts "5 lies in (1..10)"

                        if (('a'..'j') === 'c')
                        puts "c lies in ('a'..'j')"

                        if (('a'..'j') === 'z')
                        puts "z lies in ('a'..'j')"
                        end
                      

Looping through Ranges

Use the each loop to step through or iterate through ranges


                      # use the range operator to do 0 to 5 counts
                      (0..5).each do |i|
                        puts "Loop number #{i}"
                      end

                    

Let's Develop It

Write a program that prints out every number
between 1 and 1000 that is divisible by 7.

Print out all the prime numbers
between 1 and 1000.

Hint: the modulus operator, %, will be helpful.

Hashes

Hashes have curly braces {} and "hash rockets" => and can be filled with any data type: fixnum, strings, even arrays and hashes.


                      grades_hash = { "Jane Doe" => 10, "Jim Doe" => 6, "Jan Doe" => 8}
                      new_hash = { 1 => "a", "d" => 12, "f" => 35 }

                      # methods to find information about hashes
                      new_hash.length
                      grades_hash.count
                      grades_hash.size
                      grades_hash.has_key?("Jan Doe")
                      new_hash.has_value?(35)
                    

Syntax (keys as symbols): { key: value, key: value }

Syntax (keys as strings): { key => value, key => value }

Accessing Elements in Hashes

Hashes are unordered. Hashes are like dictionaries, with unique key / value pairs.

Because hashes can have any type of object as an index, and are unordered, we must access values by their key.


                      grades_hash = { "Jane Doe" => 10, "Jim Doe" => 6, "Jan Doe" => 8}
                      new_hash = { 1 => "a", "d" => 12, "f" => 35 }

                      grades_hash["Jane Doe"]   # returns 10, the value of this key
                      new_hash["d"]             # returns 12, the value of this key
                      grades_hash.first         # returns first key/value pair... probably
                    

Adding & Removing
from Hashes


                      new_hash = { 1 => "a", "d" => 12, "f" => 35 }

                      # add
                      new_hash["z"] = 43   # adds a new key/value pair "z" => 43

                      #remove
                      new_hash.delete("d") # removes key/value pair with specified key
                      new_hash.clear       # removes all key/value pairs
                    

More Hash methods


                      chapters = {"My Early Home" => (1..15), "The Hunt" => (16..28),
                        "My Breaking In" => (29..46), "Birtwick Park" => (46..60)}

                        chapters.count      # returns number of key/value pairs in hash
                        chapters.keys       # returns an array of all the keys in hash
                        chapters.has_key?("How It Ended")  # returns a boolean
                        chapters.to_a       # converts hash to an array of arrays
                        chapters.invert     # returns new hash with old one's values
                                # as keys and keys as values
                      

Learn more about hashes here.

.each with Hashes

Each element has a key and value that needs to be dealt with.


                      grades_hash = { "Jane Doe" => 10, "Jim Doe" => 6, "Jan Doe" => 8}
                      grades_hash.each do |key, value|
                        puts "#{key}'s grade is #{value}"
                      end
                    

Questions?

Homework

Good news, you are now the owner of a pet shop! Bad news, the previous owner didn't keep track of their pets. Let's write a program to keep track of all the animals!

Use a hash to keep track of your animals and create a menu to add, remove, and print from your hash.


                          $ What would you like to do?
                          $ 1. add animal
                          $ 2. remove animal
                          $ 3. show all animals
                          $ 4. quit program
                          >>1
                          $ Enter the name of the animal to add:
                          >> cat
                          $ You already have 1 cat(s)! Now you have 2 cat(s)! #updates the hash value
                          ...
                        

Homework, cont.

Write a Deaf Grandma program. Whatever you say to grandma (whatever you type in), she should respond with HUH?! SPEAK UP, HONEY!, unless you shout it (type in all capitals). If you shout, she can hear you (or at least she thinks so) and yells back, NO, NOT SINCE 1938! To make your program really believable, have grandma shout a different year each time; maybe any year at random between 1930 and 1950. (This part is optional, and would be much easier if you read the section on Ruby's random number generator at the end of the this methods chapter.) You can't stop talking to grandma until you shout BYE.

Hint: Don't forget about chomp! 'BYE' with an Enter is not the same as 'BYE' without one!

Hint 2: Try to think about what parts of your program should happen over and over again. All of those should be in your while loop.

Homework, BONUS.

Extend your Deaf Grandma program: What if grandma doesn't want you to leave? When you shout BYE, she could pretend not to hear you. Change your previous program so that you have to shout 'BYE' three times in a row. Make sure to test your program: if you shout 'BYE' three times, but not in a row, you should still be talking to grandma.

Intro to Programming in Ruby

@gdiboston   |   #GDIDAY3


We are done with class 2!

We have done a lot, I know you have questions so ask them!

Setup   |   Class 1   |   Class 2   |   Class 3   |   Class 4