Homework for 4B

Review

Topics Covered: Defining methods, classes, and modules; using methods, classes, and modules effectively.


Exercises

E1: A Career for the People

We're going to review what we learned in class about classes. Check out this code, and write down the answers to the questions below, in a file called people_quiz.rb. Have a teacher check them for you.

class Person
  def initialize(name)
    @name = name # Line 3
  end

  def name
    @name
  end
end

class Engineer < Person
  def initialize(name, field)
    @name = name
    @field = field
  end

  def go_to_work
    puts "Going to work as an engineer in #{field}..."
  end
end

elon_musk = Engineer.new('Elon Musk', 'space travel')
  1. Why is line 3 necessary? What happens without it?
  2. Is Engineer a subclass or a superclass?
  3. What will running Engineer.go_to_work do? Why?
  4. What will running elon_musk.field do? Why? If you think it's broken, how can you fix it? If you think it works, what does it return?
  5. What is elon_musk? Choose all that apply:
    • A class
    • A method
    • An instance
    • An object
    • A variable

Classes, Objects and Instances! Oh, my!

Revisiting the Person and Engineer example from above, we can test our understanding of the instance_of?, is_a? and respond_to? methods. Write down whether the following evaluate to true or false, and then write a sentence explaining the difference between instance_of? and is_a?.

james = Engineer.new("James", "robotics")
frank = Person.new("frank")
  1. james.is_a?(Person)
  2. james.is_a?(Engineer)
  3. james.instance_of?(Person)
  4. james.instance_of?(Engineer)
  5. frank.respond_to?(:name)
  6. frank.respond_to?(:go_to_work)

E2: Finding a Needle in a Hashstack

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!

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!!!")
# => []

Projects

Ruby: Fueling Consumerism

Now that you have a beautiful presence on the Internet, we're going to work on bringing one of the most notable American vices to South Africa: consumerism. Over the next two days, you'll use your new knowledge of Ruby—with all its Hashes and Classes—to build a Shopping Cart and some Shoppers. It will closely model something you might build in a Rails application some day.

The Goods

To start, create a shopping_cart folder in your projects directory. We'll start with an Item class, so in shopping_cart, create a file called item.rb. Item is the simplest: it just has a name and a price. Copy the below code into it:

# item.rb

class Item
  # @param{string} name The item's name
  # @param{float} price The item's price
  def initialize(name, price)
  end

  # Accessor methods

  # Returns name
  def name
  end

  # Returns price
  def price
  end
end

This code doesn't do anything yet, but should be simple to fill out. Go ahead and do so, just like we did in lecture.

The Vehicle

Next we're going to build a Cart class that will hold all of the items, as well as how many items there are. Put this in a new file, cart.rb. This cart will closely resemble Lesson 3A, Exercise 5, so feel free to borrow and modify code from there. To start, here's a template:

# cart.rb

class Cart
  def initialize
  end

  # @return{Array<Item>}
  #   The items and their quantities in the cart, keyed by item name.
  def items
  end

  # @return{float} The total price of all the goods in the cart.
  def total_price
  end

  # @param{Item} item The item to add.
  def add(item)
  end

  # @param{Item} item The item to remove.
  def remove(item)
  end
end

The exact specification is as follows:

Like in the slides, let's create a main.rb that we'll use to test. This is a sample of how you might test it:

# main.rb

require_relative 'item'
require_relative 'cart'
milk = Item.new("milk", 1.20)
eggs = Item.new("eggs", 1.30)
cart = Cart.new
cart.add(milk)
cart.add(milk)
cart.add(eggs)
p cart.items
# Console output might look like (but less well formatted, and the long 0x00... numbers might be different):

[
  #<Item:0x00000103083438 @name="milk", @price=1.2>,
  #<Item:0x00000103083438 @name="milk", @price=1.2>,
  #<Item:0x000001012407f0 @name="eggs", @price=1.3>
]
p cart.total_price
# 3.7
cart.remove(milk)
p cart.total_price
# 1.3

After you think you have a working answer, download the test file from here and put it in your shopping_cart directory (just do File -> Save from Chrome). Run it with ruby shopping_cart_test_1.rb. If you're failing any tests, make them pass.