Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Episode1 Homework #2

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions REV_COMMENTS
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
I am learning how to use classes in Ruby and now will get a chance to learn some of the "why" behind class design with these questions. This is exactly why I signed up. Thank you.

Questions:

1. Class Org Philosophy

In the Animal module, feed and eat are very similar. I did it this way because the instructions call for me to feed the panda via "panda.feed(food)".

I think if I was going free form I would do something more like:

zookeeper = Zookeeper.new
zookeeper.feed(panda)

and resolve it in the Zookeeper#feed method

or something like:

food = @foodbarge.food_for(panda)
zookeeper = Zookeeper.new
zookeeper.feed(panda, food)

I'm not sure which one would be the best practice, or if there's a reason why panda.feed(food) makes the most sense.

2. Lions can't just eat one.

The way I have it setup, a lion always has to eat a Wildebeest and a Zeebra. We can't feed him 4 Wilde's and 2 Zeebra's. Maybe this is just outside of scope for the exercise, or maybe I've done it wrong...

3. Defining setter/getter at the module level.

This worked:

Module Animal
attr_reader :meals

Is it a good idea Ruby wise? The alternative was to make each Lion, Panda, etc class have this definition.

4. Equality Override Method ain't DRY

I suspect this could be refactored:

class Taco
def ==(other)
other.is_a? Taco
end
end

class Bacon
def ==(other)
other.is_a? Bacon
end
end

class Bamboo
def ==(other)
other.is_a? Bamboo
end
end

Initially, I was going to:

1. Create a Food module.

2. Paste the method "up a level" from Bamboo to Food module.

3. Include Food in each Taco, Bacon, Bamboo type class.

This didn't pan out because Bamboo is hard coded in the Bamboo class. I considered replacing "Bamboo" with other.class but then I'm defining other, which has a class and then asking if it matches itself. At that point, I can shorten the method by just saying 1=1...how do I "get at it"?

98 changes: 87 additions & 11 deletions zoo.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#Zoo

module Animal

attr_reader :meals

def eat(food)
@meals ||= 0
if likes?(food)
Expand All @@ -12,8 +13,26 @@ def eat(food)
end
end

def likes?(food)
acceptable_food.include?(food.to_sym)
def feed(food)
@meals ||= 0
food.each do |f|
if likes?(f)
@meals += 1
true
else
false
end
end
end

def likes?(food_class)
like = false
acceptable_food.each do |food|
if food_class == food
like = true
end
end
return like
end

def acceptable_food
Expand All @@ -26,38 +45,95 @@ def full?

end

class Taco
def ==(other)
other.is_a? Taco
end
end

class Bacon
def ==(other)
other.is_a? Bacon
end
end

class Bamboo
def ==(other)
other.is_a? Bamboo
end
end

class Grasshopper
def ==(other)
other.is_a? Grasshopper
end
end

class Wildebeest
def ==(other)
other.is_a? Wildebeest
end
end

class Zebra
def ==(other)
other.is_a? Zebra
end
end

class Salad
def ==(other)
other.is_a? Salad
end
end

class Human
include Animal

def acceptable_food
[Bacon.new, Taco.new]
end

end

class Panda
include Animal

def acceptable_food
[:bamboo]
[Bamboo.new]
end

def full?
@meals > 30
end

end

class Lion
include Animal

def acceptable_food
[:wildebeests, :zeebras]
[Wildebeest.new, Zebra.new]
end

def full?
@meals > 10
end

end

class Zookeeper
def feed(args={})
food = args.fetch(:food)
panda = args.fetch(:to)
panda.eat(food)
animal = args.fetch(:to)
animal.eat(food)
end

end


class FoodBarge

def food_for(animal)
animal.acceptable_food
end

end
122 changes: 99 additions & 23 deletions zoo_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,73 +5,149 @@
describe Panda do

it "should like bamboo" do
Panda.new.likes?(:bamboo).should eq(true)
Panda.new.likes?(Bamboo.new).should eq(true)
end

it "should like bamboo as a string" do
Panda.new.likes?("bamboo").should eq(true)
end

