### Intro to Ruby

#### Class 2

@gdidayton   |   #GDIDAY3

Check in on the #ruby slack channel

### 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:

Practice: 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. (Note: you'll be using `gets` and `puts` in this program, along with some math)

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

### 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"
``````

### 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"]

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
``````

### Let's 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.)

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 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

### 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"
if x < 20
puts "but x is less than 20"
end
elsif x <= 10 && x > 0
puts "x is a number between 1 and 10"
else
puts "Wow, don't be so negative, dude"
end
``````

### Let's Develop It

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

``````
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 :( :( :(

### 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
``````

### 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}"

``````

### Collections

There are three main types:

• Arrays
• Ranges
• Hashes
``````
new_array = [1, 3, 5]

new_range = 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
``````

### 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)"
end

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

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
new_hash.has_value?(35)

``````

Syntax:

`{ 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 & Removingfrom Hashes

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

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
``````

### .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
``````

### 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

@gdidayton   |   #GDIDAY3

We are done with class 2!

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

Check in on the #ruby slack channel