Homework Review

Warmup:

Write a program that asks the user for all U.S. states they have visited (followed by a return). Typing "done" should terminate the program. Print all states to the screen.

 

Warmup Solution:

Let's set up an empty array of visited states and prompt the user for input.

visited = []

puts "Enter all the states you've been to! Type 'done' when you're finished:"

Warmup Solution:

Get the states from the user, then check to see if they entered "done". If so stop collecting input, otherwise push to the visited array.

state = gets.chomp.upcase

if state.downcase != 'done'
  visited.push(state)
end


Warmup Solution:

We need a loop to keep collecting states from the user. But...

keep_going = true

while keep_going
  state = gets.chomp.upcase 

  if state.downcase != 'done'
    visited.push(state)
  end
end

Warmup Solution:

... we need a way to exit the loop once "done" is entered. Use "break"!

keep_going = true

while keep_going
  state = gets.chomp.upcase 

  if state.downcase != 'done'
    visited.push(state)
  else
    break
  end
end

Warmup Solution:

Finally we need to print out the states the user has visited. We can either join a comma separated array...

puts "You have visited the following states:"
puts visited.join(', ')
visited.each do |state|
  puts state 
end

...or loop through and print each state.

Warmup Solution:

# Write a program that asks the user for all U.S. states they have visited
# (followed by a return) 
# Typing "done" should terminate the program. 
# Print all states to the screen.

visited = []
puts "Enter all the states you've been to! Type 'done' when you're finished:"
keep_going = true

while keep_going
  state = gets.chomp.upcase 

  if state.downcase != 'done'
    visited.push(state)
   else
    break
  end
end

puts "You have visited the following states:"
puts visited.join(', ')

# Write a program that prints the lyrics 
# to 99 Bottles of Beer on the Wall

# example output:
# 99 bottles of beer on the wall
# 99 bottles of beer
# Take one down pass it around
# 
# 98 bottles of beer on the wall
# 98 bottles of beer on the wall
# 98 bottles of beer 
# Take one down, pass it around

99 Bottles Program

Write a program that prints the lyrics to 99 Bottles of Beer on the Wall

# N number of bottles
number_of_bottles = 99

until number_of_bottles == 0

# Do something

end

99 Bottles Program

Let's define the number of bottles to start with (99, duh!). Then we'll loop until we're out of beer!

# print 2 lines using number of bottles

# print refrain (doesn’t change)

# print a line using number - 1

99 Bottles Program

Let's outline our solution 

# print 2 lines using number of bottles
puts "#{number_of_bottles} bottles of beer on the wall"
puts "#{number_of_bottles} bottles of beer"

# print refrain (doesn’t change)
puts "Take one down, pass it around\n\n"

#print a line using N -1
puts "#{number_of_bottles - 1} bottles of beer on the wall"

99 Bottles Program

Now print a bunch of strings (with interpolation!)  to sing our song.

number_of_bottles = 99

until number_of_bottles == 0

  # print 2 lines using N
  puts "#{number_of_bottles} bottles of beer on the wall"
  puts "#{number_of_bottles} bottles of beer"

  # print refrain (doesn’t change)
  puts "Take one down, pass it around\n\n"

  #print a line using N -1
  puts "#{number_of_bottles - 1} bottles of beer on the wall"

  number_of_bottles -= 1

end

99 Bottles Program

What happens when we run this code? Infinite loop? This means we need to increment our until loop.

if number_of_bottles > 1
  # print 2 lines using N
  puts "#{number_of_bottles} bottles of beer on the wall"
  puts "#{number_of_bottles} bottles of beer"

  # print refrain (doesn’t change)
  puts "Take one down, pass it around\n\n"

  # print a line using N -1
  puts "#{number_of_bottles - 1} bottles of beer on the wall"
else
  # print 2 lines using N
  puts "1 bottle of beer on the wall"
  puts "1 bottle of beer"

  # print refrain (doesn’t change)
  puts "Take it down, pass it around"

  # print a line using N -1
  puts "No more bottles of beer on the wall!"
end

99 Bottles Program

Lastly, we can create logic to ensure correct grammar when we get down to 1 bottle.

until time == 9:43

  break

end

A few different ways to solve a Ruby problem

5 Questions Problem

  • Ask the user 5 yes or no questions
  • Compare their answer to a list of correct answers
  • Print the number of correct answers

 


# Ask the user 5 yes or no questions 
# Compare their answers to a list of correct answers
# Print the number of correct answers

Ways to approach this

  • Arrays

  • Hashes

  • Methods

Array Approach

questions = [ 'Are narwhals real?', 
              'Is today Halloween?', 
              'Do dogs say meow?', 
              'Does 2+2 = 4?',
              'Is Jaime awesome?']
correct_answers =   ['Y', 'N', 'N', 'Y', 'Y']

Let's create 2 arrays to hold our questions & correct answers

Array Approach

puts "Please answer Y or N to the following questions!"

Let's first prompt the user ...

questions.each do |question|
  puts "Q: #{question}"

  user_answer = gets.chomp.upcase

end

Array Approach

Now we print out each question using a loop and save the user's answer in a variable.

Array Approach

index = 0
score = 0

Let's initialize some variables at the top of our code to keep track of our score and the array index.

Array Approach

questions.each do |question|
  puts "Q: #{question}"

  user_answer = gets.chomp.upcase
  
  if user_answer == correct_answers[index]
   # Do Something
  end

end
    

Let's compare the user's answer against the correct answer using the array index

Array Approach

questions.each do |question|
  puts "Q: #{question}"

  user_answer = gets.chomp.upcase

  if user_answer == correct_answers[index]
    score += 1
  end
  index += 1
