Homework for 4A

Review

Topics Covered: collections, arrays, hashes, symbols, enumeration, iteration, loops, blocks

Exercises

Note: All exercises must live inside of your session0202_exercises/firstname_lastname/d4 folder

While inside of your session0202_exercises directory, you can git add . then git commit -m "Helpful commit message here" and git push origin master to submit your homework to GitHub. (Don't forget to use git status along the way to check the state of your files in git)

E1: The Road Not Taken

Difficulty: Easy

Create a file called reverse.rb. Write a method called reverse that takes an array as input, and returns the array in reverse. Do not use .reverse on the array! Your file should look like the one below, but with the method filled in.

def reverse(array)
  # TODO: YOUR CODE HERE

end

random_objects = ["apples", 4, "bananas", "kiwis", "pears"]
puts reverse(fruits)

When you run the program on the command line, you should get the following output:

$ ruby reverse.rb
pears
kiwis
bananas
4
apples

FOOD FOR THOUGHT: What would've happened if we had print reverse(fruits) instead? Does it change what appears on the terminal? Does it change what the return value of reverse is? Discuss with a friend if you are unsure.

E2: Custom FizzBuzz

Difficulty: Easy

Create a file called fizzbuzz.rb. Write a method called fizzbuzz that takes an integer max_val as input, and prints the numbers from 1 to max_val, but for each multiple of 3, prints "fizz", each multiple of 5 prints "buzz", and each multiple of 15 prints "fizzbuzz" instead.

HINT: the modulo operator returns the remainder when the first input is divided by the second. That is, 10 modulo 4 would return 2. A quick way to check if a number is divisible by another is to see if their modulo is 0. In ruby, the % symbol is the modulo operator, that is 10 % 4 == 2.

def fizzbuzz(max_val)
  # TODO: YOUR CODE HERE

end

fizzbuzz(100)
$ ruby fizzbuzz.rb
1
2
fizz
4
buzz
...
13
14
fizzbuzz
16
...

BONUS QUESTION: What's the return value of this method?

E3: Google Map

Difficulty: Medium

Translate the following code to use map.

# map.rb

result = []
engines = ["Google", "Bing", "Ask Jeeves"]
engines.each do |e|
  if e == "Google"
    result.push("OK")
  elsif e == "Bing"
    result.push("Bad!")
  else
    result.push("What is that?")
  end
end

result
# => ["OK", "Bad!", "What is that?"]

What is the return value of map? What is the return value of each?

E4: Hashing It Out

Difficulty: Medium

While we've primarily seen examples of hashes mapping strings to integers or vice versa, the values can actually be anything (like array, or even other hashes).

Create a new file recipes.rb. Create a hash assigned to the variable dishes, that maps a dish name (i.e. "Hash browns") to a list of necessary ingredients (i.e. "Potatoes", "Butter", "...is there anything else?"). Add at least 3 dishes. Each dish should have at least 3 ingredients.

Hash on Hash on Hash

Difficulty: Medium-Hard

Create another hash, and assign it to the variable recipes. This time, map each dish name to another hash. That hash should have keys :description (which maps to a String), :ingredients (which maps to an array of Strings, like above, and :steps (which maps to an array of Strings that, you guessed it, tell you how to make the dish).

If you finish early, cook one of those dishes for your TA.

In code, formatting is important. We want our code to not only be readable to computers, but also to humans! If you're making a nested object, use a clear structure. In general, Ruby uses 2 space tabs (1 tab = 2 spaces).
hash = {
  :a => {
    :b => ["c", "d"]
  },
  :e => "f"
}

E5: Finding a Needle in a Hashstack

Difficulty: Medium-Hard

One of the best uses of a computer is to find things—meaning information or other data. Facebook finds what your friends are doing, Buzzfeed finds things you kind of care about, and even Bing finds things sometimes, too. For this exercise, you're going to write your own code that finds things. Note: if you're wondering how your methods should work in certain cases, check out the example tests in the code section below. Writing examples which make it clear how you want your method to work before implementing it is a great way to organize your thoughts!

Create a new file called finding_things.rb.

Thing to find = letter in string

Write a method index_of that takes two parameters, a string and a letter. Return the index of the first time the letter occurs in that string, or -1 if it doesn't occur.

Thing to find = item in array

Write a method find_by_name, which takes an array of hashes, each of which has the property :name, and a string and finds the first one that has that name.

Thing to find = items in array

Write a second, very similar method filter_by_name, which returns and array with all the items with the given name. Note that that method should always return an array, even if only one item is found.

# finding_things.rb

# Your code here

index_of("abcdefghijklmnop", "m")
# => 12
index_of("abcdefghijklmnop", "z")
# => -1

people = [
  {
    :id => 1,
    :name => "bru"
  },
  {
    :id => 2,
    :name => "ski"
  },
  {
    :id => 3,
    :name => "brunette"
  },
  {
    :id => 4,
    :name => "ski"
  }
]
find_by_name(people, "ski")
# => {:id=>2,:name=>"ski"}
find_by_name(people, "kitten!")
# => nil
filter_by_name(people, "ski")
# => [{:id=>2,:name=>"ski"}, {:id=>4,:name=>"ski"}]
filter_by_name(people, "bru")
# => [{:id=>1,:name=>"bru"}] (Note this is still an array)
filter_by_name(people, "puppy!!!")
# => []