it "should not like grasshoppers" do
Panda.new.likes?(:grasshoppers).should eq(false)
it "should not like grasshopper" do
Panda.new.likes?(Grasshopper.new).should eq(false)
end

it "should be able to eat the food" do
Panda.new.eat(:bamboo).should be_true
Panda.new.eat(Bamboo.new).should be_true
end

it "should be full after eating 30 bamboo" do
panda = Panda.new
31.times do
panda.eat(:bamboo)
panda.eat(Bamboo.new)
end
panda.should be_full
end

it "should not be full after 1" do
panda = Panda.new
panda.eat(:bamboo)
panda.eat(Bamboo.new)
panda.should_not be_full
end
end

describe Lion do
it "should like wildebeests" do
Lion.new.likes?(:wildebeests).should eq(true)
it "should like wildebeest" do
Lion.new.likes?(Wildebeest.new).should eq(true)
end

it "should like zeebras" do
Lion.new.likes?(:zeebras).should eq(true)
it "should like zebras" do
Lion.new.likes?(Zebra.new).should eq(true)
end

it "should not like salad" do
Lion.new.likes?(:salad).should eq(false)
Lion.new.likes?(Salad.new).should eq(false)
end

it "should take 11 meals to be full" do
it "should not be full after eating only 1 zebra" do
lion = Lion.new
lion.eat(:zeebras)
lion.eat(Zebra.new)
lion.should_not be_full
end

it "should take 11 meals to be full" do
lion = Lion.new
11.times do
lion.eat(:zeebras)
lion.eat(Zebra.new)
end
lion.should be_full
end
end

describe Human do
it "should like bacon" do
Human.new.likes?(Bacon.new).should eq(true)
end

it "should like tacos" do
Human.new.likes?(Taco.new).should eq(true)
end

it "should not like bamboo" do
Human.new.likes?(Bamboo.new).should eq(false)
end
end

describe Taco do
it "should be able to compare Taco class equality" do
a = Taco.new
(Taco.new == a).should eq(true)
end
end

describe Bacon do
it "should be able to compare Bacon class equality" do
a = Bacon.new
(Bacon.new == a).should eq(true)
end
end

describe Bamboo do
it "should be able to compare Bamboo class equality" do
a = Bamboo.new
(Bamboo.new == a).should eq(true)
end
end

describe Salad do
it "should be able to compare Salad class equality" do
a = Salad.new
(Salad.new == a).should eq(true)
end
end

describe Zookeeper do
it "should be able to feed bamboo to the pandas" do
panda = Panda.new
panda.should_receive(:eat).with(:bamboo)
Zookeeper.new.feed(food: :bamboo, to: panda)
bamboo = Bamboo.new
panda.should_receive(:eat).with(bamboo)
Zookeeper.new.feed(:food => bamboo, :to => panda)
end

it "should be able to feed zeebras to the lions" do
it "should be able to feed zebras to the lions" do
lion = Lion.new
lion.should_receive(:eat).with(:zeebras)
Zookeeper.new.feed(food: :zeebras, to: lion)
zebra = Zebra.new
lion.should_receive(:eat).with(zebra)
Zookeeper.new.feed(:food => zebra, :to => lion)
end
end

describe FoodBarge do
it "should return wildebeest and zebra true when animal is lion" do
foodbarge = FoodBarge.new
lion = Lion.new
foodbarge.food_for(lion).should eq([Wildebeest.new, Zebra.new])
end

it "should return bamboo true when animal is panda" do
foodbarge = FoodBarge.new
panda = Panda.new
foodbarge.food_for(panda).should eq([Bamboo.new])
end

it "should make the panda full after feeding 31 bamboo" do
@foodbarge = FoodBarge.new
panda = Panda.new
food = @foodbarge.food_for(panda)
31.times do
panda.feed(food)
end
panda.full?.should eq(true)
end

it "should not make the lion full after eating 4 Wildebeest and 4 zebra" do
@foodbarge = FoodBarge.new
lion = Lion.new
food = @foodbarge.food_for(lion)
4.times do
lion.feed(food)
end
lion.full?.should eq(false)
end

end