end

We increase the score by 1 point each time the answers match. We also  increment the index variable in order to work our way through array of answers

Array Approach

puts "You got #{score}/5 correct answers!"

Now that we have our score let's print it out to let the user know how they did

Array Approach

if user_answer == 'Y' || user_answer == 'N'
    if user_answer == correct_answers[index]
      score += 1
    end
    index += 1
else
  puts "Try again: Y or N?"
end

Let's add some validation to make sure we're only accepting "Y" or "N" answers from the user

Array Approach

questions.each do |question|
  puts "Q: #{question}"

  user_answer = gets.chomp.upcase

  if user_answer == 'Y' || user_answer == 'N'
    if user_answer == correct_answers[index]
      score += 1
    end
    index += 1
  else
    puts "Try again: Y or N?" 
    redo
  end
end

Don't forget "redo" to start the loop over again if their answer was invalid.

Array Approach

questions = [ 'Are narwhals real?', 
              'Is today Halloween?', 
              'Do dogs say meow?', 
              'Does 2+2 = 4?',
              'Is Jaime awesome?']

correct_answers = ['Y', 'N', 'N', 'Y', 'Y']

index = 0
score = 0

puts "Please answer Y or N to the following questions!"

questions.each do |question|
  puts "Q: #{question}"
  user_answer = gets.chomp.upcase

  if user_answer == 'Y' || user_answer == 'N'
    if user_answer == correct_answers[index]
      score += 1
    end
    index += 1
  else
    puts "Try again: Y or N?"
    redo
  end
end

puts "You got #{score}/5 correct answers!"

Hash Approach

Another approach is to set up a hash that holds the questions and correct answers in key value pairs.

questions_answers = {'Are narwhals real?'=> 'Y', 
                     'Is today Halloween?'=> 'N', 
                     'Do dogs say meow?' => 'N',
                     'Does 2+2 = 4?' => 'Y', 
                     'Is Jaime awesome?' => 'Y'}
score = 0

puts "Please answer Y or N to the following questions!"

Hash Approach

Again we prompt the user to answer the question and also initialize a score variable.

Hash Approach

Then we loop over the hash using the key and value, print the question and get the user's answer.

questions_answers.each do |question, correct_answer|
  puts "Q: #{question}"
  user_answer = gets.chomp.upcase
end

Hash Approach

Add in the same validation and scoring we used in the array approach.

if user_answer == 'Y' || user_answer == 'N'
    if user_answer == correct_answer
      score += 1
    end
  else
    puts "Try again: Y or N?"
    redo
  end

Hash Approach

Finally we output the user's score!

puts "You got #{score}/#{questions_answers.count} correct answers!"

Hash Approach

questions_answers = {'Are narwhals real?' => 'Y', 
                     'Is today Halloween?' => 'N', 
                     'Do dogs say meow?' => 'N', 
                     'Does 2+2 = 4?' => 'Y', 
                     'Is Jaime awesome?' => 'Y'}
score = 0

puts "Please answer Y or N to the following questions!"

questions_answers.each do |question, correct_answer|
  puts "Q: #{question}"

  user_answer = gets.chomp.upcase

  if user_answer == 'Y' || user_answer == 'N'
    if user_answer == correct_answer
      score += 1
    end
  else
    puts "Try again: Y or N?"
    redo
  end
end

puts "You got #{score}/#{questions_answers.count} correct answers!"

Making Methods

What if we wanted to break this into methods? We could start by declaring instance variables at the top.

@questions_answers = {'Are narwhals real?' => 'Y', 
                     'Is today Halloween?' => 'N', 
                     'Do dogs say meow?' => 'N', 
                     'Does 2+2 = 4?' => 'Y', 
                     'Is Jaime awesome?' => 'Y'}
@score = 0

Making Methods

Next we can break out the prompt into its own method.

def prompt
  puts "Please answer Y or N to the following questions!"
end

Making Methods

def put_score
 # Do something
end

We can also break out a method to print the score.

Making Methods

def put_score(s,q_a)
  puts "You got #{s}/#{q_a.count} correct answers!"
end

Don't forget to pass in local score and question/answer variables!

Making Methods

def ask_questions 
  @questions_answers.each do |question, correct_answer|
    puts "Q: #{question}"

    user_answer = gets.chomp.upcase

    if user_answer == 'Y' || user_answer == 'N'
       if user_answer == correct_answer
         @score += 1
      end
    else
      puts "Try again: Y or N?"
      redo
    end
  end
end

Now let's put the bulk of our code in it's own method. Remember we're using instance variables.

Making Methods

Add a main method to call the prompt, ask_questions and put_score methods. Then call "main."

def main
  prompt
  ask_questions
  put_score(@score)
end

main
@questions_answers = {'Are narwhals real?' => 'Y', 
                      'Is today Halloween?' => 'N', 
                      'Do dogs say meow?' => 'N', 
                      'Does 2+2 = 4?' => 'Y', 
                      'Is Jaime awesome?' => 'Y'}
@score = 0

def prompt
  puts "Please answer Y or N to the following questions!"
end

def ask_questions 
  @questions_answers.each do |question, correct_answer|
    puts "Q: #{question}"

    user_answer = gets.chomp.upcase

    if user_answer == 'Y' || user_answer == 'N'
       if user_answer == correct_answer
         @score += 1
      end
    else
      puts "Try again: Y or N?"
      redo
    end
  end
end

def put_score(s,q_a)
  puts "You got #{s}/#{q_a.count} correct answers!"
end

def main
  prompt
  ask_questions
  put_score(@score,@questions_answers) 
end

main

Method Solution

Homework: The Bank

Made with Slides.com