From afb060d3d18a4a00bda0037f8bc2b1947258dc7c Mon Sep 17 00:00:00 2001 From: Johnny Goodman Date: Sat, 28 Apr 2012 06:42:03 -0500 Subject: [PATCH 1/6] Feature: Added a human who likes bacon and tacos but not bamboo --- zoo.rb | 10 +++++++++- zoo_spec.rb | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/zoo.rb b/zoo.rb index 8f5eea5..fb555f7 100644 --- a/zoo.rb +++ b/zoo.rb @@ -1,4 +1,4 @@ -#Zoo + #Zoo module Animal @@ -52,6 +52,14 @@ def full? end end +class Human + include Animal + + def acceptable_food + [:bacon, :tacos] + end +end + class Zookeeper def feed(args={}) food = args.fetch(:food) diff --git a/zoo_spec.rb b/zoo_spec.rb index 4943c90..90b003a 100644 --- a/zoo_spec.rb +++ b/zoo_spec.rb @@ -62,6 +62,20 @@ end end +describe Human do + it "should like bacon" do + Human.new.likes?(:bacon).should eq(true) + end + + it "should like tacos" do + Human.new.likes?(:tacos).should eq(true) + end + + it "should not like bamboo" do + Human.new.likes?(:bamboo).should eq(false) + end +end + describe Zookeeper do it "should be able to feed bamboo to the pandas" do panda = Panda.new From 7e01109834f3e8ae3cb2efadf120be61b50e9d34 Mon Sep 17 00:00:00 2001 From: Johnny Goodman Date: Sat, 28 Apr 2012 08:38:30 -0500 Subject: [PATCH 2/6] Extra Credit Feature 1: Extracted Food into a class, rather than a symbol --- zoo.rb | 42 ++++++++++++++++++++++++++++-------------- zoo_spec.rb | 48 ++++++++++++++++++++++++++++-------------------- 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/zoo.rb b/zoo.rb index fb555f7..5356a9f 100644 --- a/zoo.rb +++ b/zoo.rb @@ -1,4 +1,4 @@ - #Zoo +#Zoo module Animal @@ -13,7 +13,7 @@ def eat(food) end def likes?(food) - acceptable_food.include?(food.to_sym) + acceptable_food.include?(food.to_s) end def acceptable_food @@ -26,38 +26,52 @@ def full? end +class Food + attr_accessor :name + + def initialize(name) + @name = name + end + + def to_s + "#{@name}" + end + +end + +class Human + include Animal + + def acceptable_food + ["bacon", "tacos"] + end + +end class Panda include Animal def acceptable_food - [:bamboo] + ["bamboo"] end def full? @meals > 30 end - + end class Lion include Animal def acceptable_food - [:wildebeests, :zeebras] + ["wildebeests", "zeebras"] end def full? @meals > 10 end -end - -class Human - include Animal - - def acceptable_food - [:bacon, :tacos] - end + end class Zookeeper @@ -66,6 +80,6 @@ def feed(args={}) panda = args.fetch(:to) panda.eat(food) end - + end diff --git a/zoo_spec.rb b/zoo_spec.rb index 90b003a..ca349ad 100644 --- a/zoo_spec.rb +++ b/zoo_spec.rb @@ -5,58 +5,58 @@ describe Panda do it "should like bamboo" do - Panda.new.likes?(:bamboo).should eq(true) + Panda.new.likes?(Food.new("bamboo")).should eq(true) end - it "should like bamboo as a string" do - Panda.new.likes?("bamboo").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) + Panda.new.likes?(Food.new("grasshoppers")).should eq(false) end it "should be able to eat the food" do - Panda.new.eat(:bamboo).should be_true + Panda.new.eat(Food.new("bamboo")).should be_true end it "should be full after eating 30 bamboo" do panda = Panda.new 31.times do - panda.eat(:bamboo) + panda.eat(Food.new("bamboo")) end panda.should be_full end it "should not be full after 1" do panda = Panda.new - panda.eat(:bamboo) + panda.eat(Food.new("bamboo")) panda.should_not be_full end end describe Lion do it "should like wildebeests" do - Lion.new.likes?(:wildebeests).should eq(true) + Lion.new.likes?(Food.new("wildebeests")).should eq(true) end it "should like zeebras" do - Lion.new.likes?(:zeebras).should eq(true) + Lion.new.likes?(Food.new("zeebras")).should eq(true) end it "should not like salad" do - Lion.new.likes?(:salad).should eq(false) + Lion.new.likes?(Food.new("salad")).should eq(false) end it "should take 11 meals to be full" do lion = Lion.new - lion.eat(:zeebras) + lion.eat(Food.new("zeebras")) 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(Food.new("zeebras")) end lion.should be_full end @@ -64,28 +64,36 @@ describe Human do it "should like bacon" do - Human.new.likes?(:bacon).should eq(true) + Human.new.likes?(Food.new("bacon")).should eq(true) end it "should like tacos" do - Human.new.likes?(:tacos).should eq(true) + Human.new.likes?(Food.new("tacos")).should eq(true) end it "should not like bamboo" do - Human.new.likes?(:bamboo).should eq(false) + Human.new.likes?(Food.new("bamboo")).should eq(false) 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 = Food.new("bamboo") + 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 lion = Lion.new - lion.should_receive(:eat).with(:zeebras) - Zookeeper.new.feed(food: :zeebras, to: lion) + zeebras = Food.new("zeebras") + lion.should_receive(:eat).with(zeebras) + Zookeeper.new.feed(food: zeebras, to: lion) end end + +describe Food do + it "should be able to be named bacon" do + Food.new('bacon').to_s.should eq("bacon") + end +end \ No newline at end of file From cc1478f2e2c7b5596d5d1d5c9c8f7e963661a885 Mon Sep 17 00:00:00 2001 From: Johnny Goodman Date: Tue, 1 May 2012 09:10:49 -0500 Subject: [PATCH 3/6] Feature: Extra Credit 1 Solved using Bacon.new style --- zoo.rb | 77 +++++++++++++++++++++++++++++++++++++++++++---------- zoo_spec.rb | 70 +++++++++++++++++++++++++++++------------------- 2 files changed, 105 insertions(+), 42 deletions(-) diff --git a/zoo.rb b/zoo.rb index 5356a9f..6feda8f 100644 --- a/zoo.rb +++ b/zoo.rb @@ -12,8 +12,14 @@ def eat(food) end end - def likes?(food) - acceptable_food.include?(food.to_s) + 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 @@ -26,24 +32,67 @@ def full? end -class Food - attr_accessor :name - - def initialize(name) - @name = name +class Taco + def ==(other) + other.is_a? Taco end - - def to_s - "#{@name}" +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 Zeebra + def ==(other) + other.is_a? Zeebra + end +end + +class Salad + def ==(other) + other.is_a? Salad + end +end + +# +# class Food +# attr_accessor :name +# +# def initialize(name) +# @name = name +# end +# +# def to_s +# "#{@name}" +# end +# +# end + class Human include Animal def acceptable_food - ["bacon", "tacos"] + [Bacon.new, Taco.new] end end @@ -52,7 +101,7 @@ class Panda include Animal def acceptable_food - ["bamboo"] + [Bamboo.new] end def full? @@ -65,7 +114,7 @@ class Lion include Animal def acceptable_food - ["wildebeests", "zeebras"] + [Wildebeest.new, Zeebra.new] end def full? diff --git a/zoo_spec.rb b/zoo_spec.rb index ca349ad..4f70a54 100644 --- a/zoo_spec.rb +++ b/zoo_spec.rb @@ -5,95 +5,109 @@ describe Panda do it "should like bamboo" do - Panda.new.likes?(Food.new("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?(Food.new("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(Food.new("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(Food.new("bamboo")) + panda.eat(Bamboo.new) end panda.should be_full end it "should not be full after 1" do panda = Panda.new - panda.eat(Food.new("bamboo")) + panda.eat(Bamboo.new) panda.should_not be_full end end describe Lion do - it "should like wildebeests" do - Lion.new.likes?(Food.new("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?(Food.new("zeebras")).should eq(true) + Lion.new.likes?(Zeebra.new).should eq(true) end it "should not like salad" do - Lion.new.likes?(Food.new("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 Zeebra" do lion = Lion.new - lion.eat(Food.new("zeebras")) + lion.eat(Zeebra.new) lion.should_not be_full end + it "should take 11 meals to be full" do lion = Lion.new 11.times do - lion.eat(Food.new("zeebras")) + lion.eat(Zeebra.new) end lion.should be_full end end describe Human do + it "should like bacon" do - Human.new.likes?(Food.new("bacon")).should eq(true) + Human.new.likes?(Bacon.new).should eq(true) end it "should like tacos" do - Human.new.likes?(Food.new("tacos")).should eq(true) + Human.new.likes?(Taco.new).should eq(true) end it "should not like bamboo" do - Human.new.likes?(Food.new("bamboo")).should eq(false) + 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 Zookeeper do it "should be able to feed bamboo to the pandas" do panda = Panda.new - bamboo = Food.new("bamboo") + 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 lion = Lion.new - zeebras = Food.new("zeebras") + zeebras = Zeebra.new lion.should_receive(:eat).with(zeebras) Zookeeper.new.feed(food: zeebras, to: lion) end end - -describe Food do - it "should be able to be named bacon" do - Food.new('bacon').to_s.should eq("bacon") - end -end \ No newline at end of file From d49d5118216130e8dfd1919d680aed6ab5f0531e Mon Sep 17 00:00:00 2001 From: Johnny Goodman Date: Tue, 1 May 2012 10:43:00 -0500 Subject: [PATCH 4/6] Updated zoo_spec to support 1.8.7 hash rocket syntax, out of fear that rvm use 1.9.2 would break gems, as it has in other directories I work in. The cost of ignorance... --- zoo_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zoo_spec.rb b/zoo_spec.rb index 4f70a54..12d7156 100644 --- a/zoo_spec.rb +++ b/zoo_spec.rb @@ -101,13 +101,13 @@ panda = Panda.new bamboo = Bamboo.new panda.should_receive(:eat).with(bamboo) - Zookeeper.new.feed(food: bamboo, to: panda) + Zookeeper.new.feed(:food => bamboo, :to => panda) end it "should be able to feed zeebras to the lions" do lion = Lion.new zeebras = Zeebra.new lion.should_receive(:eat).with(zeebras) - Zookeeper.new.feed(food: zeebras, to: lion) + Zookeeper.new.feed(:food => zeebras, :to => lion) end end From 071dd0a890de303249f93b2d25937ac8a47c5718 Mon Sep 17 00:00:00 2001 From: Johnny Goodman Date: Tue, 1 May 2012 14:10:01 -0500 Subject: [PATCH 5/6] Feature: FoodBarge class allows all foods for a given animal to be available for eating or feeding --- zoo.rb | 39 ++++++++++++++++++++++----------------- zoo_spec.rb | 42 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 18 deletions(-) diff --git a/zoo.rb b/zoo.rb index 6feda8f..b19838d 100644 --- a/zoo.rb +++ b/zoo.rb @@ -1,7 +1,8 @@ #Zoo module Animal - + attr_reader :meals + def eat(food) @meals ||= 0 if likes?(food) @@ -12,6 +13,18 @@ def eat(food) end end + 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| @@ -74,20 +87,6 @@ def ==(other) end end -# -# class Food -# attr_accessor :name -# -# def initialize(name) -# @name = name -# end -# -# def to_s -# "#{@name}" -# end -# -# end - class Human include Animal @@ -103,7 +102,7 @@ class Panda def acceptable_food [Bamboo.new] end - + def full? @meals > 30 end @@ -129,6 +128,12 @@ def feed(args={}) panda = args.fetch(:to) panda.eat(food) end - end + +class FoodBarge + + def food_for(animal) + animal.acceptable_food + end +end diff --git a/zoo_spec.rb b/zoo_spec.rb index 12d7156..0d9a7e7 100644 --- a/zoo_spec.rb +++ b/zoo_spec.rb @@ -60,7 +60,6 @@ end describe Human do - it "should like bacon" do Human.new.likes?(Bacon.new).should eq(true) end @@ -95,6 +94,12 @@ 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 @@ -111,3 +116,38 @@ Zookeeper.new.feed(:food => zeebras, :to => lion) end end + +describe FoodBarge do + it "should return wildebeest and zeebra true when animal is lion" do + foodbarge = FoodBarge.new + lion = Lion.new + foodbarge.food_for(lion).should eq([Wildebeest.new, Zeebra.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 Zeebra" 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 \ No newline at end of file From 91a64ccb0c1e65a246727fb1432d31fb1549adeb Mon Sep 17 00:00:00 2001 From: Johnny Goodman Date: Tue, 1 May 2012 14:33:15 -0500 Subject: [PATCH 6/6] Per DuckDuckGo, Zeebra is a DJ and Zebra is an animal. Updated to Zebra. Make peace, don't eat DJs. --- REV_COMMENTS | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ zoo.rb | 12 +++++----- zoo_spec.rb | 24 +++++++++---------- 3 files changed, 86 insertions(+), 18 deletions(-) create mode 100644 REV_COMMENTS diff --git a/REV_COMMENTS b/REV_COMMENTS new file mode 100644 index 0000000..41c7354 --- /dev/null +++ b/REV_COMMENTS @@ -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"? + diff --git a/zoo.rb b/zoo.rb index b19838d..1daf453 100644 --- a/zoo.rb +++ b/zoo.rb @@ -75,9 +75,9 @@ def ==(other) end end -class Zeebra +class Zebra def ==(other) - other.is_a? Zeebra + other.is_a? Zebra end end @@ -113,7 +113,7 @@ class Lion include Animal def acceptable_food - [Wildebeest.new, Zeebra.new] + [Wildebeest.new, Zebra.new] end def full? @@ -125,8 +125,8 @@ def full? 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 @@ -136,4 +136,4 @@ def food_for(animal) animal.acceptable_food end -end +end \ No newline at end of file diff --git a/zoo_spec.rb b/zoo_spec.rb index 0d9a7e7..712bb92 100644 --- a/zoo_spec.rb +++ b/zoo_spec.rb @@ -36,24 +36,24 @@ Lion.new.likes?(Wildebeest.new).should eq(true) end - it "should like zeebras" do - Lion.new.likes?(Zeebra.new).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.new).should eq(false) end - it "should not be full after eating only 1 Zeebra" do + it "should not be full after eating only 1 zebra" do lion = Lion.new - lion.eat(Zeebra.new) + 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(Zeebra.new) + lion.eat(Zebra.new) end lion.should be_full end @@ -109,19 +109,19 @@ 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 - zeebras = Zeebra.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 zeebra true when animal is lion" 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, Zeebra.new]) + foodbarge.food_for(lion).should eq([Wildebeest.new, Zebra.new]) end it "should return bamboo true when animal is panda" do @@ -140,7 +140,7 @@ panda.full?.should eq(true) end - it "should not make the lion full after eating 4 Wildebeest and 4 Zeebra" do + 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)