Topics Covered: Defining methods, classes, and modules; using methods, classes, and modules effectively.
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')
Engineer
a subclass or a superclass?Engineer.go_to_work
do? Why?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?elon_musk
? Choose all that apply:
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")
james.is_a?(Person)
james.is_a?(Engineer)
james.instance_of?(Person)
james.instance_of?(Engineer)
frank.respond_to?(:name)
frank.respond_to?(:go_to_work)
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!
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.
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.
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!!!")
# => []
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.
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.
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:
@items
. @items
will be an Array
, that holds Objects of the Item
class. That is, the signature of @items
is Array<Item>
.@items
will start (be initialized) as an empty array.Cart
will have a method add
that adds Item
s to its @items
array.Cart
has a method remove
that will remove all instances of an item from its cart. That is, if @items
is [milk, milk, eggs]
and I run cart.remove(milk)
, then @items
should be [eggs]
.total_price
returns a float
of the total price of all items in the cart.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.