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

              #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

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

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

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

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

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
            

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)"
			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
            grades_hash.count
            grades_hash.size
            grades_hash.has_key?("Jan Doe")
            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 & 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

@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

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