From ea06722c281a15771b6225c4e23e37926279899d Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Sun, 11 Jan 2015 22:54:28 -0500 Subject: [PATCH 01/59] Add Blackjack class, Deck class and Dealer class. Add initialize method to each class. --- code/blackjack.rb | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/code/blackjack.rb b/code/blackjack.rb index 61e088d..ea50e61 100644 --- a/code/blackjack.rb +++ b/code/blackjack.rb @@ -2,6 +2,40 @@ class Blackjack attr_accessor :deck #this means we can interact with the instance variable @deck # and we can pretend it is a method: Blackjack.new.deck def initialize #this runs when Blackjack.new is called - @deck = {{ }} + @deck = Deck.new + end + + def hand + @hand = hand + end +end + +class Deck + attr_accessor :cards + def initialize + @cards = [] + + values = [1..10,10,10,10,11] + + 4.times do + values.each do |value| + @cards << value + end + end + end + + def shuffled_cards + @cards = @cards.shuffle! + end + + def hand + #card = cards.pop + end +end + +class Dealer + #attr_accessor + def initialize + end end \ No newline at end of file From 8275d34983e2741932bae475e878fae00caee915 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Sun, 11 Jan 2015 23:17:59 -0500 Subject: [PATCH 02/59] Edit values for cards. Replace range 1..10 with 1,2,3,4,5,6,7,8,9,10. --- code/blackjack.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/blackjack.rb b/code/blackjack.rb index ea50e61..1e23141 100644 --- a/code/blackjack.rb +++ b/code/blackjack.rb @@ -5,9 +5,9 @@ def initialize #this runs when Blackjack.new is called @deck = Deck.new end - def hand - @hand = hand - end + # def hand + # @hand = hand + # end end class Deck @@ -15,7 +15,7 @@ class Deck def initialize @cards = [] - values = [1..10,10,10,10,11] + values = [1,2,3,4,5,6,7,8,9,10,10,10,10,11] 4.times do values.each do |value| From 23d42b66d12feb0da02742877d9cbcd1ed619901 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Sun, 11 Jan 2015 23:19:16 -0500 Subject: [PATCH 03/59] Remove 1 from values. No 1 card in deck. --- code/blackjack.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/blackjack.rb b/code/blackjack.rb index 1e23141..86a0f11 100644 --- a/code/blackjack.rb +++ b/code/blackjack.rb @@ -15,7 +15,7 @@ class Deck def initialize @cards = [] - values = [1,2,3,4,5,6,7,8,9,10,10,10,10,11] + values = [2,3,4,5,6,7,8,9,10,10,10,10,11] 4.times do values.each do |value| From 045fbc010e75c2c834c5943c9e1a4adfd0cfb202 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Sun, 11 Jan 2015 23:23:34 -0500 Subject: [PATCH 04/59] Comment out all tests except for setup in order to locate errors. --- code/blackjack_test.rb | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/code/blackjack_test.rb b/code/blackjack_test.rb index 5c68dba..95f48ce 100644 --- a/code/blackjack_test.rb +++ b/code/blackjack_test.rb @@ -16,28 +16,35 @@ class TestBlackjack < MiniTest::Unit::TestCase #if a player's hand is less than 21, the player is given the option to hit or stay #if a player stays, the dealer moves to the next player. #if a player hits, the dealer deals one random card to the player. - #if hand total equals 21, the dealer moves to next player - #if hand total is greater than 21, the player busts - #if hand total is less than 21, the player is given the option to hit or stay.(loop) - #if a player's hand equals 21, the dealer moves to the next player and cards are analyzed. + #if new hand total equals 21, the dealer moves to next player + #if new hand total is greater than 21, the player busts + #if new hand total is less than 21, the player is given the option to hit or stay.(loop) + #if a player's hand equals 21, player has Blackjack and the dealer moves to the next player. #the game ends when + #nouns: deck, dealer, player, hand, + #verbs: deal, hit, stay + def setup #this runs before each test @blackjack = Blackjack.new end - def test_blackjack_exists - assert Blackjack.new - end + #def test_blackjack_exists + # assert @blackjack + #end - def test_deck_exists - assert Blackjack.new.deck - end + #def test_deck_exists + # assert @blackjack.deck + #end + + # def test_deck_has_52_cards + # assert_equal 52, cards.length + # end =begin def test_blackjack_deck_has_cards - assert Game.new.grid.is_a? Array - assert_equal Game.new.grid.length, 3 + + end =end end \ No newline at end of file From 20c9429e9f1c7cbde74943d6c3cc6d51e8cb5b19 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 05:03:03 -0500 Subject: [PATCH 05/59] Run TestBlackjack with two assertions: test_blackjack_exists and test_deck_exists successfully. Add class TestDeck with setup defined. No errors on test. --- code/blackjack_test.rb | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/code/blackjack_test.rb b/code/blackjack_test.rb index 95f48ce..7b44487 100644 --- a/code/blackjack_test.rb +++ b/code/blackjack_test.rb @@ -29,22 +29,25 @@ def setup #this runs before each test @blackjack = Blackjack.new end - #def test_blackjack_exists - # assert @blackjack - #end + def test_blackjack_exists + assert @blackjack + end - #def test_deck_exists - # assert @blackjack.deck - #end + def test_deck_exists + assert @blackjack.deck + end # def test_deck_has_52_cards - # assert_equal 52, cards.length + # assert_equal 52, cards.length # end -=begin - def test_blackjack_deck_has_cards +end +class TestDeck < MiniTest::Unit::TestCase + def setup + @deck = Blackjack.new.deck end -=end + + end \ No newline at end of file From 84c638e0618302763c15a7d8ee89100ee0115d52 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 05:12:18 -0500 Subject: [PATCH 06/59] Comment out methods that do not have successful tests. --- code/blackjack.rb | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/code/blackjack.rb b/code/blackjack.rb index 86a0f11..73869b1 100644 --- a/code/blackjack.rb +++ b/code/blackjack.rb @@ -24,18 +24,18 @@ def initialize end end - def shuffled_cards - @cards = @cards.shuffle! - end + #def shuffle #shuffle cards. ! changes array. + # @cards = @cards.shuffle! + #end - def hand - #card = cards.pop - end + # def deal #remove one card from shuffled deck + # @cards.pop + # end end -class Dealer +#class Dealer #attr_accessor - def initialize + # def initialize - end -end \ No newline at end of file + # end +#end \ No newline at end of file From 72bc1122c176965f612468f5bb6b73e54fb05995 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 05:13:42 -0500 Subject: [PATCH 07/59] Add test_deck_has_52_cards. Run test. --- code/blackjack_test.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/blackjack_test.rb b/code/blackjack_test.rb index 7b44487..062a543 100644 --- a/code/blackjack_test.rb +++ b/code/blackjack_test.rb @@ -49,5 +49,8 @@ def setup @deck = Blackjack.new.deck end + def test_deck_has_52_cards + assert_equal 52, @deck.cards.length + end end \ No newline at end of file From 30b0a525b2352ea5c8b7ac5a3b562f8e8529c0d0 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 05:29:14 -0500 Subject: [PATCH 08/59] Add shuffle method. @shuffled_cards = @cards.shuffle. Add attr_accessor :shuffled_cards --- code/blackjack.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/blackjack.rb b/code/blackjack.rb index 73869b1..28ace54 100644 --- a/code/blackjack.rb +++ b/code/blackjack.rb @@ -11,7 +11,7 @@ def initialize #this runs when Blackjack.new is called end class Deck - attr_accessor :cards + attr_accessor :cards, :shuffled_cards def initialize @cards = [] @@ -24,9 +24,9 @@ def initialize end end - #def shuffle #shuffle cards. ! changes array. - # @cards = @cards.shuffle! - #end + def shuffle #shuffle cards. ! changes array. + @shuffled_cards = @cards.shuffle + end # def deal #remove one card from shuffled deck # @cards.pop From 6f1c2ae02bd18e568af9c4614e0185deab17a12b Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 05:30:38 -0500 Subject: [PATCH 09/59] Add test_shuffled_cards_not_equal_to_cards to test whether cards not equal to shuffled_cards. Test successful. --- code/blackjack_test.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/blackjack_test.rb b/code/blackjack_test.rb index 062a543..b9811e1 100644 --- a/code/blackjack_test.rb +++ b/code/blackjack_test.rb @@ -53,4 +53,8 @@ def test_deck_has_52_cards assert_equal 52, @deck.cards.length end + def test_shuffled_cards_not_equal_to_cards + assert_equal false, @deck.cards == @deck.shuffled_cards + end + end \ No newline at end of file From 76af900fda99ab76d6feaa146a709d3bb31673c6 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 05:44:33 -0500 Subject: [PATCH 10/59] Fix math. There are 4 suits. Each suit has 13 cards: 2..10, J=10, Q=10,K=10 and A=11. --- code/blackjack_test.rb | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/code/blackjack_test.rb b/code/blackjack_test.rb index b9811e1..c12dbe0 100644 --- a/code/blackjack_test.rb +++ b/code/blackjack_test.rb @@ -5,10 +5,11 @@ class TestBlackjack < MiniTest::Unit::TestCase #there's a deck of cards #there are 52 cards - #there a 4 sets of 14 cards represented by 1-10,J, Q, K, A - #cards 1..10 have the same corresponding values of 1..10. + #there a 4 sets of 13 cards represented by 2-10,J, Q, K, A + #cards 2..10 have the same corresponding values of 2..10. # J, Q, K each have a value of 10 # A has a value of 11 + #Card values: 2,3,4,5,6,7,8,9,10,10,10,10,11 (13 Cards) * 4 Suits = 52 Cards #there is one dealer #there are 1+ player(s) #the dealer deals a hand to each player and self. @@ -37,10 +38,6 @@ def test_deck_exists assert @blackjack.deck end - # def test_deck_has_52_cards - # assert_equal 52, cards.length - # end - end class TestDeck < MiniTest::Unit::TestCase @@ -57,4 +54,5 @@ def test_shuffled_cards_not_equal_to_cards assert_equal false, @deck.cards == @deck.shuffled_cards end -end \ No newline at end of file +end + From 08b43b177dd243278af83955a5603db33bf54ed5 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 05:51:59 -0500 Subject: [PATCH 11/59] Add Dealer class. Initialize with empty hand and hand_total = 0. Add attr_accessor for :hand and :hand_total. Also add @dealer to Blackjack initialize method. Need to add attr_accessor for :dealer. --- code/blackjack.rb | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/code/blackjack.rb b/code/blackjack.rb index 28ace54..3392545 100644 --- a/code/blackjack.rb +++ b/code/blackjack.rb @@ -1,13 +1,14 @@ class Blackjack - attr_accessor :deck #this means we can interact with the instance variable @deck + attr_accessor :deck, :hand #this means we can interact with the instance variable @deck # and we can pretend it is a method: Blackjack.new.deck def initialize #this runs when Blackjack.new is called @deck = Deck.new + @dealer = Dealer.new end - # def hand - # @hand = hand - # end + #def hand + # @hand = [] + #end end class Deck @@ -28,14 +29,17 @@ def shuffle #shuffle cards. ! changes array. @shuffled_cards = @cards.shuffle end - # def deal #remove one card from shuffled deck + # def deal #remove one card from shuffled deck - possible to do yield twice to get two initial cards? # @cards.pop # end end -#class Dealer - #attr_accessor - # def initialize +class Dealer + attr_accessor :hand, :hand_total + def initialize + @hand = [] + @hand_total = 0 + end - # end + end #end \ No newline at end of file From 683d6ca92fff19e92a532650bf7ef00f90839fbb Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 05:53:15 -0500 Subject: [PATCH 12/59] Add TestDealer class with instance variable @dealer. --- code/blackjack_test.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/code/blackjack_test.rb b/code/blackjack_test.rb index c12dbe0..31b6b35 100644 --- a/code/blackjack_test.rb +++ b/code/blackjack_test.rb @@ -56,3 +56,10 @@ def test_shuffled_cards_not_equal_to_cards end +class TestDealer < MiniTest::Unit::TestCase + + def setup + @dealer = Blackjack.new.dealer + end +end + From f4896b463603393b1fd93c4469283111dbb496b2 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 06:01:22 -0500 Subject: [PATCH 13/59] Test dealer_hand_total is equal to 0. Test successful. --- code/blackjack_test.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/blackjack_test.rb b/code/blackjack_test.rb index 31b6b35..c062ff0 100644 --- a/code/blackjack_test.rb +++ b/code/blackjack_test.rb @@ -61,5 +61,9 @@ class TestDealer < MiniTest::Unit::TestCase def setup @dealer = Blackjack.new.dealer end + + def test_dealer_hand_total_equal_to_zero + assert_equal true, @dealer.hand_total == 0 + end end From 4266c7b7b848e42ec8f46da82410370cf66ab243 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 06:02:47 -0500 Subject: [PATCH 14/59] Add attr_accessor :dealer to Blackjack class --- code/blackjack.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/blackjack.rb b/code/blackjack.rb index 3392545..5441b50 100644 --- a/code/blackjack.rb +++ b/code/blackjack.rb @@ -1,5 +1,5 @@ class Blackjack - attr_accessor :deck, :hand #this means we can interact with the instance variable @deck + attr_accessor :deck, :hand, :dealer #this means we can interact with the instance variable @deck # and we can pretend it is a method: Blackjack.new.deck def initialize #this runs when Blackjack.new is called @deck = Deck.new From d15e47176ce272cc76dede805a9d79f814e76efd Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 13:46:14 -0500 Subject: [PATCH 15/59] Create file code/wolf.rb --- code/wolf.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 code/wolf.rb diff --git a/code/wolf.rb b/code/wolf.rb new file mode 100644 index 0000000..e69de29 From 5a6933002d0f76f91b8f21a5360ed85647e8009d Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 14:27:27 -0500 Subject: [PATCH 16/59] Add Koans --- code/koans/GREED_RULES.txt | 66 +++ code/koans/README.rdoc | 191 ++++++++ code/koans/Rakefile | 12 + code/koans/about_array_assignment.rb | 51 +++ code/koans/about_arrays.rb | 84 ++++ code/koans/about_asserts.rb | 40 ++ code/koans/about_blocks.rb | 96 ++++ code/koans/about_class_methods.rb | 169 +++++++ code/koans/about_classes.rb | 190 ++++++++ code/koans/about_constants.rb | 87 ++++ code/koans/about_control_statements.rb | 142 ++++++ code/koans/about_dice_project.rb | 63 +++ code/koans/about_exceptions.rb | 68 +++ code/koans/about_extra_credit.rb | 8 + code/koans/about_hashes.rb | 116 +++++ code/koans/about_inheritance.rb | 85 ++++ code/koans/about_iteration.rb | 122 ++++++ code/koans/about_java_interop.rb | 137 ++++++ code/koans/about_keyword_arguments.rb | 31 ++ code/koans/about_message_passing.rb | 185 ++++++++ code/koans/about_methods.rb | 151 +++++++ code/koans/about_modules.rb | 63 +++ code/koans/about_nil.rb | 38 ++ code/koans/about_objects.rb | 50 +++ code/koans/about_open_classes.rb | 45 ++ code/koans/about_proxy_object_project.rb | 156 +++++++ code/koans/about_regular_expressions.rb | 161 +++++++ code/koans/about_sandwich_code.rb | 106 +++++ code/koans/about_scope.rb | 79 ++++ code/koans/about_scoring_project.rb | 77 ++++ code/koans/about_strings.rb | 197 +++++++++ code/koans/about_symbols.rb | 100 +++++ code/koans/about_to_str.rb | 54 +++ code/koans/about_triangle_project.rb | 24 + code/koans/about_triangle_project_2.rb | 16 + code/koans/about_true_and_false.rb | 33 ++ code/koans/about_variable_scope.rb | 114 +++++ code/koans/example_file.txt | 4 + code/koans/koans.watchr | 3 + code/koans/neo.rb | 535 +++++++++++++++++++++++ code/koans/path_to_enlightenment.rb | 41 ++ code/koans/triangle.rb | 22 + code/koans/versioning_spec.rb | 29 ++ 43 files changed, 4041 insertions(+) create mode 100644 code/koans/GREED_RULES.txt create mode 100644 code/koans/README.rdoc create mode 100644 code/koans/Rakefile create mode 100644 code/koans/about_array_assignment.rb create mode 100644 code/koans/about_arrays.rb create mode 100644 code/koans/about_asserts.rb create mode 100644 code/koans/about_blocks.rb create mode 100644 code/koans/about_class_methods.rb create mode 100644 code/koans/about_classes.rb create mode 100644 code/koans/about_constants.rb create mode 100644 code/koans/about_control_statements.rb create mode 100644 code/koans/about_dice_project.rb create mode 100644 code/koans/about_exceptions.rb create mode 100644 code/koans/about_extra_credit.rb create mode 100644 code/koans/about_hashes.rb create mode 100644 code/koans/about_inheritance.rb create mode 100644 code/koans/about_iteration.rb create mode 100644 code/koans/about_java_interop.rb create mode 100644 code/koans/about_keyword_arguments.rb create mode 100644 code/koans/about_message_passing.rb create mode 100644 code/koans/about_methods.rb create mode 100644 code/koans/about_modules.rb create mode 100644 code/koans/about_nil.rb create mode 100644 code/koans/about_objects.rb create mode 100644 code/koans/about_open_classes.rb create mode 100644 code/koans/about_proxy_object_project.rb create mode 100644 code/koans/about_regular_expressions.rb create mode 100644 code/koans/about_sandwich_code.rb create mode 100644 code/koans/about_scope.rb create mode 100644 code/koans/about_scoring_project.rb create mode 100644 code/koans/about_strings.rb create mode 100644 code/koans/about_symbols.rb create mode 100644 code/koans/about_to_str.rb create mode 100644 code/koans/about_triangle_project.rb create mode 100644 code/koans/about_triangle_project_2.rb create mode 100644 code/koans/about_true_and_false.rb create mode 100644 code/koans/about_variable_scope.rb create mode 100644 code/koans/example_file.txt create mode 100644 code/koans/koans.watchr create mode 100644 code/koans/neo.rb create mode 100644 code/koans/path_to_enlightenment.rb create mode 100644 code/koans/triangle.rb create mode 100644 code/koans/versioning_spec.rb diff --git a/code/koans/GREED_RULES.txt b/code/koans/GREED_RULES.txt new file mode 100644 index 0000000..58b5a9c --- /dev/null +++ b/code/koans/GREED_RULES.txt @@ -0,0 +1,66 @@ += Playing Greed + +Greed is a dice game played among 2 or more players, using 5 +six-sided dice. + +== Playing Greed + +Each player takes a turn consisting of one or more rolls of the dice. +On the first roll of the game, a player rolls all five dice which are +scored according to the following: + + Three 1's => 1000 points + Three 6's => 600 points + Three 5's => 500 points + Three 4's => 400 points + Three 3's => 300 points + Three 2's => 200 points + One 1 => 100 points + One 5 => 50 points + +A single die can only be counted once in each roll. For example, +a "5" can only count as part of a triplet (contributing to the 500 +points) or as a single 50 points, but not both in the same roll. + +Example Scoring + + Throw Score + --------- ------------------ + 5 1 3 4 1 50 + 2 * 100 = 250 + 1 1 1 3 1 1000 + 100 = 1100 + 2 4 4 5 4 400 + 50 = 450 + +The dice not contributing to the score are called the non-scoring +dice. "3" and "4" are non-scoring dice in the first example. "3" is +a non-scoring die in the second, and "2" is a non-score die in the +final example. + +After a player rolls and the score is calculated, the scoring dice are +removed and the player has the option of rolling again using only the +non-scoring dice. If all of the thrown dice are scoring, then the +player may roll all 5 dice in the next roll. + +The player may continue to roll as long as each roll scores points. If +a roll has zero points, then the player loses not only their turn, but +also accumulated score for that turn. If a player decides to stop +rolling before rolling a zero-point roll, then the accumulated points +for the turn is added to his total score. + +== Getting "In The Game" + +Before a player is allowed to accumulate points, they must get at +least 300 points in a single turn. Once they have achieved 300 points +in a single turn, the points earned in that turn and each following +turn will be counted toward their total score. + +== End Game + +Once a player reaches 3000 (or more) points, the game enters the final +round where each of the other players gets one more turn. The winner +is the player with the highest score after the final round. + +== References + +Greed is described on Wikipedia at +http://en.wikipedia.org/wiki/Greed_(dice_game), however the rules are +a bit different from the rules given here. diff --git a/code/koans/README.rdoc b/code/koans/README.rdoc new file mode 100644 index 0000000..5908547 --- /dev/null +++ b/code/koans/README.rdoc @@ -0,0 +1,191 @@ += Neo Ruby Koans + +The Ruby Koans walk you along the path to enlightenment in order to learn Ruby. +The goal is to learn the Ruby language, syntax, structure, and some common +functions and libraries. We also teach you culture by basing the koans on tests. +Testing is not just something we pay lip service to, but something we +live. Testing is essential in your quest to learn and do great things in Ruby. + +== The Structure + +The koans are broken out into areas by file, hashes are covered in +about_hashes.rb+, +modules are introduced in +about_modules.rb+, etc. They are presented in +order in the +path_to_enlightenment.rb+ file. + +Each koan builds up your knowledge of Ruby and builds upon itself. It will stop at +the first place you need to correct. + +Some koans simply need to have the correct answer substituted for an incorrect one. +Some, however, require you to supply your own answer. If you see the method +__+ (a +double underscore) listed, it is a hint to you to supply your own code in order to +make it work correctly. + +== Installing Ruby + +If you do not have Ruby setup, please visit http://ruby-lang.org/en/downloads/ for +operating specific instructions. In order to run the koans you need +ruby+ and ++rake+ installed. To check your installations simply type: + +*nix platforms from any terminal window: + + [~] $ ruby --version + [~] $ rake --version + +Windows from the command prompt (+cmd.exe+) + + c:\ruby --version + c:\rake --version + +If you don't have +rake+ installed, just run gem install rake + +Any response for Ruby with a version number greater than 1.8 is fine (should be +around 1.8.6 or more). Any version of +rake+ will do. + +== Generating the Koans + +A fresh checkout will not include the koans, you will need to generate +them. + + [ruby_koans] $ rake gen # generates the koans directory + +If you need to regenerate the koans, thus wiping your current `koans`, + + [ruby_koans] $ rake regen # regenerates the koans directory, wiping the original + +== The Path To Enlightenment + +You can run the tests through +rake+ or by calling the file itself (+rake+ is the +recommended way to run them as we might build more functionality into this task). + +*nix platforms, from the +ruby_koans+ directory + + [ruby_koans] $ rake # runs the default target :walk_the_path + [ruby_koans] $ ruby path_to_enlightenment.rb # simply call the file directly + +Windows is the same thing + + c:\ruby_koans\rake # runs the default target :walk_the_path + c:\ruby_koans\ruby path_to_enlightenment.rb # simply call the file directly + +=== Red, Green, Refactor + +In test-driven development the mantra has always been red, green, refactor. +Write a failing test and run it (red), make the test pass (green), +then look at the code and consider if you can make it any better (refactor). + +While walking the path to Ruby enlightenment you will need to run the koan and +see it fail (red), make the test pass (green), then take a moment +and reflect upon the test to see what it is teaching you and improve the code to +better communicate its intent (refactor). + +The very first time you run the koans you will see the following output: + + [ ruby_koans ] $ rake + (in /Users/person/dev/ruby_koans) + /usr/bin/ruby1.8 path_to_enlightenment.rb + + AboutAsserts#test_assert_truth has damaged your karma. + + The Master says: + You have not yet reached enlightenment. + + The answers you seek... + is not true. + + Please meditate on the following code: + ./about_asserts.rb:10:in `test_assert_truth' + path_to_enlightenment.rb:38:in `each_with_index' + path_to_enlightenment.rb:38 + + mountains are merely mountains + your path thus far [X_________________________________________________] 0/280 + +You have come to your first stage. Notice it is telling you where to look for +the first solution: + + Please meditate on the following code: + ./about_asserts.rb:10:in `test_assert_truth' + path_to_enlightenment.rb:38:in `each_with_index' + path_to_enlightenment.rb:38 + +Open the +about_asserts.rb+ file and look at the first test: + + # We shall contemplate truth by testing reality, via asserts. + def test_assert_truth + assert false # This should be true + end + +Change the +false+ to +true+ and re-run the test. After you are +done, think about what you are learning. In this case, ignore everything except +the method name (+test_assert_truth+) and the parts inside the method (everything +before the +end+). + +In this case the goal is for you to see that if you pass a value to the +assert+ +method, it will either ensure it is +true+ and continue on, or fail if +the statement is +false+. + +=== Running the Koans automatically + +This section is optional. + +Normally the path to enlightenment looks like this: + + cd ruby_koans + rake + # edit + rake + # edit + rake + # etc + +If you prefer, you can keep the koans running in the background so that after you +make a change in your editor, the koans will immediately run again. This will +hopefully keep your focus on learning Ruby instead of on the command line. + +Install the Ruby gem (library) called +watchr+ and then ask it to +"watch" the koans for changes: + + cd ruby_koans + rake + # decide to run rake automatically from now on as you edit + gem install watchr + watchr ./koans/koans.watchr + +== Inspiration + +A special thanks to Mike Clark and Ara Howard for inspiring this +project. Mike Clark wrote an excellent blog post about learning Ruby +through unit testing. This sparked an idea that has taken a bit to +solidify, that of bringing new rubyists into the community through +testing. Ara Howard then gave us the idea for the Koans in his ruby +quiz entry on Meta Koans (a must for any rubyist wanting to improve +their skills). Also, "The Little Lisper" taught us all the value of +the short questions/simple answers style of learning. + +Mike Clark's post :: http://www.clarkware.com/cgi/blosxom/2005/03/18 +Meta Koans :: http://rubyquiz.com/quiz67.html +The Little Lisper :: http://www.amazon.com/Little-LISPer-Third-Daniel-Friedman/dp/0023397632 + +== Other Resources + +The Ruby Language :: http://ruby-lang.org +Try Ruby in your browser :: http://tryruby.org + +Dave Thomas' introduction to Ruby Programming Ruby (the Pick Axe) :: http://pragprog.com/titles/ruby/programming-ruby + +Brian Marick's fantastic guide for beginners Everyday Scripting with Ruby :: http://pragprog.com/titles/bmsft/everyday-scripting-with-ruby + += Other stuff + +Author :: Jim Weirich +Author :: Joe O'Brien +Issue Tracker :: http://www.pivotaltracker.com/projects/48111 +Requires :: Ruby 1.8.x or later and Rake (any recent version) + += License + +http://i.creativecommons.org/l/by-nc-sa/3.0/88x31.png + +RubyKoans is released under a Creative Commons, +Attribution-NonCommercial-ShareAlike, Version 3.0 +(http://creativecommons.org/licenses/by-nc-sa/3.0/) License. diff --git a/code/koans/Rakefile b/code/koans/Rakefile new file mode 100644 index 0000000..1a2c7f2 --- /dev/null +++ b/code/koans/Rakefile @@ -0,0 +1,12 @@ +#!/usr/bin/env ruby +# -*- ruby -*- + +require 'rake/clean' +require 'rake/testtask' + +task :default => :test + +task :test do + ruby 'path_to_enlightenment.rb' +end + diff --git a/code/koans/about_array_assignment.rb b/code/koans/about_array_assignment.rb new file mode 100644 index 0000000..87186ff --- /dev/null +++ b/code/koans/about_array_assignment.rb @@ -0,0 +1,51 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutArrayAssignment < Neo::Koan + def test_non_parallel_assignment + names = ["John", "Smith"] + assert_equal __, names + end + + def test_parallel_assignments + first_name, last_name = ["John", "Smith"] + assert_equal __, first_name + assert_equal __, last_name + end + + def test_parallel_assignments_with_extra_values + first_name, last_name = ["John", "Smith", "III"] + assert_equal __, first_name + assert_equal __, last_name + end + + def test_parallel_assignments_with_splat_operator + first_name, *last_name = ["John", "Smith", "III"] + assert_equal __, first_name + assert_equal __, last_name + end + + def test_parallel_assignments_with_too_few_variables + first_name, last_name = ["Cher"] + assert_equal __, first_name + assert_equal __, last_name + end + + def test_parallel_assignments_with_subarrays + first_name, last_name = [["Willie", "Rae"], "Johnson"] + assert_equal __, first_name + assert_equal __, last_name + end + + def test_parallel_assignment_with_one_variable + first_name, = ["John", "Smith"] + assert_equal __, first_name + end + + def test_swapping_with_parallel_assignment + first_name = "Roy" + last_name = "Rob" + first_name, last_name = last_name, first_name + assert_equal __, first_name + assert_equal __, last_name + end +end diff --git a/code/koans/about_arrays.rb b/code/koans/about_arrays.rb new file mode 100644 index 0000000..ce9b46e --- /dev/null +++ b/code/koans/about_arrays.rb @@ -0,0 +1,84 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutArrays < Neo::Koan + def test_creating_arrays + empty_array = Array.new + assert_equal __, empty_array.class + assert_equal __, empty_array.size + end + + def test_array_literals + array = Array.new + assert_equal [], array + + array[0] = 1 + assert_equal [1], array + + array[1] = 2 + assert_equal [1, __], array + + array << 333 + assert_equal __, array + end + + def test_accessing_array_elements + array = [:peanut, :butter, :and, :jelly] + + assert_equal __, array[0] + assert_equal __, array.first + assert_equal __, array[3] + assert_equal __, array.last + assert_equal __, array[-1] + assert_equal __, array[-3] + end + + def test_slicing_arrays + array = [:peanut, :butter, :and, :jelly] + + assert_equal __, array[0,1] + assert_equal __, array[0,2] + assert_equal __, array[2,2] + assert_equal __, array[2,20] + assert_equal __, array[4,0] + assert_equal __, array[4,100] + assert_equal __, array[5,0] + end + + def test_arrays_and_ranges + assert_equal __, (1..5).class + assert_not_equal [1,2,3,4,5], (1..5) + assert_equal __, (1..5).to_a + assert_equal __, (1...5).to_a + end + + def test_slicing_with_ranges + array = [:peanut, :butter, :and, :jelly] + + assert_equal __, array[0..2] + assert_equal __, array[0...2] + assert_equal __, array[2..-1] + end + + def test_pushing_and_popping_arrays + array = [1,2] + array.push(:last) + + assert_equal __, array + + popped_value = array.pop + assert_equal __, popped_value + assert_equal __, array + end + + def test_shifting_arrays + array = [1,2] + array.unshift(:first) + + assert_equal __, array + + shifted_value = array.shift + assert_equal __, shifted_value + assert_equal __, array + end + +end diff --git a/code/koans/about_asserts.rb b/code/koans/about_asserts.rb new file mode 100644 index 0000000..5defa59 --- /dev/null +++ b/code/koans/about_asserts.rb @@ -0,0 +1,40 @@ +#!/usr/bin/env ruby +# -*- ruby -*- + +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutAsserts < Neo::Koan + + # We shall contemplate truth by testing reality, via asserts. + def test_assert_truth + assert false # This should be true + end + + # Enlightenment may be more easily achieved with appropriate + # messages. + def test_assert_with_message + assert false, "This should be true -- Please fix this" + end + + # To understand reality, we must compare our expectations against + # reality. + def test_assert_equality + expected_value = __ + actual_value = 1 + 1 + + assert expected_value == actual_value + end + + # Some ways of asserting equality are better than others. + def test_a_better_way_of_asserting_equality + expected_value = __ + actual_value = 1 + 1 + + assert_equal expected_value, actual_value + end + + # Sometimes we will ask you to fill in the values + def test_fill_in_values + assert_equal __, 1 + 1 + end +end diff --git a/code/koans/about_blocks.rb b/code/koans/about_blocks.rb new file mode 100644 index 0000000..c02dab9 --- /dev/null +++ b/code/koans/about_blocks.rb @@ -0,0 +1,96 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutBlocks < Neo::Koan + def method_with_block + result = yield + result + end + + def test_methods_can_take_blocks + yielded_result = method_with_block { 1 + 2 } + assert_equal __, yielded_result + end + + def test_blocks_can_be_defined_with_do_end_too + yielded_result = method_with_block do 1 + 2 end + assert_equal __, yielded_result + end + + # ------------------------------------------------------------------ + + def method_with_block_arguments + yield("Jim") + end + + def test_blocks_can_take_arguments + method_with_block_arguments do |argument| + assert_equal __, argument + end + end + + # ------------------------------------------------------------------ + + def many_yields + yield(:peanut) + yield(:butter) + yield(:and) + yield(:jelly) + end + + def test_methods_can_call_yield_many_times + result = [] + many_yields { |item| result << item } + assert_equal __, result + end + + # ------------------------------------------------------------------ + + def yield_tester + if block_given? + yield + else + :no_block + end + end + + def test_methods_can_see_if_they_have_been_called_with_a_block + assert_equal __, yield_tester { :with_block } + assert_equal __, yield_tester + end + + # ------------------------------------------------------------------ + + def test_block_can_affect_variables_in_the_code_where_they_are_created + value = :initial_value + method_with_block { value = :modified_in_a_block } + assert_equal __, value + end + + def test_blocks_can_be_assigned_to_variables_and_called_explicitly + add_one = lambda { |n| n + 1 } + assert_equal __, add_one.call(10) + + # Alternative calling syntax + assert_equal __, add_one[10] + end + + def test_stand_alone_blocks_can_be_passed_to_methods_expecting_blocks + make_upper = lambda { |n| n.upcase } + result = method_with_block_arguments(&make_upper) + assert_equal __, result + end + + # ------------------------------------------------------------------ + + def method_with_explicit_block(&block) + block.call(10) + end + + def test_methods_can_take_an_explicit_block_argument + assert_equal __, method_with_explicit_block { |n| n * 2 } + + add_one = lambda { |n| n + 1 } + assert_equal __, method_with_explicit_block(&add_one) + end + +end diff --git a/code/koans/about_class_methods.rb b/code/koans/about_class_methods.rb new file mode 100644 index 0000000..46aab74 --- /dev/null +++ b/code/koans/about_class_methods.rb @@ -0,0 +1,169 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutClassMethods < Neo::Koan + class Dog + end + + def test_objects_are_objects + fido = Dog.new + assert_equal __, fido.is_a?(Object) + end + + def test_classes_are_classes + assert_equal __, Dog.is_a?(Class) + end + + def test_classes_are_objects_too + assert_equal __, Dog.is_a?(Object) + end + + def test_objects_have_methods + fido = Dog.new + assert fido.methods.size > _n_ + end + + def test_classes_have_methods + assert Dog.methods.size > _n_ + end + + def test_you_can_define_methods_on_individual_objects + fido = Dog.new + def fido.wag + :fidos_wag + end + assert_equal __, fido.wag + end + + def test_other_objects_are_not_affected_by_these_singleton_methods + fido = Dog.new + rover = Dog.new + def fido.wag + :fidos_wag + end + + assert_raise(___) do + rover.wag + end + end + + # ------------------------------------------------------------------ + + class Dog2 + def wag + :instance_level_wag + end + end + + def Dog2.wag + :class_level_wag + end + + def test_since_classes_are_objects_you_can_define_singleton_methods_on_them_too + assert_equal __, Dog2.wag + end + + def test_class_methods_are_independent_of_instance_methods + fido = Dog2.new + assert_equal __, fido.wag + assert_equal __, Dog2.wag + end + + # ------------------------------------------------------------------ + + class Dog + attr_accessor :name + end + + def Dog.name + @name + end + + def test_classes_and_instances_do_not_share_instance_variables + fido = Dog.new + fido.name = "Fido" + assert_equal __, fido.name + assert_equal __, Dog.name + end + + # ------------------------------------------------------------------ + + class Dog + def Dog.a_class_method + :dogs_class_method + end + end + + def test_you_can_define_class_methods_inside_the_class + assert_equal __, Dog.a_class_method + end + + # ------------------------------------------------------------------ + + LastExpressionInClassStatement = class Dog + 21 + end + + def test_class_statements_return_the_value_of_their_last_expression + assert_equal __, LastExpressionInClassStatement + end + + # ------------------------------------------------------------------ + + SelfInsideOfClassStatement = class Dog + self + end + + def test_self_while_inside_class_is_class_object_not_instance + assert_equal __, Dog == SelfInsideOfClassStatement + end + + # ------------------------------------------------------------------ + + class Dog + def self.class_method2 + :another_way_to_write_class_methods + end + end + + def test_you_can_use_self_instead_of_an_explicit_reference_to_dog + assert_equal __, Dog.class_method2 + end + + # ------------------------------------------------------------------ + + class Dog + class << self + def another_class_method + :still_another_way + end + end + end + + def test_heres_still_another_way_to_write_class_methods + assert_equal __, Dog.another_class_method + end + + # THINK ABOUT IT: + # + # The two major ways to write class methods are: + # class Demo + # def self.method + # end + # + # class << self + # def class_methods + # end + # end + # end + # + # Which do you prefer and why? + # Are there times you might prefer one over the other? + + # ------------------------------------------------------------------ + + def test_heres_an_easy_way_to_call_class_methods_from_instance_methods + fido = Dog.new + assert_equal __, fido.class.another_class_method + end + +end diff --git a/code/koans/about_classes.rb b/code/koans/about_classes.rb new file mode 100644 index 0000000..1d146be --- /dev/null +++ b/code/koans/about_classes.rb @@ -0,0 +1,190 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutClasses < Neo::Koan + class Dog + end + + def test_instances_of_classes_can_be_created_with_new + fido = Dog.new + assert_equal __, fido.class + end + + # ------------------------------------------------------------------ + + class Dog2 + def set_name(a_name) + @name = a_name + end + end + + def test_instance_variables_can_be_set_by_assigning_to_them + fido = Dog2.new + assert_equal __, fido.instance_variables + + fido.set_name("Fido") + assert_equal __, fido.instance_variables + end + + def test_instance_variables_cannot_be_accessed_outside_the_class + fido = Dog2.new + fido.set_name("Fido") + + assert_raise(___) do + fido.name + end + + assert_raise(___) do + eval "fido.@name" + # NOTE: Using eval because the above line is a syntax error. + end + end + + def test_you_can_politely_ask_for_instance_variable_values + fido = Dog2.new + fido.set_name("Fido") + + assert_equal __, fido.instance_variable_get("@name") + end + + def test_you_can_rip_the_value_out_using_instance_eval + fido = Dog2.new + fido.set_name("Fido") + + assert_equal __, fido.instance_eval("@name") # string version + assert_equal __, fido.instance_eval { @name } # block version + end + + # ------------------------------------------------------------------ + + class Dog3 + def set_name(a_name) + @name = a_name + end + def name + @name + end + end + + def test_you_can_create_accessor_methods_to_return_instance_variables + fido = Dog3.new + fido.set_name("Fido") + + assert_equal __, fido.name + end + + # ------------------------------------------------------------------ + + class Dog4 + attr_reader :name + + def set_name(a_name) + @name = a_name + end + end + + + def test_attr_reader_will_automatically_define_an_accessor + fido = Dog4.new + fido.set_name("Fido") + + assert_equal __, fido.name + end + + # ------------------------------------------------------------------ + + class Dog5 + attr_accessor :name + end + + + def test_attr_accessor_will_automatically_define_both_read_and_write_accessors + fido = Dog5.new + + fido.name = "Fido" + assert_equal __, fido.name + end + + # ------------------------------------------------------------------ + + class Dog6 + attr_reader :name + def initialize(initial_name) + @name = initial_name + end + end + + def test_initialize_provides_initial_values_for_instance_variables + fido = Dog6.new("Fido") + assert_equal __, fido.name + end + + def test_args_to_new_must_match_initialize + assert_raise(___) do + Dog6.new + end + # THINK ABOUT IT: + # Why is this so? + end + + def test_different_objects_have_different_instance_variables + fido = Dog6.new("Fido") + rover = Dog6.new("Rover") + + assert_equal __, rover.name != fido.name + end + + # ------------------------------------------------------------------ + + class Dog7 + attr_reader :name + + def initialize(initial_name) + @name = initial_name + end + + def get_self + self + end + + def to_s + @name + end + + def inspect + "" + end + end + + def test_inside_a_method_self_refers_to_the_containing_object + fido = Dog7.new("Fido") + + fidos_self = fido.get_self + assert_equal __, fidos_self + end + + def test_to_s_provides_a_string_version_of_the_object + fido = Dog7.new("Fido") + assert_equal __, fido.to_s + end + + def test_to_s_is_used_in_string_interpolation + fido = Dog7.new("Fido") + assert_equal __, "My dog is #{fido}" + end + + def test_inspect_provides_a_more_complete_string_version + fido = Dog7.new("Fido") + assert_equal __, fido.inspect + end + + def test_all_objects_support_to_s_and_inspect + array = [1,2,3] + + assert_equal __, array.to_s + assert_equal __, array.inspect + + assert_equal __, "STRING".to_s + assert_equal __, "STRING".inspect + end + +end diff --git a/code/koans/about_constants.rb b/code/koans/about_constants.rb new file mode 100644 index 0000000..68ae078 --- /dev/null +++ b/code/koans/about_constants.rb @@ -0,0 +1,87 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +C = "top level" + +class AboutConstants < Neo::Koan + + C = "nested" + + def test_nested_constants_may_also_be_referenced_with_relative_paths + assert_equal __, C + end + + def test_top_level_constants_are_referenced_by_double_colons + assert_equal __, ::C + end + + def test_nested_constants_are_referenced_by_their_complete_path + assert_equal __, AboutConstants::C + assert_equal __, ::AboutConstants::C + end + + # ------------------------------------------------------------------ + + class Animal + LEGS = 4 + def legs_in_animal + LEGS + end + + class NestedAnimal + def legs_in_nested_animal + LEGS + end + end + end + + def test_nested_classes_inherit_constants_from_enclosing_classes + assert_equal __, Animal::NestedAnimal.new.legs_in_nested_animal + end + + # ------------------------------------------------------------------ + + class Reptile < Animal + def legs_in_reptile + LEGS + end + end + + def test_subclasses_inherit_constants_from_parent_classes + assert_equal __, Reptile.new.legs_in_reptile + end + + # ------------------------------------------------------------------ + + class MyAnimals + LEGS = 2 + + class Bird < Animal + def legs_in_bird + LEGS + end + end + end + + def test_who_wins_with_both_nested_and_inherited_constants + assert_equal __, MyAnimals::Bird.new.legs_in_bird + end + + # QUESTION: Which has precedence: The constant in the lexical scope, + # or the constant from the inheritance hierarchy? + + # ------------------------------------------------------------------ + + class MyAnimals::Oyster < Animal + def legs_in_oyster + LEGS + end + end + + def test_who_wins_with_explicit_scoping_on_class_definition + assert_equal __, MyAnimals::Oyster.new.legs_in_oyster + end + + # QUESTION: Now which has precedence: The constant in the lexical + # scope, or the constant from the inheritance hierarchy? Why is it + # different than the previous answer? +end diff --git a/code/koans/about_control_statements.rb b/code/koans/about_control_statements.rb new file mode 100644 index 0000000..f323757 --- /dev/null +++ b/code/koans/about_control_statements.rb @@ -0,0 +1,142 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutControlStatements < Neo::Koan + + def test_if_then_else_statements + if true + result = :true_value + else + result = :false_value + end + assert_equal __, result + end + + def test_if_then_statements + result = :default_value + if true + result = :true_value + end + assert_equal __, result + end + + def test_if_statements_return_values + value = if true + :true_value + else + :false_value + end + assert_equal __, value + + value = if false + :true_value + else + :false_value + end + assert_equal __, value + + # NOTE: Actually, EVERY statement in Ruby will return a value, not + # just if statements. + end + + def test_if_statements_with_no_else_with_false_condition_return_value + value = if false + :true_value + end + assert_equal __, value + end + + def test_condition_operators + assert_equal __, (true ? :true_value : :false_value) + assert_equal __, (false ? :true_value : :false_value) + end + + def test_if_statement_modifiers + result = :default_value + result = :true_value if true + + assert_equal __, result + end + + def test_unless_statement + result = :default_value + unless false # same as saying 'if !false', which evaluates as 'if true' + result = :false_value + end + assert_equal __, result + end + + def test_unless_statement_evaluate_true + result = :default_value + unless true # same as saying 'if !true', which evaluates as 'if false' + result = :true_value + end + assert_equal __, result + end + + def test_unless_statement_modifier + result = :default_value + result = :false_value unless false + + assert_equal __, result + end + + def test_while_statement + i = 1 + result = 1 + while i <= 10 + result = result * i + i += 1 + end + assert_equal __, result + end + + def test_break_statement + i = 1 + result = 1 + while true + break unless i <= 10 + result = result * i + i += 1 + end + assert_equal __, result + end + + def test_break_statement_returns_values + i = 1 + result = while i <= 10 + break i if i % 2 == 0 + i += 1 + end + + assert_equal __, result + end + + def test_next_statement + i = 0 + result = [] + while i < 10 + i += 1 + next if (i % 2) == 0 + result << i + end + assert_equal __, result + end + + def test_for_statement + array = ["fish", "and", "chips"] + result = [] + for item in array + result << item.upcase + end + assert_equal [__, __, __], result + end + + def test_times_statement + sum = 0 + 10.times do + sum += 1 + end + assert_equal __, sum + end + +end diff --git a/code/koans/about_dice_project.rb b/code/koans/about_dice_project.rb new file mode 100644 index 0000000..5a1848f --- /dev/null +++ b/code/koans/about_dice_project.rb @@ -0,0 +1,63 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +# Implement a DiceSet Class here: +# +# class DiceSet +# code ... +# end + +class AboutDiceProject < Neo::Koan + def test_can_create_a_dice_set + dice = DiceSet.new + assert_not_nil dice + end + + def test_rolling_the_dice_returns_a_set_of_integers_between_1_and_6 + dice = DiceSet.new + + dice.roll(5) + assert dice.values.is_a?(Array), "should be an array" + assert_equal 5, dice.values.size + dice.values.each do |value| + assert value >= 1 && value <= 6, "value #{value} must be between 1 and 6" + end + end + + def test_dice_values_do_not_change_unless_explicitly_rolled + dice = DiceSet.new + dice.roll(5) + first_time = dice.values + second_time = dice.values + assert_equal first_time, second_time + end + + def test_dice_values_should_change_between_rolls + dice = DiceSet.new + + dice.roll(5) + first_time = dice.values + + dice.roll(5) + second_time = dice.values + + assert_not_equal first_time, second_time, + "Two rolls should not be equal" + + # THINK ABOUT IT: + # + # If the rolls are random, then it is possible (although not + # likely) that two consecutive rolls are equal. What would be a + # better way to test this? + end + + def test_you_can_roll_different_numbers_of_dice + dice = DiceSet.new + + dice.roll(3) + assert_equal 3, dice.values.size + + dice.roll(1) + assert_equal 1, dice.values.size + end + +end diff --git a/code/koans/about_exceptions.rb b/code/koans/about_exceptions.rb new file mode 100644 index 0000000..464f57e --- /dev/null +++ b/code/koans/about_exceptions.rb @@ -0,0 +1,68 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutExceptions < Neo::Koan + + class MySpecialError < RuntimeError + end + + def test_exceptions_inherit_from_Exception + assert_equal __, MySpecialError.ancestors[1] + assert_equal __, MySpecialError.ancestors[2] + assert_equal __, MySpecialError.ancestors[3] + assert_equal __, MySpecialError.ancestors[4] + end + + def test_rescue_clause + result = nil + begin + fail "Oops" + rescue StandardError => ex + result = :exception_handled + end + + assert_equal __, result + + assert_equal __, ex.is_a?(StandardError), "Should be a Standard Error" + assert_equal __, ex.is_a?(RuntimeError), "Should be a Runtime Error" + + assert RuntimeError.ancestors.include?(StandardError), + "RuntimeError is a subclass of StandardError" + + assert_equal __, ex.message + end + + def test_raising_a_particular_error + result = nil + begin + # 'raise' and 'fail' are synonyms + raise MySpecialError, "My Message" + rescue MySpecialError => ex + result = :exception_handled + end + + assert_equal __, result + assert_equal __, ex.message + end + + def test_ensure_clause + result = nil + begin + fail "Oops" + rescue StandardError + # no code here + ensure + result = :always_run + end + + assert_equal __, result + end + + # Sometimes, we must know about the unknown + def test_asserting_an_error_is_raised + # A do-end is a block, a topic to explore more later + assert_raise(___) do + raise MySpecialError.new("New instances can be raised directly.") + end + end + +end diff --git a/code/koans/about_extra_credit.rb b/code/koans/about_extra_credit.rb new file mode 100644 index 0000000..5012edf --- /dev/null +++ b/code/koans/about_extra_credit.rb @@ -0,0 +1,8 @@ +# EXTRA CREDIT: +# +# Create a program that will play the Greed Game. +# Rules for the game are in GREED_RULES.TXT. +# +# You already have a DiceSet class and score function you can use. +# Write a player class and a Game class to complete the project. This +# is a free form assignment, so approach it however you desire. diff --git a/code/koans/about_hashes.rb b/code/koans/about_hashes.rb new file mode 100644 index 0000000..7287ba0 --- /dev/null +++ b/code/koans/about_hashes.rb @@ -0,0 +1,116 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutHashes < Neo::Koan + def test_creating_hashes + empty_hash = Hash.new + assert_equal __, empty_hash.class + assert_equal(__, empty_hash) + assert_equal __, empty_hash.size + end + + def test_hash_literals + hash = { :one => "uno", :two => "dos" } + assert_equal __, hash.size + end + + def test_accessing_hashes + hash = { :one => "uno", :two => "dos" } + assert_equal __, hash[:one] + assert_equal __, hash[:two] + assert_equal __, hash[:doesnt_exist] + end + + def test_accessing_hashes_with_fetch + hash = { :one => "uno" } + assert_equal __, hash.fetch(:one) + assert_raise(___) do + hash.fetch(:doesnt_exist) + end + + # THINK ABOUT IT: + # + # Why might you want to use #fetch instead of #[] when accessing hash keys? + end + + def test_changing_hashes + hash = { :one => "uno", :two => "dos" } + hash[:one] = "eins" + + expected = { :one => __, :two => "dos" } + assert_equal __, hash + + # Bonus Question: Why was "expected" broken out into a variable + # rather than used as a literal? + end + + def test_hash_is_unordered + hash1 = { :one => "uno", :two => "dos" } + hash2 = { :two => "dos", :one => "uno" } + + assert_equal __, hash1 == hash2 + end + + def test_hash_keys + hash = { :one => "uno", :two => "dos" } + assert_equal __, hash.keys.size + assert_equal __, hash.keys.include?(:one) + assert_equal __, hash.keys.include?(:two) + assert_equal __, hash.keys.class + end + + def test_hash_values + hash = { :one => "uno", :two => "dos" } + assert_equal __, hash.values.size + assert_equal __, hash.values.include?("uno") + assert_equal __, hash.values.include?("dos") + assert_equal __, hash.values.class + end + + def test_combining_hashes + hash = { "jim" => 53, "amy" => 20, "dan" => 23 } + new_hash = hash.merge({ "jim" => 54, "jenny" => 26 }) + + assert_equal __, hash != new_hash + + expected = { "jim" => __, "amy" => 20, "dan" => 23, "jenny" => __ } + assert_equal __, expected == new_hash + end + + def test_default_value + hash1 = Hash.new + hash1[:one] = 1 + + assert_equal __, hash1[:one] + assert_equal __, hash1[:two] + + hash2 = Hash.new("dos") + hash2[:one] = 1 + + assert_equal __, hash2[:one] + assert_equal __, hash2[:two] + end + + def test_default_value_is_the_same_object + hash = Hash.new([]) + + hash[:one] << "uno" + hash[:two] << "dos" + + assert_equal __, hash[:one] + assert_equal __, hash[:two] + assert_equal __, hash[:three] + + assert_equal __, hash[:one].object_id == hash[:two].object_id + end + + def test_default_value_with_block + hash = Hash.new {|hash, key| hash[key] = [] } + + hash[:one] << "uno" + hash[:two] << "dos" + + assert_equal __, hash[:one] + assert_equal __, hash[:two] + assert_equal __, hash[:three] + end +end diff --git a/code/koans/about_inheritance.rb b/code/koans/about_inheritance.rb new file mode 100644 index 0000000..61bc890 --- /dev/null +++ b/code/koans/about_inheritance.rb @@ -0,0 +1,85 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutInheritance < Neo::Koan + class Dog + attr_reader :name + + def initialize(name) + @name = name + end + + def bark + "WOOF" + end + end + + class Chihuahua < Dog + def wag + :happy + end + + def bark + "yip" + end + end + + def test_subclasses_have_the_parent_as_an_ancestor + assert_equal __, Chihuahua.ancestors.include?(Dog) + end + + def test_all_classes_ultimately_inherit_from_object + assert_equal __, Chihuahua.ancestors.include?(Object) + end + + def test_subclasses_inherit_behavior_from_parent_class + chico = Chihuahua.new("Chico") + assert_equal __, chico.name + end + + def test_subclasses_add_new_behavior + chico = Chihuahua.new("Chico") + assert_equal __, chico.wag + + assert_raise(___) do + fido = Dog.new("Fido") + fido.wag + end + end + + def test_subclasses_can_modify_existing_behavior + chico = Chihuahua.new("Chico") + assert_equal __, chico.bark + + fido = Dog.new("Fido") + assert_equal __, fido.bark + end + + # ------------------------------------------------------------------ + + class BullDog < Dog + def bark + super + ", GROWL" + end + end + + def test_subclasses_can_invoke_parent_behavior_via_super + ralph = BullDog.new("Ralph") + assert_equal __, ralph.bark + end + + # ------------------------------------------------------------------ + + class GreatDane < Dog + def growl + super.bark + ", GROWL" + end + end + + def test_super_does_not_work_cross_method + george = GreatDane.new("George") + assert_raise(___) do + george.growl + end + end + +end diff --git a/code/koans/about_iteration.rb b/code/koans/about_iteration.rb new file mode 100644 index 0000000..6179c2c --- /dev/null +++ b/code/koans/about_iteration.rb @@ -0,0 +1,122 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutIteration < Neo::Koan + + # -- An Aside ------------------------------------------------------ + # Ruby 1.8 stores names as strings. Ruby 1.9 and later stores names + # as symbols. So we use a version dependent method "as_name" to + # convert to the right format in the koans. We will use "as_name" + # whenever comparing to lists of methods. + + in_ruby_version("1.8") do + def as_name(name) + name.to_s + end + end + + in_ruby_version("1.9", "2") do + def as_name(name) + name.to_sym + end + end + + # Ok, now back to the Koans. + # ------------------------------------------------------------------- + + def test_each_is_a_method_on_arrays + assert_equal __, [].methods.include?(as_name(:each)) + end + + def test_iterating_with_each + array = [1, 2, 3] + sum = 0 + array.each do |item| + sum += item + end + assert_equal __, sum + end + + def test_each_can_use_curly_brace_blocks_too + array = [1, 2, 3] + sum = 0 + array.each { |item| sum += item } + assert_equal __, sum + end + + def test_break_works_with_each_style_iterations + array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + sum = 0 + array.each do |item| + break if item > 3 + sum += item + end + assert_equal __, sum + end + + def test_collect_transforms_elements_of_an_array + array = [1, 2, 3] + new_array = array.collect { |item| item + 10 } + assert_equal __, new_array + + # NOTE: 'map' is another name for the 'collect' operation + another_array = array.map { |item| item + 10 } + assert_equal __, another_array + end + + def test_select_selects_certain_items_from_an_array + array = [1, 2, 3, 4, 5, 6] + + even_numbers = array.select { |item| (item % 2) == 0 } + assert_equal __, even_numbers + + # NOTE: 'find_all' is another name for the 'select' operation + more_even_numbers = array.find_all { |item| (item % 2) == 0 } + assert_equal __, more_even_numbers + end + + def test_find_locates_the_first_element_matching_a_criteria + array = ["Jim", "Bill", "Clarence", "Doug", "Eli"] + + assert_equal __, array.find { |item| item.size > 4 } + end + + def test_inject_will_blow_your_mind + result = [2, 3, 4].inject(0) { |sum, item| sum + item } + assert_equal __, result + + result2 = [2, 3, 4].inject(1) { |product, item| product * item } + assert_equal __, result2 + + # Extra Credit: + # Describe in your own words what inject does. + end + + def test_all_iteration_methods_work_on_any_collection_not_just_arrays + # Ranges act like a collection + result = (1..3).map { |item| item + 10 } + assert_equal __, result + + # Files act like a collection of lines + File.open("example_file.txt") do |file| + upcase_lines = file.map { |line| line.strip.upcase } + assert_equal __, upcase_lines + end + + # NOTE: You can create your own collections that work with each, + # map, select, etc. + end + + # Bonus Question: In the previous koan, we saw the construct: + # + # File.open(filename) do |file| + # # code to read 'file' + # end + # + # Why did we do it that way instead of the following? + # + # file = File.open(filename) + # # code to read 'file' + # + # When you get to the "AboutSandwichCode" koan, recheck your answer. + +end diff --git a/code/koans/about_java_interop.rb b/code/koans/about_java_interop.rb new file mode 100644 index 0000000..47fef28 --- /dev/null +++ b/code/koans/about_java_interop.rb @@ -0,0 +1,137 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +include Java + +# Concepts +# * Pull in a java class +# * calling a method, Camel vs snake +# * Resolving module/class name conflicts +# * Showing what gets returned +# * Ruby Strings VS Java Strings +# * Calling custom java class +# * Calling Ruby from java??? + +class AboutJavaInterop < Neo::Koan + def test_using_a_java_library_class + java_array = java.util.ArrayList.new + assert_equal __, java_array.class + end + + def test_java_class_can_be_referenced_using_both_ruby_and_java_like_syntax + assert_equal __, Java::JavaUtil::ArrayList == java.util.ArrayList + end + + def test_include_class_includes_class_in_module_scope + assert_nil defined?(TreeSet) + include_class "java.util.TreeSet" + assert_equal __, defined?(TreeSet) + end + + # THINK ABOUT IT: + # + # What if we use: + # + # include_class "java.lang.String" + # + # What would be the value of the String constant after this + # include_class is run? Would it be useful to provide a way of + # aliasing java classes to different names? + + JString = java.lang.String + def test_also_java_class_can_be_given_ruby_aliases + java_string = JString.new("A Java String") + assert_equal __, java_string.class + assert_equal __, JString + end + + def test_can_directly_call_java_methods_on_java_objects + java_string = JString.new("A Java String") + assert_equal __, java_string.toLowerCase + end + + def test_jruby_provides_snake_case_versions_of_java_methods + java_string = JString.new("A Java String") + assert_equal __, java_string.to_lower_case + end + + def test_jruby_provides_question_mark_versions_of_boolean_methods + java_string = JString.new("A Java String") + assert_equal __, java_string.endsWith("String") + assert_equal __, java_string.ends_with("String") + assert_equal __, java_string.ends_with?("String") + end + + def test_java_string_are_not_ruby_strings + ruby_string = "A Java String" + java_string = java.lang.String.new(ruby_string) + assert_equal __, java_string.is_a?(java.lang.String) + assert_equal __, java_string.is_a?(String) + end + + def test_java_strings_can_be_compared_to_ruby_strings_maybe + ruby_string = "A Java String" + java_string = java.lang.String.new(ruby_string) + assert_equal __, ruby_string == java_string + assert_equal __, java_string == ruby_string + + # THINK ABOUT IT: + # + # Is there any possible way for this to be more wrong? + # + # SERIOUSLY, THINK ABOUT IT: + # + # Why do you suppose that Ruby and Java strings compare like that? + # + # ADVANCED THINK ABOUT IT: + # + # Is there a way to make Ruby/Java string comparisons commutative? + # How would you do it? + end + + def test_however_most_methods_returning_strings_return_ruby_strings + java_array = java.util.ArrayList.new + assert_equal __, java_array.toString + assert_equal __, java_array.toString.is_a?(String) + assert_equal __, java_array.toString.is_a?(java.lang.String) + end + + def test_some_ruby_objects_can_be_coerced_to_java + assert_equal __, "ruby string".to_java.class + assert_equal __, 1.to_java.class + assert_equal __, 9.32.to_java.class + assert_equal __, false.to_java.class + end + + def test_some_ruby_objects_are_not_coerced_to_what_you_might_expect + assert_equal __, [].to_java.class == Java::JavaUtil::ArrayList + assert_equal __, {}.to_java.class == Java::JavaUtil::HashMap + assert_equal __, Object.new.to_java.class == Java::JavaLang::Object + end + + def test_java_collections_are_enumerable + java_array = java.util.ArrayList.new + java_array << "one" << "two" << "three" + assert_equal __, java_array.map { |item| item.upcase } + end + + # ------------------------------------------------------------------ + + # Open the Java ArrayList class and add a new method. + class Java::JavaUtil::ArrayList + def multiply_all + result = 1 + each do |item| + result *= item + end + result + end + end + + def test_java_class_are_open_from_ruby + java_array = java.util.ArrayList.new + java_array.add_all([1,2,3,4,5]) + + assert_equal __, java_array.multiply_all + end + +end diff --git a/code/koans/about_keyword_arguments.rb b/code/koans/about_keyword_arguments.rb new file mode 100644 index 0000000..740d0c0 --- /dev/null +++ b/code/koans/about_keyword_arguments.rb @@ -0,0 +1,31 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutKeywordArguments < Neo::Koan + + def method_with_keyword_arguments(one: 1, two: 'two') + [one, two] + end + + def test_keyword_arguments + assert_equal __, method_with_keyword_arguments.class + assert_equal __, method_with_keyword_arguments + assert_equal __, method_with_keyword_arguments(one: 'one') + assert_equal __, method_with_keyword_arguments(two: 2) + end + + def method_with_keyword_arguments_with_mandatory_argument(one, two: 2, three: 3) + [one, two, three] + end + + def test_keyword_arguments_with_wrong_number_of_arguments + exception = assert_raise (___) do + method_with_keyword_arguments_with_mandatory_argument + end + assert_match(/__/, exception.message) + end + + # THINK ABOUT IT: + # + # Keyword arguments always have a default value, making them optional to the caller + +end diff --git a/code/koans/about_message_passing.rb b/code/koans/about_message_passing.rb new file mode 100644 index 0000000..c6d80a8 --- /dev/null +++ b/code/koans/about_message_passing.rb @@ -0,0 +1,185 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutMessagePassing < Neo::Koan + + class MessageCatcher + def caught? + true + end + end + + def test_methods_can_be_called_directly + mc = MessageCatcher.new + + assert mc.caught? + end + + def test_methods_can_be_invoked_by_sending_the_message + mc = MessageCatcher.new + + assert mc.send(:caught?) + end + + def test_methods_can_be_invoked_more_dynamically + mc = MessageCatcher.new + + assert mc.send("caught?") + assert mc.send("caught" + __ ) # What do you need to add to the first string? + assert mc.send("CAUGHT?".____ ) # What would you need to do to the string? + end + + def test_send_with_underscores_will_also_send_messages + mc = MessageCatcher.new + + assert_equal __, mc.__send__(:caught?) + + # THINK ABOUT IT: + # + # Why does Ruby provide both send and __send__ ? + end + + def test_classes_can_be_asked_if_they_know_how_to_respond + mc = MessageCatcher.new + + assert_equal __, mc.respond_to?(:caught?) + assert_equal __, mc.respond_to?(:does_not_exist) + end + + # ------------------------------------------------------------------ + + class MessageCatcher + def add_a_payload(*args) + args + end + end + + def test_sending_a_message_with_arguments + mc = MessageCatcher.new + + assert_equal __, mc.add_a_payload + assert_equal __, mc.send(:add_a_payload) + + assert_equal __, mc.add_a_payload(3, 4, nil, 6) + assert_equal __, mc.send(:add_a_payload, 3, 4, nil, 6) + end + + # NOTE: + # + # Both obj.msg and obj.send(:msg) sends the message named :msg to + # the object. We use "send" when the name of the message can vary + # dynamically (e.g. calculated at run time), but by far the most + # common way of sending a message is just to say: obj.msg. + + # ------------------------------------------------------------------ + + class TypicalObject + end + + def test_sending_undefined_messages_to_a_typical_object_results_in_errors + typical = TypicalObject.new + + exception = assert_raise(___) do + typical.foobar + end + assert_match(/foobar/, exception.message) + end + + def test_calling_method_missing_causes_the_no_method_error + typical = TypicalObject.new + + exception = assert_raise(___) do + typical.method_missing(:foobar) + end + assert_match(/foobar/, exception.message) + + # THINK ABOUT IT: + # + # If the method :method_missing causes the NoMethodError, then + # what would happen if we redefine method_missing? + # + # NOTE: + # + # In Ruby 1.8 the method_missing method is public and can be + # called as shown above. However, in Ruby 1.9 (and later versions) + # the method_missing method is private. We explicitly made it + # public in the testing framework so this example works in both + # versions of Ruby. Just keep in mind you can't call + # method_missing like that after Ruby 1.9 normally. + # + # Thanks. We now return you to your regularly scheduled Ruby + # Koans. + end + + # ------------------------------------------------------------------ + + class AllMessageCatcher + def method_missing(method_name, *args, &block) + "Someone called #{method_name} with <#{args.join(", ")}>" + end + end + + def test_all_messages_are_caught + catcher = AllMessageCatcher.new + + assert_equal __, catcher.foobar + assert_equal __, catcher.foobaz(1) + assert_equal __, catcher.sum(1,2,3,4,5,6) + end + + def test_catching_messages_makes_respond_to_lie + catcher = AllMessageCatcher.new + + assert_nothing_raised do + catcher.any_method + end + assert_equal __, catcher.respond_to?(:any_method) + end + + # ------------------------------------------------------------------ + + class WellBehavedFooCatcher + def method_missing(method_name, *args, &block) + if method_name.to_s[0,3] == "foo" + "Foo to you too" + else + super(method_name, *args, &block) + end + end + end + + def test_foo_method_are_caught + catcher = WellBehavedFooCatcher.new + + assert_equal __, catcher.foo_bar + assert_equal __, catcher.foo_baz + end + + def test_non_foo_messages_are_treated_normally + catcher = WellBehavedFooCatcher.new + + assert_raise(___) do + catcher.normal_undefined_method + end + end + + # ------------------------------------------------------------------ + + # (note: just reopening class from above) + class WellBehavedFooCatcher + def respond_to?(method_name) + if method_name.to_s[0,3] == "foo" + true + else + super(method_name) + end + end + end + + def test_explicitly_implementing_respond_to_lets_objects_tell_the_truth + catcher = WellBehavedFooCatcher.new + + assert_equal __, catcher.respond_to?(:foo_bar) + assert_equal __, catcher.respond_to?(:something_else) + end + +end diff --git a/code/koans/about_methods.rb b/code/koans/about_methods.rb new file mode 100644 index 0000000..5678f22 --- /dev/null +++ b/code/koans/about_methods.rb @@ -0,0 +1,151 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +def my_global_method(a,b) + a + b +end + +class AboutMethods < Neo::Koan + + def test_calling_global_methods + assert_equal __, my_global_method(2,3) + end + + def test_calling_global_methods_without_parentheses + result = my_global_method 2, 3 + assert_equal __, result + end + + # (NOTE: We are Using eval below because the example code is + # considered to be syntactically invalid). + def test_sometimes_missing_parentheses_are_ambiguous + eval "assert_equal 5, my_global_method 2, 3" # ENABLE CHECK + # + # Ruby doesn't know if you mean: + # + # assert_equal(5, my_global_method(2), 3) + # or + # assert_equal(5, my_global_method(2, 3)) + # + # Rewrite the eval string to continue. + # + end + + # NOTE: wrong number of arguments is not a SYNTAX error, but a + # runtime error. + def test_calling_global_methods_with_wrong_number_of_arguments + exception = assert_raise(___) do + my_global_method + end + assert_match(/__/, exception.message) + + exception = assert_raise(___) do + my_global_method(1,2,3) + end + assert_match(/__/, exception.message) + end + + # ------------------------------------------------------------------ + + def method_with_defaults(a, b=:default_value) + [a, b] + end + + def test_calling_with_default_values + assert_equal [1, __], method_with_defaults(1) + assert_equal [1, __], method_with_defaults(1, 2) + end + + # ------------------------------------------------------------------ + + def method_with_var_args(*args) + args + end + + def test_calling_with_variable_arguments + assert_equal __, method_with_var_args.class + assert_equal __, method_with_var_args + assert_equal __, method_with_var_args(:one) + assert_equal __, method_with_var_args(:one, :two) + end + + # ------------------------------------------------------------------ + + def method_with_explicit_return + :a_non_return_value + return :return_value + :another_non_return_value + end + + def test_method_with_explicit_return + assert_equal __, method_with_explicit_return + end + + # ------------------------------------------------------------------ + + def method_without_explicit_return + :a_non_return_value + :return_value + end + + def test_method_without_explicit_return + assert_equal __, method_without_explicit_return + end + + # ------------------------------------------------------------------ + + def my_method_in_the_same_class(a, b) + a * b + end + + def test_calling_methods_in_same_class + assert_equal __, my_method_in_the_same_class(3,4) + end + + def test_calling_methods_in_same_class_with_explicit_receiver + assert_equal __, self.my_method_in_the_same_class(3,4) + end + + # ------------------------------------------------------------------ + + def my_private_method + "a secret" + end + private :my_private_method + + def test_calling_private_methods_without_receiver + assert_equal __, my_private_method + end + + def test_calling_private_methods_with_an_explicit_receiver + exception = assert_raise(___) do + self.my_private_method + end + assert_match /__/, exception.message + end + + # ------------------------------------------------------------------ + + class Dog + def name + "Fido" + end + + private + + def tail + "tail" + end + end + + def test_calling_methods_in_other_objects_require_explicit_receiver + rover = Dog.new + assert_equal __, rover.name + end + + def test_calling_private_methods_in_other_objects + rover = Dog.new + assert_raise(___) do + rover.tail + end + end +end diff --git a/code/koans/about_modules.rb b/code/koans/about_modules.rb new file mode 100644 index 0000000..38652df --- /dev/null +++ b/code/koans/about_modules.rb @@ -0,0 +1,63 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutModules < Neo::Koan + module Nameable + def set_name(new_name) + @name = new_name + end + + def here + :in_module + end + end + + def test_cant_instantiate_modules + assert_raise(___) do + Nameable.new + end + end + + # ------------------------------------------------------------------ + + class Dog + include Nameable + + attr_reader :name + + def initialize + @name = "Fido" + end + + def bark + "WOOF" + end + + def here + :in_object + end + end + + def test_normal_methods_are_available_in_the_object + fido = Dog.new + assert_equal __, fido.bark + end + + def test_module_methods_are_also_available_in_the_object + fido = Dog.new + assert_nothing_raised do + fido.set_name("Rover") + end + end + + def test_module_methods_can_affect_instance_variables_in_the_object + fido = Dog.new + assert_equal __, fido.name + fido.set_name("Rover") + assert_equal __, fido.name + end + + def test_classes_can_override_module_methods + fido = Dog.new + assert_equal __, fido.here + end +end diff --git a/code/koans/about_nil.rb b/code/koans/about_nil.rb new file mode 100644 index 0000000..be1d5db --- /dev/null +++ b/code/koans/about_nil.rb @@ -0,0 +1,38 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutNil < Neo::Koan + def test_nil_is_an_object + assert_equal __, nil.is_a?(Object), "Unlike NULL in other languages" + end + + def test_you_dont_get_null_pointer_errors_when_calling_methods_on_nil + # What happens when you call a method that doesn't exist. The + # following begin/rescue/end code block captures the exception and + # makes some assertions about it. + begin + nil.some_method_nil_doesnt_know_about + rescue Exception => ex + # What exception has been caught? + assert_equal __, ex.class + + # What message was attached to the exception? + # (HINT: replace __ with part of the error message.) + assert_match(/__/, ex.message) + end + end + + def test_nil_has_a_few_methods_defined_on_it + assert_equal __, nil.nil? + assert_equal __, nil.to_s + assert_equal __, nil.inspect + + # THINK ABOUT IT: + # + # Is it better to use + # obj.nil? + # or + # obj == nil + # Why? + end + +end diff --git a/code/koans/about_objects.rb b/code/koans/about_objects.rb new file mode 100644 index 0000000..514fcdc --- /dev/null +++ b/code/koans/about_objects.rb @@ -0,0 +1,50 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutObjects < Neo::Koan + def test_everything_is_an_object + assert_equal __, 1.is_a?(Object) + assert_equal __, 1.5.is_a?(Object) + assert_equal __, "string".is_a?(Object) + assert_equal __, nil.is_a?(Object) + assert_equal __, Object.is_a?(Object) + end + + def test_objects_can_be_converted_to_strings + assert_equal __, 123.to_s + assert_equal __, nil.to_s + end + + def test_objects_can_be_inspected + assert_equal __, 123.inspect + assert_equal __, nil.inspect + end + + def test_every_object_has_an_id + obj = Object.new + assert_equal __, obj.object_id.class + end + + def test_every_object_has_different_id + obj = Object.new + another_obj = Object.new + assert_equal __, obj.object_id != another_obj.object_id + end + + def test_small_integers_have_fixed_ids + assert_equal __, 0.object_id + assert_equal __, 1.object_id + assert_equal __, 2.object_id + assert_equal __, 100.object_id + + # THINK ABOUT IT: + # What pattern do the object IDs for small integers follow? + end + + def test_clone_creates_a_different_object + obj = Object.new + copy = obj.clone + + assert_equal __, obj != copy + assert_equal __, obj.object_id != copy.object_id + end +end diff --git a/code/koans/about_open_classes.rb b/code/koans/about_open_classes.rb new file mode 100644 index 0000000..56d1817 --- /dev/null +++ b/code/koans/about_open_classes.rb @@ -0,0 +1,45 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutOpenClasses < Neo::Koan + class Dog + def bark + "WOOF" + end + end + + def test_as_defined_dogs_do_bark + fido = Dog.new + assert_equal __, fido.bark + end + + # ------------------------------------------------------------------ + + # Open the existing Dog class and add a new method. + class Dog + def wag + "HAPPY" + end + end + + def test_after_reopening_dogs_can_both_wag_and_bark + fido = Dog.new + assert_equal __, fido.wag + assert_equal __, fido.bark + end + + # ------------------------------------------------------------------ + + class ::Integer + def even? + (self % 2) == 0 + end + end + + def test_even_existing_built_in_classes_can_be_reopened + assert_equal __, 1.even? + assert_equal __, 2.even? + end + + # NOTE: To understand why we need the :: before Integer, you need to + # become enlightened about scope. +end diff --git a/code/koans/about_proxy_object_project.rb b/code/koans/about_proxy_object_project.rb new file mode 100644 index 0000000..36d1cf0 --- /dev/null +++ b/code/koans/about_proxy_object_project.rb @@ -0,0 +1,156 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +# Project: Create a Proxy Class +# +# In this assignment, create a proxy class (one is started for you +# below). You should be able to initialize the proxy object with any +# object. Any messages sent to the proxy object should be forwarded +# to the target object. As each message is sent, the proxy should +# record the name of the method sent. +# +# The proxy class is started for you. You will need to add a method +# missing handler and any other supporting methods. The specification +# of the Proxy class is given in the AboutProxyObjectProject koan. + +class Proxy + def initialize(target_object) + @object = target_object + # ADD MORE CODE HERE + end + + # WRITE CODE HERE +end + +# The proxy object should pass the following Koan: +# +class AboutProxyObjectProject < Neo::Koan + def test_proxy_method_returns_wrapped_object + # NOTE: The Television class is defined below + tv = Proxy.new(Television.new) + + # HINT: Proxy class is defined above, may need tweaking... + + assert tv.instance_of?(Proxy) + end + + def test_tv_methods_still_perform_their_function + tv = Proxy.new(Television.new) + + tv.channel = 10 + tv.power + + assert_equal 10, tv.channel + assert tv.on? + end + + def test_proxy_records_messages_sent_to_tv + tv = Proxy.new(Television.new) + + tv.power + tv.channel = 10 + + assert_equal [:power, :channel=], tv.messages + end + + def test_proxy_handles_invalid_messages + tv = Proxy.new(Television.new) + + assert_raise(NoMethodError) do + tv.no_such_method + end + end + + def test_proxy_reports_methods_have_been_called + tv = Proxy.new(Television.new) + + tv.power + tv.power + + assert tv.called?(:power) + assert ! tv.called?(:channel) + end + + def test_proxy_counts_method_calls + tv = Proxy.new(Television.new) + + tv.power + tv.channel = 48 + tv.power + + assert_equal 2, tv.number_of_times_called(:power) + assert_equal 1, tv.number_of_times_called(:channel=) + assert_equal 0, tv.number_of_times_called(:on?) + end + + def test_proxy_can_record_more_than_just_tv_objects + proxy = Proxy.new("Code Mash 2009") + + proxy.upcase! + result = proxy.split + + assert_equal ["CODE", "MASH", "2009"], result + assert_equal [:upcase!, :split], proxy.messages + end +end + + +# ==================================================================== +# The following code is to support the testing of the Proxy class. No +# changes should be necessary to anything below this comment. + +# Example class using in the proxy testing above. +class Television + attr_accessor :channel + + def power + if @power == :on + @power = :off + else + @power = :on + end + end + + def on? + @power == :on + end +end + +# Tests for the Television class. All of theses tests should pass. +class TelevisionTest < Neo::Koan + def test_it_turns_on + tv = Television.new + + tv.power + assert tv.on? + end + + def test_it_also_turns_off + tv = Television.new + + tv.power + tv.power + + assert ! tv.on? + end + + def test_edge_case_on_off + tv = Television.new + + tv.power + tv.power + tv.power + + assert tv.on? + + tv.power + + assert ! tv.on? + end + + def test_can_set_the_channel + tv = Television.new + + tv.channel = 11 + assert_equal 11, tv.channel + end +end diff --git a/code/koans/about_regular_expressions.rb b/code/koans/about_regular_expressions.rb new file mode 100644 index 0000000..b1b47a2 --- /dev/null +++ b/code/koans/about_regular_expressions.rb @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutRegularExpressions < Neo::Koan + def test_a_pattern_is_a_regular_expression + assert_equal __, /pattern/.class + end + + def test_a_regexp_can_search_a_string_for_matching_content + assert_equal __, "some matching content"[/match/] + end + + def test_a_failed_match_returns_nil + assert_equal __, "some matching content"[/missing/] + end + + # ------------------------------------------------------------------ + + def test_question_mark_means_optional + assert_equal __, "abbcccddddeeeee"[/ab?/] + assert_equal __, "abbcccddddeeeee"[/az?/] + end + + def test_plus_means_one_or_more + assert_equal __, "abbcccddddeeeee"[/bc+/] + end + + def test_asterisk_means_zero_or_more + assert_equal __, "abbcccddddeeeee"[/ab*/] + assert_equal __, "abbcccddddeeeee"[/az*/] + assert_equal __, "abbcccddddeeeee"[/z*/] + + # THINK ABOUT IT: + # + # When would * fail to match? + end + + # THINK ABOUT IT: + # + # We say that the repetition operators above are "greedy." + # + # Why? + + # ------------------------------------------------------------------ + + def test_the_left_most_match_wins + assert_equal __, "abbccc az"[/az*/] + end + + # ------------------------------------------------------------------ + + def test_character_classes_give_options_for_a_character + animals = ["cat", "bat", "rat", "zat"] + assert_equal __, animals.select { |a| a[/[cbr]at/] } + end + + def test_slash_d_is_a_shortcut_for_a_digit_character_class + assert_equal __, "the number is 42"[/[0123456789]+/] + assert_equal __, "the number is 42"[/\d+/] + end + + def test_character_classes_can_include_ranges + assert_equal __, "the number is 42"[/[0-9]+/] + end + + def test_slash_s_is_a_shortcut_for_a_whitespace_character_class + assert_equal __, "space: \t\n"[/\s+/] + end + + def test_slash_w_is_a_shortcut_for_a_word_character_class + # NOTE: This is more like how a programmer might define a word. + assert_equal __, "variable_1 = 42"[/[a-zA-Z0-9_]+/] + assert_equal __, "variable_1 = 42"[/\w+/] + end + + def test_period_is_a_shortcut_for_any_non_newline_character + assert_equal __, "abc\n123"[/a.+/] + end + + def test_a_character_class_can_be_negated + assert_equal __, "the number is 42"[/[^0-9]+/] + end + + def test_shortcut_character_classes_are_negated_with_capitals + assert_equal __, "the number is 42"[/\D+/] + assert_equal __, "space: \t\n"[/\S+/] + # ... a programmer would most likely do + assert_equal __, "variable_1 = 42"[/[^a-zA-Z0-9_]+/] + assert_equal __, "variable_1 = 42"[/\W+/] + end + + # ------------------------------------------------------------------ + + def test_slash_a_anchors_to_the_start_of_the_string + assert_equal __, "start end"[/\Astart/] + assert_equal __, "start end"[/\Aend/] + end + + def test_slash_z_anchors_to_the_end_of_the_string + assert_equal __, "start end"[/end\z/] + assert_equal __, "start end"[/start\z/] + end + + def test_caret_anchors_to_the_start_of_lines + assert_equal __, "num 42\n2 lines"[/^\d+/] + end + + def test_dollar_sign_anchors_to_the_end_of_lines + assert_equal __, "2 lines\nnum 42"[/\d+$/] + end + + def test_slash_b_anchors_to_a_word_boundary + assert_equal __, "bovine vines"[/\bvine./] + end + + # ------------------------------------------------------------------ + + def test_parentheses_group_contents + assert_equal __, "ahahaha"[/(ha)+/] + end + + # ------------------------------------------------------------------ + + def test_parentheses_also_capture_matched_content_by_number + assert_equal __, "Gray, James"[/(\w+), (\w+)/, 1] + assert_equal __, "Gray, James"[/(\w+), (\w+)/, 2] + end + + def test_variables_can_also_be_used_to_access_captures + assert_equal __, "Name: Gray, James"[/(\w+), (\w+)/] + assert_equal __, $1 + assert_equal __, $2 + end + + # ------------------------------------------------------------------ + + def test_a_vertical_pipe_means_or + grays = /(James|Dana|Summer) Gray/ + assert_equal __, "James Gray"[grays] + assert_equal __, "Summer Gray"[grays, 1] + assert_equal __, "Jim Gray"[grays, 1] + end + + # THINK ABOUT IT: + # + # Explain the difference between a character class ([...]) and alternation (|). + + # ------------------------------------------------------------------ + + def test_scan_is_like_find_all + assert_equal __, "one two-three".scan(/\w+/) + end + + def test_sub_is_like_find_and_replace + assert_equal __, "one two-three".sub(/(t\w*)/) { $1[0, 1] } + end + + def test_gsub_is_like_find_and_replace_all + assert_equal __, "one two-three".gsub(/(t\w*)/) { $1[0, 1] } + end +end diff --git a/code/koans/about_sandwich_code.rb b/code/koans/about_sandwich_code.rb new file mode 100644 index 0000000..ca9c554 --- /dev/null +++ b/code/koans/about_sandwich_code.rb @@ -0,0 +1,106 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutSandwichCode < Neo::Koan + + def count_lines(file_name) + file = open(file_name) + count = 0 + while file.gets + count += 1 + end + count + ensure + file.close if file + end + + def test_counting_lines + assert_equal __, count_lines("example_file.txt") + end + + # ------------------------------------------------------------------ + + def find_line(file_name) + file = open(file_name) + while line = file.gets + return line if line.match(/e/) + end + ensure + file.close if file + end + + def test_finding_lines + assert_equal __, find_line("example_file.txt") + end + + # ------------------------------------------------------------------ + # THINK ABOUT IT: + # + # The count_lines and find_line are similar, and yet different. + # They both follow the pattern of "sandwich code". + # + # Sandwich code is code that comes in three parts: (1) the top slice + # of bread, (2) the meat, and (3) the bottom slice of bread. The + # bread part of the sandwich almost always goes together, but + # the meat part changes all the time. + # + # Because the changing part of the sandwich code is in the middle, + # abstracting the top and bottom bread slices to a library can be + # difficult in many languages. + # + # (Aside for C++ programmers: The idiom of capturing allocated + # pointers in a smart pointer constructor is an attempt to deal with + # the problem of sandwich code for resource allocation.) + # + # Consider the following code: + # + + def file_sandwich(file_name) + file = open(file_name) + yield(file) + ensure + file.close if file + end + + # Now we write: + + def count_lines2(file_name) + file_sandwich(file_name) do |file| + count = 0 + while file.gets + count += 1 + end + count + end + end + + def test_counting_lines2 + assert_equal __, count_lines2("example_file.txt") + end + + # ------------------------------------------------------------------ + + def find_line2(file_name) + # Rewrite find_line using the file_sandwich library function. + end + + def test_finding_lines2 + assert_equal __, find_line2("example_file.txt") + end + + # ------------------------------------------------------------------ + + def count_lines3(file_name) + open(file_name) do |file| + count = 0 + while file.gets + count += 1 + end + count + end + end + + def test_open_handles_the_file_sandwich_when_given_a_block + assert_equal __, count_lines3("example_file.txt") + end + +end diff --git a/code/koans/about_scope.rb b/code/koans/about_scope.rb new file mode 100644 index 0000000..451e98b --- /dev/null +++ b/code/koans/about_scope.rb @@ -0,0 +1,79 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutScope < Neo::Koan + module Jims + class Dog + def identify + :jims_dog + end + end + end + + module Joes + class Dog + def identify + :joes_dog + end + end + end + + def test_dog_is_not_available_in_the_current_scope + assert_raise(___) do + Dog.new + end + end + + def test_you_can_reference_nested_classes_using_the_scope_operator + fido = Jims::Dog.new + rover = Joes::Dog.new + assert_equal __, fido.identify + assert_equal __, rover.identify + + assert_equal __, fido.class != rover.class + assert_equal __, Jims::Dog != Joes::Dog + end + + # ------------------------------------------------------------------ + + class String + end + + def test_bare_bones_class_names_assume_the_current_scope + assert_equal __, AboutScope::String == String + end + + def test_nested_string_is_not_the_same_as_the_system_string + assert_equal __, String == "HI".class + end + + def test_use_the_prefix_scope_operator_to_force_the_global_scope + assert_equal __, ::String == "HI".class + end + + # ------------------------------------------------------------------ + + PI = 3.1416 + + def test_constants_are_defined_with_an_initial_uppercase_letter + assert_equal __, PI + end + + # ------------------------------------------------------------------ + + MyString = ::String + + def test_class_names_are_just_constants + assert_equal __, MyString == ::String + assert_equal __, MyString == "HI".class + end + + def test_constants_can_be_looked_up_explicitly + assert_equal __, PI == AboutScope.const_get("PI") + assert_equal __, MyString == AboutScope.const_get("MyString") + end + + def test_you_can_get_a_list_of_constants_for_any_class_or_module + assert_equal __, Jims.constants + assert Object.constants.size > _n_ + end +end diff --git a/code/koans/about_scoring_project.rb b/code/koans/about_scoring_project.rb new file mode 100644 index 0000000..bdc5dd1 --- /dev/null +++ b/code/koans/about_scoring_project.rb @@ -0,0 +1,77 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +# Greed is a dice game where you roll up to five dice to accumulate +# points. The following "score" function will be used to calculate the +# score of a single roll of the dice. +# +# A greed roll is scored as follows: +# +# * A set of three ones is 1000 points +# +# * A set of three numbers (other than ones) is worth 100 times the +# number. (e.g. three fives is 500 points). +# +# * A one (that is not part of a set of three) is worth 100 points. +# +# * A five (that is not part of a set of three) is worth 50 points. +# +# * Everything else is worth 0 points. +# +# +# Examples: +# +# score([1,1,1,5,1]) => 1150 points +# score([2,3,4,6,2]) => 0 points +# score([3,4,5,3,3]) => 350 points +# score([1,5,1,2,4]) => 250 points +# +# More scoring examples are given in the tests below: +# +# Your goal is to write the score method. + +def score(dice) + # You need to write this method +end + +class AboutScoringProject < Neo::Koan + def test_score_of_an_empty_list_is_zero + assert_equal 0, score([]) + end + + def test_score_of_a_single_roll_of_5_is_50 + assert_equal 50, score([5]) + end + + def test_score_of_a_single_roll_of_1_is_100 + assert_equal 100, score([1]) + end + + def test_score_of_multiple_1s_and_5s_is_the_sum_of_individual_scores + assert_equal 300, score([1,5,5,1]) + end + + def test_score_of_single_2s_3s_4s_and_6s_are_zero + assert_equal 0, score([2,3,4,6]) + end + + def test_score_of_a_triple_1_is_1000 + assert_equal 1000, score([1,1,1]) + end + + def test_score_of_other_triples_is_100x + assert_equal 200, score([2,2,2]) + assert_equal 300, score([3,3,3]) + assert_equal 400, score([4,4,4]) + assert_equal 500, score([5,5,5]) + assert_equal 600, score([6,6,6]) + end + + def test_score_of_mixed_is_sum + assert_equal 250, score([2,5,2,2,3]) + assert_equal 550, score([5,5,5,5]) + assert_equal 1100, score([1,1,1,1]) + assert_equal 1200, score([1,1,1,1,1]) + assert_equal 1150, score([1,1,1,5,1]) + end + +end diff --git a/code/koans/about_strings.rb b/code/koans/about_strings.rb new file mode 100644 index 0000000..1e0ea49 --- /dev/null +++ b/code/koans/about_strings.rb @@ -0,0 +1,197 @@ +require File.expand_path(File.dirname(__FILE__) + '/neo') + +class AboutStrings < Neo::Koan + def test_double_quoted_strings_are_strings + string = "Hello, World" + assert_equal __, string.is_a?(String) + end + + def test_single_quoted_strings_are_also_strings + string = 'Goodbye, World' + assert_equal __, string.is_a?(String) + end + + def test_use_single_quotes_to_create_string_with_double_quotes + string = 'He said, "Go Away."' + assert_equal __, string + end + + def test_use_double_quotes_to_create_strings_with_single_quotes + string = "Don't" + assert_equal __, string + end + + def test_use_backslash_for_those_hard_cases + a = "He said, \"Don't\"" + b = 'He said, "Don\'t"' + assert_equal __, a == b + end + + def test_use_flexible_quoting_to_handle_really_hard_cases + a = %(flexible quotes can handle both ' and " characters) + b = %!flexible quotes can handle both ' and " characters! + c = %{flexible quotes can handle both ' and " characters} + assert_equal __, a == b + assert_equal __, a == c + end + + def test_flexible_quotes_can_handle_multiple_lines + long_string = %{ +It was the best of times, +It was the worst of times. +} + assert_equal __, long_string.length + assert_equal __, long_string.lines.count + assert_equal __, long_string[0,1] + end + + def test_here_documents_can_also_handle_multiple_lines + long_string = < 0, :black => 30, :red => 31, + :green => 32, :yellow => 33, :blue => 34, + :magenta => 35, :cyan => 36, + } + + module_function + + COLORS.each do |color, value| + module_eval "def #{color}(string); colorize(string, #{value}); end" + module_function color + end + + def colorize(string, color_value) + if use_colors? + color(color_value) + string + color(COLORS[:clear]) + else + string + end + end + + def color(color_value) + "\e[#{color_value}m" + end + + def use_colors? + return false if ENV['NO_COLOR'] + if ENV['ANSI_COLOR'].nil? + if using_windows? + using_win32console + else + return true + end + else + ENV['ANSI_COLOR'] =~ /^(t|y)/i + end + end + + def using_windows? + File::ALT_SEPARATOR + end + + def using_win32console + defined? Win32::Console + end + end + + module Assertions + FailedAssertionError = Class.new(StandardError) + + def flunk(msg) + raise FailedAssertionError, msg + end + + def assert(condition, msg=nil) + msg ||= "Failed assertion." + flunk(msg) unless condition + true + end + + def assert_equal(expected, actual, msg=nil) + msg ||= "Expected #{expected.inspect} to equal #{actual.inspect}" + assert(expected == actual, msg) + end + + def assert_not_equal(expected, actual, msg=nil) + msg ||= "Expected #{expected.inspect} to not equal #{actual.inspect}" + assert(expected != actual, msg) + end + + def assert_nil(actual, msg=nil) + msg ||= "Expected #{actual.inspect} to be nil" + assert(nil == actual, msg) + end + + def assert_not_nil(actual, msg=nil) + msg ||= "Expected #{actual.inspect} to not be nil" + assert(nil != actual, msg) + end + + def assert_match(pattern, actual, msg=nil) + msg ||= "Expected #{actual.inspect} to match #{pattern.inspect}" + assert pattern =~ actual, msg + end + + def assert_raise(exception) + begin + yield + rescue Exception => ex + expected = ex.is_a?(exception) + assert(expected, "Exception #{exception.inspect} expected, but #{ex.inspect} was raised") + return ex + end + flunk "Exception #{exception.inspect} expected, but nothing raised" + end + + def assert_nothing_raised + begin + yield + rescue Exception => ex + flunk "Expected nothing to be raised, but exception #{exception.inspect} was raised" + end + end + end + + class Sensei + attr_reader :failure, :failed_test, :pass_count + + FailedAssertionError = Assertions::FailedAssertionError + + def initialize + @pass_count = 0 + @failure = nil + @failed_test = nil + @observations = [] + end + + PROGRESS_FILE_NAME = '.path_progress' + + def add_progress(prog) + @_contents = nil + exists = File.exists?(PROGRESS_FILE_NAME) + File.open(PROGRESS_FILE_NAME,'a+') do |f| + f.print "#{',' if exists}#{prog}" + end + end + + def progress + if @_contents.nil? + if File.exists?(PROGRESS_FILE_NAME) + File.open(PROGRESS_FILE_NAME,'r') do |f| + @_contents = f.read.to_s.gsub(/\s/,'').split(',') + end + else + @_contents = [] + end + end + @_contents + end + + def observe(step) + if step.passed? + @pass_count += 1 + if @pass_count > progress.last.to_i + @observations << Color.green("#{step.koan_file}##{step.name} has expanded your awareness.") + end + else + @failed_test = step + @failure = step.failure + add_progress(@pass_count) + @observations << Color.red("#{step.koan_file}##{step.name} has damaged your karma.") + throw :neo_exit + end + end + + def failed? + ! @failure.nil? + end + + def assert_failed? + failure.is_a?(FailedAssertionError) + end + + def instruct + if failed? + @observations.each{|c| puts c } + encourage + guide_through_error + a_zenlike_statement + show_progress + else + end_screen + end + end + + def show_progress + bar_width = 50 + total_tests = Neo::Koan.total_tests + scale = bar_width.to_f/total_tests + print Color.green("your path thus far [") + happy_steps = (pass_count*scale).to_i + happy_steps = 1 if happy_steps == 0 && pass_count > 0 + print Color.green('.'*happy_steps) + if failed? + print Color.red('X') + print Color.cyan('_'*(bar_width-1-happy_steps)) + end + print Color.green(']') + print " #{pass_count}/#{total_tests}" + puts + end + + def end_screen + if Neo.simple_output + boring_end_screen + else + artistic_end_screen + end + end + + def boring_end_screen + puts "Mountains are again merely mountains" + end + + def artistic_end_screen + "JRuby 1.9.x Koans" + ruby_version = "(in #{'J' if defined?(JRUBY_VERSION)}Ruby #{defined?(JRUBY_VERSION) ? JRUBY_VERSION : RUBY_VERSION})" + ruby_version = ruby_version.side_padding(54) + completed = <<-ENDTEXT + ,, , ,, + : ::::, :::, + , ,,: :::::::::::::,, :::: : , + , ,,, ,:::::::::::::::::::, ,: ,: ,, + :, ::, , , :, ,::::::::::::::::::, ::: ,:::: + : : ::, ,:::::::: ::, ,:::: + , ,::::: :,:::::::,::::, + ,: , ,:,,: ::::::::::::: + ::,: ,,:::, ,::::::::::::, + ,:::, :,,::: ::::::::::::, + ,::: :::::::, Mountains are again merely mountains ,:::::::::::: + :::,,,:::::: :::::::::::: + ,:::::::::::, ::::::::::::, + :::::::::::, ,:::::::::::: +::::::::::::: ,:::::::::::: +:::::::::::: Ruby Koans :::::::::::: +::::::::::::#{ ruby_version },:::::::::::: +:::::::::::, , ::::::::::: +,:::::::::::::, brought to you by ,,:::::::::::: +:::::::::::::: ,:::::::::::: + ::::::::::::::, ,::::::::::::: + ::::::::::::, Neo Software Artisans , :::::::::::: + :,::::::::: :::: ::::::::::::: + ,::::::::::: ,: ,,:::::::::::::, + :::::::::::: ,::::::::::::::, + :::::::::::::::::, :::::::::::::::: + :::::::::::::::::::, :::::::::::::::: + ::::::::::::::::::::::, ,::::,:, , ::::,::: + :::::::::::::::::::::::, ::,: ::,::, ,,: :::: + ,:::::::::::::::::::: ::,, , ,, ,:::: + ,:::::::::::::::: ::,, , ,:::, + ,:::: , ,, + ,,, +ENDTEXT + puts completed + end + + def encourage + puts + puts "The Master says:" + puts Color.cyan(" You have not yet reached enlightenment.") + if ((recents = progress.last(5)) && recents.size == 5 && recents.uniq.size == 1) + puts Color.cyan(" I sense frustration. Do not be afraid to ask for help.") + elsif progress.last(2).size == 2 && progress.last(2).uniq.size == 1 + puts Color.cyan(" Do not lose hope.") + elsif progress.last.to_i > 0 + puts Color.cyan(" You are progressing. Excellent. #{progress.last} completed.") + end + end + + def guide_through_error + puts + puts "The answers you seek..." + puts Color.red(indent(failure.message).join) + puts + puts "Please meditate on the following code:" + puts embolden_first_line_only(indent(find_interesting_lines(failure.backtrace))) + puts + end + + def embolden_first_line_only(text) + first_line = true + text.collect { |t| + if first_line + first_line = false + Color.red(t) + else + Color.cyan(t) + end + } + end + + def indent(text) + text = text.split(/\n/) if text.is_a?(String) + text.collect{|t| " #{t}"} + end + + def find_interesting_lines(backtrace) + backtrace.reject { |line| + line =~ /neo\.rb/ + } + end + + # Hat's tip to Ara T. Howard for the zen statements from his + # metakoans Ruby Quiz (http://rubyquiz.com/quiz67.html) + def a_zenlike_statement + if !failed? + zen_statement = "Mountains are again merely mountains" + else + zen_statement = case (@pass_count % 10) + when 0 + "mountains are merely mountains" + when 1, 2 + "learn the rules so you know how to break them properly" + when 3, 4 + "remember that silence is sometimes the best answer" + when 5, 6 + "sleep is the best meditation" + when 7, 8 + "when you lose, don't lose the lesson" + else + "things are not what they appear to be: nor are they otherwise" + end + end + puts Color.green(zen_statement) + end + end + + class Koan + include Assertions + + attr_reader :name, :failure, :koan_count, :step_count, :koan_file + + def initialize(name, koan_file=nil, koan_count=0, step_count=0) + @name = name + @failure = nil + @koan_count = koan_count + @step_count = step_count + @koan_file = koan_file + end + + def passed? + @failure.nil? + end + + def failed(failure) + @failure = failure + end + + def setup + end + + def teardown + end + + def meditate + setup + begin + send(name) + rescue StandardError, Neo::Sensei::FailedAssertionError => ex + failed(ex) + ensure + begin + teardown + rescue StandardError, Neo::Sensei::FailedAssertionError => ex + failed(ex) if passed? + end + end + self + end + + # Class methods for the Neo test suite. + class << self + def inherited(subclass) + subclasses << subclass + end + + def method_added(name) + testmethods << name if !tests_disabled? && Koan.test_pattern =~ name.to_s + end + + def end_of_enlightenment + @tests_disabled = true + end + + def command_line(args) + args.each do |arg| + case arg + when /^-n\/(.*)\/$/ + @test_pattern = Regexp.new($1) + when /^-n(.*)$/ + @test_pattern = Regexp.new(Regexp.quote($1)) + else + if File.exist?(arg) + load(arg) + else + fail "Unknown command line argument '#{arg}'" + end + end + end + end + + # Lazy initialize list of subclasses + def subclasses + @subclasses ||= [] + end + + # Lazy initialize list of test methods. + def testmethods + @test_methods ||= [] + end + + def tests_disabled? + @tests_disabled ||= false + end + + def test_pattern + @test_pattern ||= /^test_/ + end + + def total_tests + self.subclasses.inject(0){|total, k| total + k.testmethods.size } + end + end + end + + class ThePath + def walk + sensei = Neo::Sensei.new + each_step do |step| + sensei.observe(step.meditate) + end + sensei.instruct + end + + def each_step + catch(:neo_exit) { + step_count = 0 + Neo::Koan.subclasses.each_with_index do |koan,koan_index| + koan.testmethods.each do |method_name| + step = koan.new(method_name, koan.to_s, koan_index+1, step_count+=1) + yield step + end + end + } + end + end +end + +END { + Neo::Koan.command_line(ARGV) + Neo::ThePath.new.walk +} diff --git a/code/koans/path_to_enlightenment.rb b/code/koans/path_to_enlightenment.rb new file mode 100644 index 0000000..9e8ccbe --- /dev/null +++ b/code/koans/path_to_enlightenment.rb @@ -0,0 +1,41 @@ +# The path to Ruby Enlightenment starts with the following: + +$LOAD_PATH << File.dirname(__FILE__) + +require 'about_asserts' +require 'about_nil' +require 'about_objects' +require 'about_arrays' +require 'about_array_assignment' +require 'about_hashes' +require 'about_strings' +require 'about_symbols' +require 'about_regular_expressions' +require 'about_methods' +in_ruby_version("2") do + require 'about_keyword_arguments' +end +require 'about_constants' +require 'about_control_statements' +require 'about_true_and_false' +require 'about_triangle_project' +require 'about_exceptions' +require 'about_triangle_project_2' +require 'about_iteration' +require 'about_blocks' +require 'about_sandwich_code' +require 'about_scoring_project' +require 'about_classes' +require 'about_open_classes' +require 'about_dice_project' +require 'about_inheritance' +require 'about_modules' +require 'about_scope' +require 'about_class_methods' +require 'about_message_passing' +require 'about_proxy_object_project' +require 'about_to_str' +in_ruby_version("jruby") do + require 'about_java_interop' +end +require 'about_extra_credit' diff --git a/code/koans/triangle.rb b/code/koans/triangle.rb new file mode 100644 index 0000000..8df052a --- /dev/null +++ b/code/koans/triangle.rb @@ -0,0 +1,22 @@ +# Triangle Project Code. + +# Triangle analyzes the lengths of the sides of a triangle +# (represented by a, b and c) and returns the type of triangle. +# +# It returns: +# :equilateral if all sides are equal +# :isosceles if exactly 2 sides are equal +# :scalene if no sides are equal +# +# The tests for this method can be found in +# about_triangle_project.rb +# and +# about_triangle_project_2.rb +# +def triangle(a, b, c) + # WRITE THIS CODE +end + +# Error class used in part 2. No need to change this code. +class TriangleError < StandardError +end diff --git a/code/koans/versioning_spec.rb b/code/koans/versioning_spec.rb new file mode 100644 index 0000000..44cc763 --- /dev/null +++ b/code/koans/versioning_spec.rb @@ -0,0 +1,29 @@ + +def version_ints(version) + version.split(".").map { |v| v.to_i } +end + +def at_least_ruby_version(version) + vints = version_ints(version) + ruby_vints = version_ints(RUBY_VERSION) + vints.zip(ruby_vints).all? { |v, rv| v.nil? || rv.nil? || v >= rv } +end + + +require 'rspec/given' + +describe "#version_ints" do + Then { version_ints("1.2") == [1, 2] } + Then { version_ints("2.1.20") == [2, 1, 20] } +end + +describe "at_least_ruby_version" do + Then { at_least_ruby_version("2") } + Then { at_least_ruby_version("2.0") } + Then { at_least_ruby_version("2.0.1") } + Then { at_least_ruby_version("2.1") } + Then { at_least_ruby_version("2.1.3.4.1") } + + Then { ! at_least_ruby_version("1.9") } + Then { ! at_least_ruby_version("1.9.9.9.9") } +end From 7e20591d6654305d7e11275b5bc33714cd01f9d8 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 14:28:19 -0500 Subject: [PATCH 17/59] Create and commit wolfpack.rb file --- code/wolfpack.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 code/wolfpack.rb diff --git a/code/wolfpack.rb b/code/wolfpack.rb new file mode 100644 index 0000000..e69de29 From 7a764540bd3f6287a0d4fc8dcb912576560906a2 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 14:29:23 -0500 Subject: [PATCH 18/59] Create and commit wolf_test.rb file --- code/wolf_test.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 code/wolf_test.rb diff --git a/code/wolf_test.rb b/code/wolf_test.rb new file mode 100644 index 0000000..e69de29 From c0b0efa0fa33aec6056a6e405a44fc12b32f2f9a Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 14:30:11 -0500 Subject: [PATCH 19/59] Create and commit wolfpack_test.rb file --- code/wolfpack_test.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 code/wolfpack_test.rb diff --git a/code/wolfpack_test.rb b/code/wolfpack_test.rb new file mode 100644 index 0000000..e69de29 From 3303c7bf3d3953764f1ed5dd7ffd5ec7d1fa0f91 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 14:32:48 -0500 Subject: [PATCH 20/59] Create and commit empty code/card.rb file --- code/card.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 code/card.rb diff --git a/code/card.rb b/code/card.rb new file mode 100644 index 0000000..e69de29 From 38426281292a83b49ed1d54dfd99b7067f14f889 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 14:33:57 -0500 Subject: [PATCH 21/59] Create and commit empty card_test.rb file --- code/card_test.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 code/card_test.rb diff --git a/code/card_test.rb b/code/card_test.rb new file mode 100644 index 0000000..e69de29 From a327a7565ccc14938f3d4d6897fd120b8f2b85b3 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 14:48:46 -0500 Subject: [PATCH 22/59] Add attr_accessor for :name, :age. Define initialize --- code/wolf.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/code/wolf.rb b/code/wolf.rb index e69de29..0dbcea2 100644 --- a/code/wolf.rb +++ b/code/wolf.rb @@ -0,0 +1,9 @@ +class Wolf + attr_accessor :name, :age + + def initialize(name,age) + @name = name + @age = age + end + + end \ No newline at end of file From cb65715252a545005b84ccec94ac9915bbbd6caa Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 14:51:41 -0500 Subject: [PATCH 23/59] Require minitest/autorun and ./wolf. --- code/wolf_test.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/code/wolf_test.rb b/code/wolf_test.rb index e69de29..d205bd9 100644 --- a/code/wolf_test.rb +++ b/code/wolf_test.rb @@ -0,0 +1,12 @@ +require 'minitest/autorun' +#require 'minitest/pride' +require './wolf' + +#Wolf has a name and age +#Wolf can join a pack +#Wolf can howl +#wolf can how louder if older than 3 than if it's younger + +class TestWolf < MiniTest::Unit::TestCase + +end \ No newline at end of file From d959fcee2366b948c3e76c9dd6d65e9368bcfb72 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 14:53:02 -0500 Subject: [PATCH 24/59] Add class Wolfpack. Comment out attr_accessor and initialize. --- code/wolfpack.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/wolfpack.rb b/code/wolfpack.rb index e69de29..e5ee0b3 100644 --- a/code/wolfpack.rb +++ b/code/wolfpack.rb @@ -0,0 +1,5 @@ +class Wolfpack + #attr_accessor + # def initialize + + # end \ No newline at end of file From c6a1d1d419cd23f5a43aa53a3de7a19551225a4f Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 18:08:54 -0500 Subject: [PATCH 25/59] Add join_pack, howl, howl_louder, submissive_to and dominant_to methods. Test all methods. --- code/wolf.rb | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/code/wolf.rb b/code/wolf.rb index 0dbcea2..bf8b226 100644 --- a/code/wolf.rb +++ b/code/wolf.rb @@ -1,9 +1,47 @@ +#Wolf has a name and age +#Wolf can join a pack +#Wolf can howl +#Wolf can how louder if older than 3 than if it's younger + class Wolf - attr_accessor :name, :age + attr_accessor :name, :age, :wolf def initialize(name,age) @name = name @age = age end - end \ No newline at end of file + def join_pack + true + end + + def howl + "howwwlllll!" + end + + def howl_louder + if self.age > 3 + "HOWWWWWWLLLLLL!" + else + "#{@name} is too young to howl any louder!" + end + end + + + def submissive_to(wolf) + if self.age < wolf.age + true + else + false + end + end + + + def dominant_to(wolf) + if self.age > wolf.age + true + else + false + end + end + end From 1bbcc2968fdcf3510b05434f2269850f9a4fdc48 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Mon, 12 Jan 2015 18:09:30 -0500 Subject: [PATCH 26/59] Test all wolf.rb methods with success. --- code/wolf_test.rb | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/code/wolf_test.rb b/code/wolf_test.rb index d205bd9..91c47b1 100644 --- a/code/wolf_test.rb +++ b/code/wolf_test.rb @@ -9,4 +9,35 @@ class TestWolf < MiniTest::Unit::TestCase + def setup #this runs before each test + @wolf = Wolf.new('wolfie', 23) + end + + def test_wolf_exists + assert @wolf + end + + def test_wolf_can_howl + assert_equal "howwwlllll!", @wolf.howl + end + + def test_wolf_can_howl_louder + assert_equal "HOWWWWWWLLLLLL!", @wolf.howl_louder + end + + def test_wolf_can_join_pack + assert_equal true, @wolf.join_pack + end + + def test_wolf_is_dominant_to + wolfram = Wolf.new('wolfram', 45) + assert_equal false, @wolf.dominant_to(wolfram) + end + + def test_wolf_is_submissive_to + wolfram = Wolf.new('wolfram', 45) + assert_equal true, @wolf.submissive_to(wolfram) + end + + end \ No newline at end of file From ed006f0c9a3176bc8ed61c3c50e84ac0fa567dfa Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Tue, 13 Jan 2015 06:36:59 -0500 Subject: [PATCH 27/59] Add join_pack method. --- code/wolf.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/code/wolf.rb b/code/wolf.rb index bf8b226..6a8d49b 100644 --- a/code/wolf.rb +++ b/code/wolf.rb @@ -4,15 +4,12 @@ #Wolf can how louder if older than 3 than if it's younger class Wolf - attr_accessor :name, :age, :wolf + attr_accessor :name, :age, :wolf, :wolves def initialize(name,age) @name = name @age = age - end - - def join_pack - true + @wolves = wolves end def howl @@ -44,4 +41,9 @@ def dominant_to(wolf) false end end + + def join_pack + @wolves = [] unless @wolves + @wolves << @name end +end From 396b04894ce04433af973dea7d932b11f4377bb7 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Tue, 13 Jan 2015 06:38:18 -0500 Subject: [PATCH 28/59] Add test_wolf_can_join_pack and run tests. 6 Assertions, 0 Errors, O Failures. --- code/wolf_test.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/wolf_test.rb b/code/wolf_test.rb index 91c47b1..5f4abc5 100644 --- a/code/wolf_test.rb +++ b/code/wolf_test.rb @@ -11,6 +11,7 @@ class TestWolf < MiniTest::Unit::TestCase def setup #this runs before each test @wolf = Wolf.new('wolfie', 23) + @wolves = [] end def test_wolf_exists @@ -25,10 +26,6 @@ def test_wolf_can_howl_louder assert_equal "HOWWWWWWLLLLLL!", @wolf.howl_louder end - def test_wolf_can_join_pack - assert_equal true, @wolf.join_pack - end - def test_wolf_is_dominant_to wolfram = Wolf.new('wolfram', 45) assert_equal false, @wolf.dominant_to(wolfram) @@ -39,5 +36,9 @@ def test_wolf_is_submissive_to assert_equal true, @wolf.submissive_to(wolfram) end + def test_wolf_can_join_pack + assert_equal ['wolfie'], @wolf.join_pack + end + end \ No newline at end of file From 12f4c923b22567769e180a474e6bd7f73563a833 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Tue, 13 Jan 2015 07:11:56 -0500 Subject: [PATCH 29/59] Complete about_array_assignment --- code/koans/about_array_assignment.rb | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/code/koans/about_array_assignment.rb b/code/koans/about_array_assignment.rb index 87186ff..b54072e 100644 --- a/code/koans/about_array_assignment.rb +++ b/code/koans/about_array_assignment.rb @@ -3,49 +3,49 @@ class AboutArrayAssignment < Neo::Koan def test_non_parallel_assignment names = ["John", "Smith"] - assert_equal __, names + assert_equal ["John","Smith"], names end def test_parallel_assignments first_name, last_name = ["John", "Smith"] - assert_equal __, first_name - assert_equal __, last_name + assert_equal "John", first_name + assert_equal "Smith", last_name end def test_parallel_assignments_with_extra_values first_name, last_name = ["John", "Smith", "III"] - assert_equal __, first_name - assert_equal __, last_name + assert_equal "John", first_name + assert_equal "Smith", last_name end def test_parallel_assignments_with_splat_operator first_name, *last_name = ["John", "Smith", "III"] - assert_equal __, first_name - assert_equal __, last_name + assert_equal "John", first_name + assert_equal ["Smith","III"], last_name end def test_parallel_assignments_with_too_few_variables first_name, last_name = ["Cher"] - assert_equal __, first_name - assert_equal __, last_name + assert_equal "Cher", first_name + assert_equal nil, last_name end def test_parallel_assignments_with_subarrays first_name, last_name = [["Willie", "Rae"], "Johnson"] - assert_equal __, first_name - assert_equal __, last_name + assert_equal ["Willie","Rae"], first_name + assert_equal "Johnson", last_name end def test_parallel_assignment_with_one_variable first_name, = ["John", "Smith"] - assert_equal __, first_name + assert_equal "John", first_name end def test_swapping_with_parallel_assignment first_name = "Roy" last_name = "Rob" first_name, last_name = last_name, first_name - assert_equal __, first_name - assert_equal __, last_name + assert_equal "Rob", first_name + assert_equal "Roy", last_name end end From c68323850007f15082289985e79cebf9391f8de1 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Tue, 13 Jan 2015 07:26:34 -0500 Subject: [PATCH 30/59] Complete about_arrays --- code/koans/about_arrays.rb | 60 +++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/code/koans/about_arrays.rb b/code/koans/about_arrays.rb index ce9b46e..5910ca4 100644 --- a/code/koans/about_arrays.rb +++ b/code/koans/about_arrays.rb @@ -3,8 +3,8 @@ class AboutArrays < Neo::Koan def test_creating_arrays empty_array = Array.new - assert_equal __, empty_array.class - assert_equal __, empty_array.size + assert_equal Array, empty_array.class + assert_equal 0, empty_array.size end def test_array_literals @@ -15,70 +15,70 @@ def test_array_literals assert_equal [1], array array[1] = 2 - assert_equal [1, __], array + assert_equal [1, 2], array array << 333 - assert_equal __, array + assert_equal [1,2,333], array end def test_accessing_array_elements array = [:peanut, :butter, :and, :jelly] - assert_equal __, array[0] - assert_equal __, array.first - assert_equal __, array[3] - assert_equal __, array.last - assert_equal __, array[-1] - assert_equal __, array[-3] + assert_equal :peanut, array[0] + assert_equal :peanut, array.first + assert_equal :jelly, array[3] + assert_equal :jelly, array.last + assert_equal :jelly, array[-1] + assert_equal :butter, array[-3] end def test_slicing_arrays array = [:peanut, :butter, :and, :jelly] - assert_equal __, array[0,1] - assert_equal __, array[0,2] - assert_equal __, array[2,2] - assert_equal __, array[2,20] - assert_equal __, array[4,0] - assert_equal __, array[4,100] - assert_equal __, array[5,0] + assert_equal [:peanut], array[0,1] + assert_equal [:peanut,:butter], array[0,2] + assert_equal [:and,:jelly], array[2,2] + assert_equal [:and,:jelly], array[2,20] + assert_equal [], array[4,0] + assert_equal [], array[4,100] + assert_equal nil, array[5,0] end def test_arrays_and_ranges - assert_equal __, (1..5).class - assert_not_equal [1,2,3,4,5], (1..5) - assert_equal __, (1..5).to_a - assert_equal __, (1...5).to_a + assert_equal Range, (1..5).class + assert_not_equal [1,2,3,4], (1..5) + assert_equal [1,2,3,4,5], (1..5).to_a + assert_equal [1,2,3,4], (1...5).to_a end def test_slicing_with_ranges array = [:peanut, :butter, :and, :jelly] - assert_equal __, array[0..2] - assert_equal __, array[0...2] - assert_equal __, array[2..-1] + assert_equal [:peanut,:butter,:and], array[0..2] + assert_equal [:peanut,:butter], array[0...2] + assert_equal [:and,:jelly], array[2..-1] end def test_pushing_and_popping_arrays array = [1,2] array.push(:last) - assert_equal __, array + assert_equal [1,2,:last], array popped_value = array.pop - assert_equal __, popped_value - assert_equal __, array + assert_equal :last, popped_value + assert_equal [1,2], array end def test_shifting_arrays array = [1,2] array.unshift(:first) - assert_equal __, array + assert_equal [:first,1,2], array shifted_value = array.shift - assert_equal __, shifted_value - assert_equal __, array + assert_equal :first, shifted_value + assert_equal [1,2], array end end From 3dd00b6c19d66f78d9cfa7f5b7740d22a75fda78 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Tue, 13 Jan 2015 07:30:28 -0500 Subject: [PATCH 31/59] Create file. Add initialize. --- code/card.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/card.rb b/code/card.rb index e69de29..f39ff42 100644 --- a/code/card.rb +++ b/code/card.rb @@ -0,0 +1,8 @@ +class Card + attr_accessor :suit, :value + + def initialize(suit,value) + @suit = suit + @value = value + end + From a1516ab51929014c527e17e069e6fe93b46d31e2 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Tue, 13 Jan 2015 07:31:09 -0500 Subject: [PATCH 32/59] Create test with requiremed files. Add setup --- code/card_test.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/code/card_test.rb b/code/card_test.rb index e69de29..a9eb1b5 100644 --- a/code/card_test.rb +++ b/code/card_test.rb @@ -0,0 +1,14 @@ +require 'minitest/autorun' +#require 'minitest/pride' +require './card' + +#card + +class TestCard < MiniTest::Unit::TestCase + def setup #this runs before each test + @card = Card.new( 'hearts', 3) + end + + def test_card_exists + assert @card + end \ No newline at end of file From f784e7e5848a8033f48ec857b6c2c03442c6e23a Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Tue, 13 Jan 2015 07:33:06 -0500 Subject: [PATCH 33/59] Add display method --- code/card.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/card.rb b/code/card.rb index f39ff42..e6caf2c 100644 --- a/code/card.rb +++ b/code/card.rb @@ -6,3 +6,6 @@ def initialize(suit,value) @value = value end + def display_card + "#{@value} of #{suit}" + end \ No newline at end of file From 639c5638f62341c8249e0d08697a00dda3736ae4 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Tue, 13 Jan 2015 13:32:09 -0500 Subject: [PATCH 34/59] complete about_asserts.rb --- code/koans/about_asserts.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/koans/about_asserts.rb b/code/koans/about_asserts.rb index 5defa59..158394f 100644 --- a/code/koans/about_asserts.rb +++ b/code/koans/about_asserts.rb @@ -7,19 +7,19 @@ class AboutAsserts < Neo::Koan # We shall contemplate truth by testing reality, via asserts. def test_assert_truth - assert false # This should be true + assert true # This should be true end # Enlightenment may be more easily achieved with appropriate # messages. def test_assert_with_message - assert false, "This should be true -- Please fix this" + assert true, "This should be true -- Please fix this" end # To understand reality, we must compare our expectations against # reality. def test_assert_equality - expected_value = __ + expected_value = 2 actual_value = 1 + 1 assert expected_value == actual_value @@ -27,7 +27,7 @@ def test_assert_equality # Some ways of asserting equality are better than others. def test_a_better_way_of_asserting_equality - expected_value = __ + expected_value = 2 actual_value = 1 + 1 assert_equal expected_value, actual_value @@ -35,6 +35,6 @@ def test_a_better_way_of_asserting_equality # Sometimes we will ask you to fill in the values def test_fill_in_values - assert_equal __, 1 + 1 + assert_equal 2, 1 + 1 end end From 862f3868185dda6b7ed3c41097bbc008e792432a Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Tue, 13 Jan 2015 13:45:16 -0500 Subject: [PATCH 35/59] complete about_blocks.rb. --- code/koans/about_blocks.rb | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/code/koans/about_blocks.rb b/code/koans/about_blocks.rb index c02dab9..64ec2a9 100644 --- a/code/koans/about_blocks.rb +++ b/code/koans/about_blocks.rb @@ -8,12 +8,12 @@ def method_with_block def test_methods_can_take_blocks yielded_result = method_with_block { 1 + 2 } - assert_equal __, yielded_result + assert_equal 3, yielded_result end def test_blocks_can_be_defined_with_do_end_too yielded_result = method_with_block do 1 + 2 end - assert_equal __, yielded_result + assert_equal 3, yielded_result end # ------------------------------------------------------------------ @@ -24,7 +24,7 @@ def method_with_block_arguments def test_blocks_can_take_arguments method_with_block_arguments do |argument| - assert_equal __, argument + assert_equal "Jim", argument end end @@ -40,7 +40,7 @@ def many_yields def test_methods_can_call_yield_many_times result = [] many_yields { |item| result << item } - assert_equal __, result + assert_equal [:peanut,:butter,:and,:jelly], result end # ------------------------------------------------------------------ @@ -54,8 +54,8 @@ def yield_tester end def test_methods_can_see_if_they_have_been_called_with_a_block - assert_equal __, yield_tester { :with_block } - assert_equal __, yield_tester + assert_equal :with_block, yield_tester { :with_block } + assert_equal :no_block, yield_tester end # ------------------------------------------------------------------ @@ -63,21 +63,21 @@ def test_methods_can_see_if_they_have_been_called_with_a_block def test_block_can_affect_variables_in_the_code_where_they_are_created value = :initial_value method_with_block { value = :modified_in_a_block } - assert_equal __, value + assert_equal :modified_in_a_block, value end def test_blocks_can_be_assigned_to_variables_and_called_explicitly add_one = lambda { |n| n + 1 } - assert_equal __, add_one.call(10) + assert_equal 11, add_one.call(10) # Alternative calling syntax - assert_equal __, add_one[10] + assert_equal 11, add_one[10] end def test_stand_alone_blocks_can_be_passed_to_methods_expecting_blocks make_upper = lambda { |n| n.upcase } result = method_with_block_arguments(&make_upper) - assert_equal __, result + assert_equal "JIM", result end # ------------------------------------------------------------------ @@ -87,10 +87,10 @@ def method_with_explicit_block(&block) end def test_methods_can_take_an_explicit_block_argument - assert_equal __, method_with_explicit_block { |n| n * 2 } + assert_equal 20, method_with_explicit_block { |n| n * 2 } add_one = lambda { |n| n + 1 } - assert_equal __, method_with_explicit_block(&add_one) + assert_equal 11, method_with_explicit_block(&add_one) end end From 8403bc7a263797f1a19fbe73c4b985788201a12f Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Tue, 13 Jan 2015 14:39:29 -0500 Subject: [PATCH 36/59] complete about_class_methods --- code/koans/about_class_methods.rb | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/code/koans/about_class_methods.rb b/code/koans/about_class_methods.rb index 46aab74..fa8f5b5 100644 --- a/code/koans/about_class_methods.rb +++ b/code/koans/about_class_methods.rb @@ -6,24 +6,24 @@ class Dog def test_objects_are_objects fido = Dog.new - assert_equal __, fido.is_a?(Object) + assert_equal true, fido.is_a?(Object) end def test_classes_are_classes - assert_equal __, Dog.is_a?(Class) + assert_equal true, Dog.is_a?(Class) end def test_classes_are_objects_too - assert_equal __, Dog.is_a?(Object) + assert_equal true, Dog.is_a?(Object) end def test_objects_have_methods fido = Dog.new - assert fido.methods.size > _n_ + assert fido.methods.size > 4 end def test_classes_have_methods - assert Dog.methods.size > _n_ + assert Dog.methods.size > 0 end def test_you_can_define_methods_on_individual_objects @@ -31,7 +31,7 @@ def test_you_can_define_methods_on_individual_objects def fido.wag :fidos_wag end - assert_equal __, fido.wag + assert_equal :fidos_wag,fido.wag end def test_other_objects_are_not_affected_by_these_singleton_methods @@ -41,7 +41,7 @@ def fido.wag :fidos_wag end - assert_raise(___) do + assert_raise(NoMethodError) do rover.wag end end @@ -59,13 +59,13 @@ def Dog2.wag end def test_since_classes_are_objects_you_can_define_singleton_methods_on_them_too - assert_equal __, Dog2.wag + assert_equal :class_level_wag, Dog2.wag end def test_class_methods_are_independent_of_instance_methods fido = Dog2.new - assert_equal __, fido.wag - assert_equal __, Dog2.wag + assert_equal :instance_level_wag, fido.wag + assert_equal :class_level_wag, Dog2.wag end # ------------------------------------------------------------------ @@ -81,8 +81,8 @@ def Dog.name def test_classes_and_instances_do_not_share_instance_variables fido = Dog.new fido.name = "Fido" - assert_equal __, fido.name - assert_equal __, Dog.name + assert_equal "Fido", fido.name + assert_equal nil, Dog.name end # ------------------------------------------------------------------ @@ -94,7 +94,7 @@ def Dog.a_class_method end def test_you_can_define_class_methods_inside_the_class - assert_equal __, Dog.a_class_method + assert_equal :dogs_class_method, Dog.a_class_method end # ------------------------------------------------------------------ @@ -104,7 +104,7 @@ def test_you_can_define_class_methods_inside_the_class end def test_class_statements_return_the_value_of_their_last_expression - assert_equal __, LastExpressionInClassStatement + assert_equal 21, LastExpressionInClassStatement end # ------------------------------------------------------------------ @@ -114,7 +114,7 @@ def test_class_statements_return_the_value_of_their_last_expression end def test_self_while_inside_class_is_class_object_not_instance - assert_equal __, Dog == SelfInsideOfClassStatement + assert_equal true, Dog == SelfInsideOfClassStatement end # ------------------------------------------------------------------ @@ -126,7 +126,7 @@ def self.class_method2 end def test_you_can_use_self_instead_of_an_explicit_reference_to_dog - assert_equal __, Dog.class_method2 + assert_equal :another_way_to_write_class_methods, Dog.class_method2 end # ------------------------------------------------------------------ @@ -140,7 +140,7 @@ def another_class_method end def test_heres_still_another_way_to_write_class_methods - assert_equal __, Dog.another_class_method + assert_equal :still_another_way, Dog.another_class_method end # THINK ABOUT IT: @@ -163,7 +163,7 @@ def test_heres_still_another_way_to_write_class_methods def test_heres_an_easy_way_to_call_class_methods_from_instance_methods fido = Dog.new - assert_equal __, fido.class.another_class_method + assert_equal :still_another_way, fido.class.another_class_method end end From d63ab2d1648090b0001deba66ee756270dca8180 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Tue, 13 Jan 2015 15:26:32 -0500 Subject: [PATCH 37/59] complete about_classes --- code/koans/about_classes.rb | 44 ++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/code/koans/about_classes.rb b/code/koans/about_classes.rb index 1d146be..ac121ab 100644 --- a/code/koans/about_classes.rb +++ b/code/koans/about_classes.rb @@ -6,7 +6,7 @@ class Dog def test_instances_of_classes_can_be_created_with_new fido = Dog.new - assert_equal __, fido.class + assert_equal Dog, fido.class end # ------------------------------------------------------------------ @@ -19,21 +19,21 @@ def set_name(a_name) def test_instance_variables_can_be_set_by_assigning_to_them fido = Dog2.new - assert_equal __, fido.instance_variables + assert_equal [], fido.instance_variables fido.set_name("Fido") - assert_equal __, fido.instance_variables + assert_equal [:@name], fido.instance_variables end def test_instance_variables_cannot_be_accessed_outside_the_class fido = Dog2.new fido.set_name("Fido") - assert_raise(___) do + assert_raise(NoMethodError) do fido.name end - assert_raise(___) do + assert_raise(SyntaxError) do eval "fido.@name" # NOTE: Using eval because the above line is a syntax error. end @@ -43,15 +43,15 @@ def test_you_can_politely_ask_for_instance_variable_values fido = Dog2.new fido.set_name("Fido") - assert_equal __, fido.instance_variable_get("@name") + assert_equal "Fido", fido.instance_variable_get("@name") end def test_you_can_rip_the_value_out_using_instance_eval fido = Dog2.new fido.set_name("Fido") - assert_equal __, fido.instance_eval("@name") # string version - assert_equal __, fido.instance_eval { @name } # block version + assert_equal "Fido", fido.instance_eval("@name") # string version + assert_equal "Fido", fido.instance_eval { @name } # block version end # ------------------------------------------------------------------ @@ -69,7 +69,7 @@ def test_you_can_create_accessor_methods_to_return_instance_variables fido = Dog3.new fido.set_name("Fido") - assert_equal __, fido.name + assert_equal "Fido", fido.name end # ------------------------------------------------------------------ @@ -87,7 +87,7 @@ def test_attr_reader_will_automatically_define_an_accessor fido = Dog4.new fido.set_name("Fido") - assert_equal __, fido.name + assert_equal "Fido", fido.name end # ------------------------------------------------------------------ @@ -101,7 +101,7 @@ def test_attr_accessor_will_automatically_define_both_read_and_write_accessors fido = Dog5.new fido.name = "Fido" - assert_equal __, fido.name + assert_equal "Fido", fido.name end # ------------------------------------------------------------------ @@ -115,11 +115,11 @@ def initialize(initial_name) def test_initialize_provides_initial_values_for_instance_variables fido = Dog6.new("Fido") - assert_equal __, fido.name + assert_equal "Fido", fido.name end def test_args_to_new_must_match_initialize - assert_raise(___) do + assert_raise(ArgumentError) do Dog6.new end # THINK ABOUT IT: @@ -130,7 +130,7 @@ def test_different_objects_have_different_instance_variables fido = Dog6.new("Fido") rover = Dog6.new("Rover") - assert_equal __, rover.name != fido.name + assert_equal true, rover.name != fido.name end # ------------------------------------------------------------------ @@ -159,32 +159,32 @@ def test_inside_a_method_self_refers_to_the_containing_object fido = Dog7.new("Fido") fidos_self = fido.get_self - assert_equal __, fidos_self + assert_equal fido, fidos_self end def test_to_s_provides_a_string_version_of_the_object fido = Dog7.new("Fido") - assert_equal __, fido.to_s + assert_equal "Fido", fido.to_s end def test_to_s_is_used_in_string_interpolation fido = Dog7.new("Fido") - assert_equal __, "My dog is #{fido}" + assert_equal "My dog is Fido", "My dog is #{fido}" end def test_inspect_provides_a_more_complete_string_version fido = Dog7.new("Fido") - assert_equal __, fido.inspect + assert_equal "", fido.inspect end def test_all_objects_support_to_s_and_inspect array = [1,2,3] - assert_equal __, array.to_s - assert_equal __, array.inspect + assert_equal "[1, 2, 3]", array.to_s + assert_equal "[1, 2, 3]", array.inspect - assert_equal __, "STRING".to_s - assert_equal __, "STRING".inspect + assert_equal "STRING", "STRING".to_s + assert_equal "\"STRING\"", "STRING".inspect end end From e115125fd91375ab5ae1b2253c1c2935ba6ec94d Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Tue, 13 Jan 2015 15:32:26 -0500 Subject: [PATCH 38/59] complete about_constants --- code/koans/about_constants.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/code/koans/about_constants.rb b/code/koans/about_constants.rb index 68ae078..472792a 100644 --- a/code/koans/about_constants.rb +++ b/code/koans/about_constants.rb @@ -7,16 +7,16 @@ class AboutConstants < Neo::Koan C = "nested" def test_nested_constants_may_also_be_referenced_with_relative_paths - assert_equal __, C + assert_equal "nested", C end def test_top_level_constants_are_referenced_by_double_colons - assert_equal __, ::C + assert_equal "top level", ::C end def test_nested_constants_are_referenced_by_their_complete_path - assert_equal __, AboutConstants::C - assert_equal __, ::AboutConstants::C + assert_equal "nested", AboutConstants::C + assert_equal "nested", ::AboutConstants::C end # ------------------------------------------------------------------ @@ -35,7 +35,7 @@ def legs_in_nested_animal end def test_nested_classes_inherit_constants_from_enclosing_classes - assert_equal __, Animal::NestedAnimal.new.legs_in_nested_animal + assert_equal 4, Animal::NestedAnimal.new.legs_in_nested_animal end # ------------------------------------------------------------------ @@ -47,7 +47,7 @@ def legs_in_reptile end def test_subclasses_inherit_constants_from_parent_classes - assert_equal __, Reptile.new.legs_in_reptile + assert_equal 4, Reptile.new.legs_in_reptile end # ------------------------------------------------------------------ @@ -63,7 +63,7 @@ def legs_in_bird end def test_who_wins_with_both_nested_and_inherited_constants - assert_equal __, MyAnimals::Bird.new.legs_in_bird + assert_equal 2, MyAnimals::Bird.new.legs_in_bird end # QUESTION: Which has precedence: The constant in the lexical scope, @@ -78,7 +78,7 @@ def legs_in_oyster end def test_who_wins_with_explicit_scoping_on_class_definition - assert_equal __, MyAnimals::Oyster.new.legs_in_oyster + assert_equal 4, MyAnimals::Oyster.new.legs_in_oyster end # QUESTION: Now which has precedence: The constant in the lexical From 6c5aca7bf4e2408ad7898de4bd7c1185ee07b03d Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Tue, 13 Jan 2015 17:16:38 -0500 Subject: [PATCH 39/59] complete path_to_enlightenment through about_symbols --- code/koans/about_control_statements.rb | 4 +- code/koans/about_hashes.rb | 68 +++++++++++------------ code/koans/about_nil.rb | 12 ++-- code/koans/about_objects.rb | 34 ++++++------ code/koans/about_strings.rb | 76 +++++++++++++------------- code/koans/about_symbols.rb | 34 ++++++------ 6 files changed, 114 insertions(+), 114 deletions(-) diff --git a/code/koans/about_control_statements.rb b/code/koans/about_control_statements.rb index f323757..22575d8 100644 --- a/code/koans/about_control_statements.rb +++ b/code/koans/about_control_statements.rb @@ -8,7 +8,7 @@ def test_if_then_else_statements else result = :false_value end - assert_equal __, result + assert_equal :test_value, result end def test_if_then_statements @@ -16,7 +16,7 @@ def test_if_then_statements if true result = :true_value end - assert_equal __, result + assert_equal :true_value, result end def test_if_statements_return_values diff --git a/code/koans/about_hashes.rb b/code/koans/about_hashes.rb index 7287ba0..332c26e 100644 --- a/code/koans/about_hashes.rb +++ b/code/koans/about_hashes.rb @@ -3,27 +3,27 @@ class AboutHashes < Neo::Koan def test_creating_hashes empty_hash = Hash.new - assert_equal __, empty_hash.class - assert_equal(__, empty_hash) - assert_equal __, empty_hash.size + assert_equal Hash, empty_hash.class + assert_equal({}, empty_hash) + assert_equal 0, empty_hash.size end def test_hash_literals hash = { :one => "uno", :two => "dos" } - assert_equal __, hash.size + assert_equal 2, hash.size end def test_accessing_hashes hash = { :one => "uno", :two => "dos" } - assert_equal __, hash[:one] - assert_equal __, hash[:two] - assert_equal __, hash[:doesnt_exist] + assert_equal "uno", hash[:one] + assert_equal "dos", hash[:two] + assert_equal nil, hash[:doesnt_exist] end def test_accessing_hashes_with_fetch hash = { :one => "uno" } - assert_equal __, hash.fetch(:one) - assert_raise(___) do + assert_equal "uno", hash.fetch(:one) + assert_raise(Exception) do hash.fetch(:doesnt_exist) end @@ -36,8 +36,8 @@ def test_changing_hashes hash = { :one => "uno", :two => "dos" } hash[:one] = "eins" - expected = { :one => __, :two => "dos" } - assert_equal __, hash + expected = { :one => "eins", :two => "dos" } + assert_equal expected, hash # Bonus Question: Why was "expected" broken out into a variable # rather than used as a literal? @@ -47,47 +47,47 @@ def test_hash_is_unordered hash1 = { :one => "uno", :two => "dos" } hash2 = { :two => "dos", :one => "uno" } - assert_equal __, hash1 == hash2 + assert_equal true, hash1 == hash2 end def test_hash_keys hash = { :one => "uno", :two => "dos" } - assert_equal __, hash.keys.size - assert_equal __, hash.keys.include?(:one) - assert_equal __, hash.keys.include?(:two) - assert_equal __, hash.keys.class + assert_equal 2, hash.keys.size + assert_equal true, hash.keys.include?(:one) + assert_equal true, hash.keys.include?(:two) + assert_equal Array, hash.keys.class end def test_hash_values hash = { :one => "uno", :two => "dos" } - assert_equal __, hash.values.size - assert_equal __, hash.values.include?("uno") - assert_equal __, hash.values.include?("dos") - assert_equal __, hash.values.class + assert_equal 2, hash.values.size + assert_equal true, hash.values.include?("uno") + assert_equal true, hash.values.include?("dos") + assert_equal Array, hash.values.class end def test_combining_hashes hash = { "jim" => 53, "amy" => 20, "dan" => 23 } new_hash = hash.merge({ "jim" => 54, "jenny" => 26 }) - assert_equal __, hash != new_hash + assert_equal true, hash != new_hash - expected = { "jim" => __, "amy" => 20, "dan" => 23, "jenny" => __ } - assert_equal __, expected == new_hash + expected = { "jim" => 54, "amy" => 20, "dan" => 23, "jenny" => 26 } + assert_equal true, expected == new_hash end def test_default_value hash1 = Hash.new hash1[:one] = 1 - assert_equal __, hash1[:one] - assert_equal __, hash1[:two] + assert_equal 1, hash1[:one] + assert_equal nil, hash1[:two] hash2 = Hash.new("dos") hash2[:one] = 1 - assert_equal __, hash2[:one] - assert_equal __, hash2[:two] + assert_equal 1, hash2[:one] + assert_equal "dos", hash2[:two] end def test_default_value_is_the_same_object @@ -96,11 +96,11 @@ def test_default_value_is_the_same_object hash[:one] << "uno" hash[:two] << "dos" - assert_equal __, hash[:one] - assert_equal __, hash[:two] - assert_equal __, hash[:three] + assert_equal ["uno","dos"], hash[:one] + assert_equal ["uno","dos"], hash[:two] + assert_equal ["uno","dos"], hash[:three] - assert_equal __, hash[:one].object_id == hash[:two].object_id + assert_equal true, hash[:one].object_id == hash[:two].object_id end def test_default_value_with_block @@ -109,8 +109,8 @@ def test_default_value_with_block hash[:one] << "uno" hash[:two] << "dos" - assert_equal __, hash[:one] - assert_equal __, hash[:two] - assert_equal __, hash[:three] + assert_equal ["uno"], hash[:one] + assert_equal ["dos"], hash[:two] + assert_equal [], hash[:three] end end diff --git a/code/koans/about_nil.rb b/code/koans/about_nil.rb index be1d5db..8a3412d 100644 --- a/code/koans/about_nil.rb +++ b/code/koans/about_nil.rb @@ -2,7 +2,7 @@ class AboutNil < Neo::Koan def test_nil_is_an_object - assert_equal __, nil.is_a?(Object), "Unlike NULL in other languages" + assert_equal true, nil.is_a?(Object), "Unlike NULL in other languages" end def test_you_dont_get_null_pointer_errors_when_calling_methods_on_nil @@ -13,18 +13,18 @@ def test_you_dont_get_null_pointer_errors_when_calling_methods_on_nil nil.some_method_nil_doesnt_know_about rescue Exception => ex # What exception has been caught? - assert_equal __, ex.class + assert_equal NoMethodError, ex.class # What message was attached to the exception? # (HINT: replace __ with part of the error message.) - assert_match(/__/, ex.message) + assert_match(/undefined method/, ex.message) end end def test_nil_has_a_few_methods_defined_on_it - assert_equal __, nil.nil? - assert_equal __, nil.to_s - assert_equal __, nil.inspect + assert_equal true, nil.nil? + assert_equal "", nil.to_s + assert_equal "nil", nil.inspect # THINK ABOUT IT: # diff --git a/code/koans/about_objects.rb b/code/koans/about_objects.rb index 514fcdc..28b822c 100644 --- a/code/koans/about_objects.rb +++ b/code/koans/about_objects.rb @@ -2,39 +2,39 @@ class AboutObjects < Neo::Koan def test_everything_is_an_object - assert_equal __, 1.is_a?(Object) - assert_equal __, 1.5.is_a?(Object) - assert_equal __, "string".is_a?(Object) - assert_equal __, nil.is_a?(Object) - assert_equal __, Object.is_a?(Object) + assert_equal true, 1.is_a?(Object) + assert_equal true, 1.5.is_a?(Object) + assert_equal true, "string".is_a?(Object) + assert_equal true, nil.is_a?(Object) + assert_equal true, Object.is_a?(Object) end def test_objects_can_be_converted_to_strings - assert_equal __, 123.to_s - assert_equal __, nil.to_s + assert_equal "123", 123.to_s + assert_equal "", nil.to_s end def test_objects_can_be_inspected - assert_equal __, 123.inspect - assert_equal __, nil.inspect + assert_equal "123", 123.inspect + assert_equal "nil", nil.inspect end def test_every_object_has_an_id obj = Object.new - assert_equal __, obj.object_id.class + assert_equal Fixnum, obj.object_id.class end def test_every_object_has_different_id obj = Object.new another_obj = Object.new - assert_equal __, obj.object_id != another_obj.object_id + assert_equal true, obj.object_id != another_obj.object_id end def test_small_integers_have_fixed_ids - assert_equal __, 0.object_id - assert_equal __, 1.object_id - assert_equal __, 2.object_id - assert_equal __, 100.object_id + assert_equal 1, 0.object_id + assert_equal 3, 1.object_id + assert_equal 5, 2.object_id + assert_equal 201, 100.object_id # THINK ABOUT IT: # What pattern do the object IDs for small integers follow? @@ -44,7 +44,7 @@ def test_clone_creates_a_different_object obj = Object.new copy = obj.clone - assert_equal __, obj != copy - assert_equal __, obj.object_id != copy.object_id + assert_equal true, obj != copy + assert_equal true, obj.object_id != copy.object_id end end diff --git a/code/koans/about_strings.rb b/code/koans/about_strings.rb index 1e0ea49..5182b87 100644 --- a/code/koans/about_strings.rb +++ b/code/koans/about_strings.rb @@ -3,36 +3,36 @@ class AboutStrings < Neo::Koan def test_double_quoted_strings_are_strings string = "Hello, World" - assert_equal __, string.is_a?(String) + assert_equal true, string.is_a?(String) end def test_single_quoted_strings_are_also_strings string = 'Goodbye, World' - assert_equal __, string.is_a?(String) + assert_equal true, string.is_a?(String) end def test_use_single_quotes_to_create_string_with_double_quotes string = 'He said, "Go Away."' - assert_equal __, string + assert_equal 'He said, "Go Away."', string end def test_use_double_quotes_to_create_strings_with_single_quotes string = "Don't" - assert_equal __, string + assert_equal "Don't", string end def test_use_backslash_for_those_hard_cases a = "He said, \"Don't\"" b = 'He said, "Don\'t"' - assert_equal __, a == b + assert_equal true, a == b end def test_use_flexible_quoting_to_handle_really_hard_cases a = %(flexible quotes can handle both ' and " characters) b = %!flexible quotes can handle both ' and " characters! c = %{flexible quotes can handle both ' and " characters} - assert_equal __, a == b - assert_equal __, a == c + assert_equal true, a == b + assert_equal true, a == c end def test_flexible_quotes_can_handle_multiple_lines @@ -40,9 +40,9 @@ def test_flexible_quotes_can_handle_multiple_lines It was the best of times, It was the worst of times. } - assert_equal __, long_string.length - assert_equal __, long_string.lines.count - assert_equal __, long_string[0,1] + assert_equal 54, long_string.length + assert_equal 3, long_string.lines.count + assert_equal "\n", long_string[0,1] end def test_here_documents_can_also_handle_multiple_lines @@ -50,29 +50,29 @@ def test_here_documents_can_also_handle_multiple_lines It was the best of times, It was the worst of times. EOS - assert_equal __, long_string.length - assert_equal __, long_string.lines.count - assert_equal __, long_string[0,1] + assert_equal 53, long_string.length + assert_equal 2, long_string.lines.count + assert_equal "I", long_string[0,1] end def test_plus_will_concatenate_two_strings string = "Hello, " + "World" - assert_equal __, string + assert_equal "Hello, World", string end def test_plus_concatenation_will_leave_the_original_strings_unmodified hi = "Hello, " there = "World" string = hi + there - assert_equal __, hi - assert_equal __, there + assert_equal "Hello, ", hi + assert_equal "World", there end def test_plus_equals_will_concatenate_to_the_end_of_a_string hi = "Hello, " there = "World" hi += there - assert_equal __, hi + assert_equal "Hello, World", hi end def test_plus_equals_also_will_leave_the_original_string_unmodified @@ -80,15 +80,15 @@ def test_plus_equals_also_will_leave_the_original_string_unmodified hi = original_string there = "World" hi += there - assert_equal __, original_string + assert_equal "Hello, ", original_string end def test_the_shovel_operator_will_also_append_content_to_a_string hi = "Hello, " there = "World" hi << there - assert_equal __, hi - assert_equal __, there + assert_equal "Hello, World", hi + assert_equal "World", there end def test_the_shovel_operator_modifies_the_original_string @@ -96,7 +96,7 @@ def test_the_shovel_operator_modifies_the_original_string hi = original_string there = "World" hi << there - assert_equal __, original_string + assert_equal "Hello, World", original_string # THINK ABOUT IT: # @@ -106,46 +106,46 @@ def test_the_shovel_operator_modifies_the_original_string def test_double_quoted_string_interpret_escape_characters string = "\n" - assert_equal __, string.size + assert_equal 1, string.size end def test_single_quoted_string_do_not_interpret_escape_characters string = '\n' - assert_equal __, string.size + assert_equal 2, string.size end def test_single_quotes_sometimes_interpret_escape_characters string = '\\\'' - assert_equal __, string.size - assert_equal __, string + assert_equal 2, string.size + assert_equal "\\'", string end def test_double_quoted_strings_interpolate_variables value = 123 string = "The value is #{value}" - assert_equal __, string + assert_equal "The value is 123", string end def test_single_quoted_strings_do_not_interpolate value = 123 string = 'The value is #{value}' - assert_equal __, string + assert_equal "The value is \#{value}", string end def test_any_ruby_expression_may_be_interpolated string = "The square root of 5 is #{Math.sqrt(5)}" - assert_equal __, string + assert_equal "The square root of 5 is 2.23606797749979", string end def test_you_can_get_a_substring_from_a_string string = "Bacon, lettuce and tomato" - assert_equal __, string[7,3] - assert_equal __, string[7..9] + assert_equal "let", string[7,3] + assert_equal "let", string[7..9] end def test_you_can_get_a_single_character_from_a_string string = "Bacon, lettuce and tomato" - assert_equal __, string[1] + assert_equal "a", string[1] # Surprised? end @@ -161,21 +161,21 @@ def test_in_older_ruby_single_characters_are_represented_by_integers in_ruby_version("1.9", "2") do def test_in_modern_ruby_single_characters_are_represented_by_strings - assert_equal __, ?a - assert_equal __, ?a == 97 + assert_equal "a", ?a + assert_equal false, ?a == 97 end end def test_strings_can_be_split string = "Sausage Egg Cheese" words = string.split - assert_equal [__, __, __], words + assert_equal ["Sausage", "Egg", "Cheese"], words end def test_strings_can_be_split_with_different_patterns string = "the:rain:in:spain" words = string.split(/:/) - assert_equal [__, __, __, __], words + assert_equal ["the","rain","in","spain"], words # NOTE: Patterns are formed from Regular Expressions. Ruby has a # very powerful Regular Expression library. We will become @@ -184,14 +184,14 @@ def test_strings_can_be_split_with_different_patterns def test_strings_can_be_joined words = ["Now", "is", "the", "time"] - assert_equal __, words.join(" ") + assert_equal "Now is the time", words.join(" ") end def test_strings_are_unique_objects a = "a string" b = "a string" - assert_equal __, a == b - assert_equal __, a.object_id == b.object_id + assert_equal true, a == b + assert_equal false, a.object_id == b.object_id end end diff --git a/code/koans/about_symbols.rb b/code/koans/about_symbols.rb index 7eea2cf..2d2d600 100644 --- a/code/koans/about_symbols.rb +++ b/code/koans/about_symbols.rb @@ -3,7 +3,7 @@ class AboutSymbols < Neo::Koan def test_symbols_are_symbols symbol = :ruby - assert_equal __, symbol.is_a?(Symbol) + assert_equal true, symbol.is_a?(Symbol) end def test_symbols_can_be_compared @@ -11,21 +11,21 @@ def test_symbols_can_be_compared symbol2 = :a_symbol symbol3 = :something_else - assert_equal __, symbol1 == symbol2 - assert_equal __, symbol1 == symbol3 + assert_equal true, symbol1 == symbol2 + assert_equal false, symbol1 == symbol3 end def test_identical_symbols_are_a_single_internal_object symbol1 = :a_symbol symbol2 = :a_symbol - assert_equal __, symbol1 == symbol2 - assert_equal __, symbol1.object_id == symbol2.object_id + assert_equal true, symbol1 == symbol2 + assert_equal true, symbol1.object_id == symbol2.object_id end def test_method_names_become_symbols symbols_as_strings = Symbol.all_symbols.map { |x| x.to_s } - assert_equal __, symbols_as_strings.include?("test_method_names_become_symbols") + assert_equal true, symbols_as_strings.include?("test_method_names_become_symbols") end # THINK ABOUT IT: @@ -38,45 +38,45 @@ def test_method_names_become_symbols def test_constants_become_symbols all_symbols_as_strings = Symbol.all_symbols.map { |x| x.to_s } - assert_equal __, all_symbols_as_strings.include?(__) + assert_equal true, all_symbols_as_strings.include?("test_constants_become_symbols") end end def test_symbols_can_be_made_from_strings string = "catsAndDogs" - assert_equal __, string.to_sym + assert_equal :catsAndDogs, string.to_sym end def test_symbols_with_spaces_can_be_built symbol = :"cats and dogs" - assert_equal __.to_sym, symbol + assert_equal "cats and dogs".to_sym, symbol end def test_symbols_with_interpolation_can_be_built value = "and" symbol = :"cats #{value} dogs" - assert_equal __.to_sym, symbol + assert_equal "cats and dogs".to_sym, symbol end def test_to_s_is_called_on_interpolated_symbols symbol = :cats string = "It is raining #{symbol} and dogs." - assert_equal __, string + assert_equal "It is raining cats and dogs.", string end def test_symbols_are_not_strings symbol = :ruby - assert_equal __, symbol.is_a?(String) - assert_equal __, symbol.eql?("ruby") + assert_equal false, symbol.is_a?(String) + assert_equal false, symbol.eql?("ruby") end def test_symbols_do_not_have_string_methods symbol = :not_a_string - assert_equal __, symbol.respond_to?(:each_char) - assert_equal __, symbol.respond_to?(:reverse) + assert_equal false, symbol.respond_to?(:each_char) + assert_equal false, symbol.respond_to?(:reverse) end # It's important to realize that symbols are not "immutable @@ -85,13 +85,13 @@ def test_symbols_do_not_have_string_methods def test_symbols_cannot_be_concatenated # Exceptions will be pondered further down the path - assert_raise(___) do + assert_raise(Exception) do :cats + :dogs end end def test_symbols_can_be_dynamically_created - assert_equal __, ("cats" + "dogs").to_sym + assert_equal :catsdogs, ("cats" + "dogs").to_sym end # THINK ABOUT IT: From 612da97089ee2dbf91add202f2556ee0e46449ae Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Wed, 14 Jan 2015 13:52:18 -0500 Subject: [PATCH 40/59] Update blackjack.rb. --- .idea/codeStyleSettings.xml | 9 +++++++++ code/array_methods.rb | 0 code/blackjack.rb | 40 +++++++++++++++++++++++++++++-------- 3 files changed, 41 insertions(+), 8 deletions(-) create mode 100644 .idea/codeStyleSettings.xml create mode 100644 code/array_methods.rb diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml new file mode 100644 index 0000000..c4c9543 --- /dev/null +++ b/.idea/codeStyleSettings.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/code/array_methods.rb b/code/array_methods.rb new file mode 100644 index 0000000..e69de29 diff --git a/code/blackjack.rb b/code/blackjack.rb index 5441b50..a1d74d1 100644 --- a/code/blackjack.rb +++ b/code/blackjack.rb @@ -1,14 +1,22 @@ class Blackjack - attr_accessor :deck, :hand, :dealer #this means we can interact with the instance variable @deck + attr_accessor :deck, :hand, :dealer,:player,:dealt_cards #this means we can interact with the instance variable @deck # and we can pretend it is a method: Blackjack.new.deck def initialize #this runs when Blackjack.new is called @deck = Deck.new @dealer = Dealer.new + @player = Player.new end - #def hand - # @hand = [] - #end + def deal + @Deck.shuffle.pop + end + + def hand + @hand = [] + 2.times do + @hand = @hand << deck.deal + end + end end class Deck @@ -26,12 +34,28 @@ def initialize end def shuffle #shuffle cards. ! changes array. - @shuffled_cards = @cards.shuffle + @shuffled_cards = @cards.shuffle! end - # def deal #remove one card from shuffled deck - possible to do yield twice to get two initial cards? - # @cards.pop - # end + def deal #remove one card from shuffled deck - possible to do yield twice to get two initial cards? + @shuffled_cards.pop + end +end + +class Player + attr_accessor :hand_total,:hand + def initialize + @hand = [] + @hand_total = 0 + end + + #def hand + # @hand = @hand << deck.deal + #end + + #def bust(hand_total) + # hand_total > 21 + #end end class Dealer From c6e3dde19ada015140edbc308a03ec1a88be1a5a Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Wed, 14 Jan 2015 13:52:45 -0500 Subject: [PATCH 41/59] update blackjack_test.rb --- code/blackjack_test.rb | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/code/blackjack_test.rb b/code/blackjack_test.rb index c062ff0..4169b79 100644 --- a/code/blackjack_test.rb +++ b/code/blackjack_test.rb @@ -11,9 +11,12 @@ class TestBlackjack < MiniTest::Unit::TestCase # A has a value of 11 #Card values: 2,3,4,5,6,7,8,9,10,10,10,10,11 (13 Cards) * 4 Suits = 52 Cards #there is one dealer + #dealer starts with empty hand + #empty hand equals 0 #there are 1+ player(s) - #the dealer deals a hand to each player and self. - #a hand is 2 random cards from the deck + #each player receives 2 cards from shuffled deck. + # for each player "deal shuffled_cards.pop times 2" + #hand total = 0, deal 2 cards, new hand total = sum of two dealt cards? #if a player's hand is less than 21, the player is given the option to hit or stay #if a player stays, the dealer moves to the next player. #if a player hits, the dealer deals one random card to the player. @@ -21,10 +24,19 @@ class TestBlackjack < MiniTest::Unit::TestCase #if new hand total is greater than 21, the player busts #if new hand total is less than 21, the player is given the option to hit or stay.(loop) #if a player's hand equals 21, player has Blackjack and the dealer moves to the next player. - #the game ends when + #Dealer and each Player, play against each other -- compare Dealer's total to Player's total. + #the game ends when there are no cards left in deck? + + #class Card + #has a suit and a value + #displaying a card should be a string, like "2 of Hearts" or "King of Spades" + #in blackjack, teh value of jack/queen/king are all 10 and ace is 11 + #nouns: deck, dealer, player, hand, - #verbs: deal, hit, stay + #verbs: deal, hit, stay, shuffle, bust + + def setup #this runs before each test @blackjack = Blackjack.new @@ -38,6 +50,14 @@ def test_deck_exists assert @blackjack.deck end + #def test_deal_method_returns_integer_from_deck + # assert + #end + + def test_hand_has_two_cards + assert_equal 2, @blackjack.hand.length + end + end class TestDeck < MiniTest::Unit::TestCase @@ -56,6 +76,16 @@ def test_shuffled_cards_not_equal_to_cards end +class TestPlayer < Minitest::Unit::TestCase + def setup + @player = Blackjack.new.player + end + + #def test_hand_dealt_has_2_cards + # assert_equal 2, @player.hand.length + #end +end + class TestDealer < MiniTest::Unit::TestCase def setup From 40e27f54dc60cc2a893c2484bb5921d45a56d59d Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Wed, 14 Jan 2015 13:54:36 -0500 Subject: [PATCH 42/59] update all so I don't lose changes when I checkout feature/03-Method_to_the_Madness --- code/wolf-wolfpack.rb | 5 +++++ code/wolf.rb | 3 +-- code/wolf_test.rb | 2 +- code/wolfpack.rb | 33 ++++++++++++++++++++++++++++++--- code/wolfpack_test.rb | 28 ++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 code/wolf-wolfpack.rb diff --git a/code/wolf-wolfpack.rb b/code/wolf-wolfpack.rb new file mode 100644 index 0000000..c922fc4 --- /dev/null +++ b/code/wolf-wolfpack.rb @@ -0,0 +1,5 @@ +access Wolf @age and @name in Wolfpack? +Compare wolf1 to wolf2? +How to add wolves to array which is pack? +Sort wolves in array by age? +Name => Age Hash diff --git a/code/wolf.rb b/code/wolf.rb index 6a8d49b..cf1cc59 100644 --- a/code/wolf.rb +++ b/code/wolf.rb @@ -9,7 +9,6 @@ class Wolf def initialize(name,age) @name = name @age = age - @wolves = wolves end def howl @@ -44,6 +43,6 @@ def dominant_to(wolf) def join_pack @wolves = [] unless @wolves - @wolves << @name + @wolves << wolf.name end end diff --git a/code/wolf_test.rb b/code/wolf_test.rb index 5f4abc5..a23224f 100644 --- a/code/wolf_test.rb +++ b/code/wolf_test.rb @@ -37,7 +37,7 @@ def test_wolf_is_submissive_to end def test_wolf_can_join_pack - assert_equal ['wolfie'], @wolf.join_pack + assert_equal ['wolfie'],@wolf.join_pack end diff --git a/code/wolfpack.rb b/code/wolfpack.rb index e5ee0b3..1e76bbe 100644 --- a/code/wolfpack.rb +++ b/code/wolfpack.rb @@ -1,5 +1,32 @@ +# Wolfpack is a group of wolves +# Oldest wolf is the leader +# If a wolf joins a pack and becomes leader, the pack throws out the former leader. +# A wolfpack can take down different sized things depending on how big it is. + # A pack of 2 wolves can hunt a gazelle + # A pack of 5 wolves can hunt a water buffalo + # A pack of 30 wolves can eat a rhinoceros + class Wolfpack - #attr_accessor - # def initialize + attr_accessor :wolves + + def initialize + @wolves = [] unless @wolves + end + + def is_leader + @wolves.sort_by(age) + end + + def can_hunt + if @wolves.length > 2 && < 5 + "The Wolfpack can hunt a gazelle! " + elsif @wolves.length > 5 && < 30 + "The Wolfpack can hunt a water buffalo" + else + @wolves.length > 30 + "The Wolfpack can hunt a rhinoceros" + end + end + - # end \ No newline at end of file + end \ No newline at end of file diff --git a/code/wolfpack_test.rb b/code/wolfpack_test.rb index e69de29..bbf1d24 100644 --- a/code/wolfpack_test.rb +++ b/code/wolfpack_test.rb @@ -0,0 +1,28 @@ +require 'minitest/autorun' +#require 'minitest/pride' +require './wolfpack' +require './wolf' + +# Wolfpack is a group of wolves +# Oldest wolf is the leader + +# If a wolf joins a pack and becomes leader, the pack throws out the former leader. +# A wolfpack can take down different sized things depending on how big it is. + # A pack of 2 wolves can hunt a gazelle + # A pack of 5 wolves can hunt a water buffalo + # A pack of 30 wolves can eat a rhinoceros + +class TestWolfpack < MiniTest::Unit::TestCase + def setup + @wolfpack = Wolfpack.new + end + + def test_wolfpack_exists + assert @wolfpack + end + + def test_more_than_one_wolf + assert_equal true, @wolfpack.wolves + end + +end \ No newline at end of file From d2379975cffc941c2c1f4447dcbd35a248d7a0a5 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Wed, 14 Jan 2015 13:55:21 -0500 Subject: [PATCH 43/59] update array methods --- code/array_methods.rb | 101 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/code/array_methods.rb b/code/array_methods.rb index e69de29..4bd3512 100644 --- a/code/array_methods.rb +++ b/code/array_methods.rb @@ -0,0 +1,101 @@ ++ #[2, 6, 8] + [ 9, 12, 13] => [2, 6, 8, 9, 12, 13] +<< #[12, 4, 13, 6] << 45 ==> [12, 4, 13, 6, 45] +== # [1, 23, 45] == [1, 23, 45] ==> true +[] # +[]= +collect(!) (aka map(!)) # an_array[1,2,3,6,5,6] an_array[1,2,3,6,5,6] +compact(!) +each #new_array = [1, 2] newer_array = [] new_array.each{|n| newer_array << n * 5} +#newer_array = [] new_array.each{|n| newer_array << n * 5 if n > 1} +empty? ## newer_array.empty? ==> false +index # [20,45,60].index(45) ==> 1 +first +flatten(!) +include? +index +join #comic_book_guy_words = %w(worst episode ever) ==> ["worst", "episode","ever"] +#comic_book_guy_words.join('!') ==>"worst!episode!ever!" +last +length (aka size) +pop +push +reject(!) #strange_array.reject{|thing| thing.is_a?String} +reverse +select(!) +shift +shuffle +sort(!) +sort_by(!) +uniq(!) +unshift +Enumerable + +all? +any? +detect +each_with_index +grep +group_by +inject +max +max_by +member? +min +min_by +partition +reduce +String + +* ++ +<< +=~ + [] +[]= + capitalize(!) +chomp(!) +downcase(!) +each_line +empty? +gsub(!) +include? +sub(!) +to_i +to_f +to_sym +Object + +class +inspect + instance_of? + is_a? + kind_of? + methods + nil? + respond_to? + send + tap + Hash + + [] + []=delete + each + each_key + each_value + empty? + fetch + has_key? + has_value? + include? + invert + keep_if + key + keys + length + merge(!) + reject(!) + select(!) + values + Range + + nested_array = \ No newline at end of file From 9020be5447f8c3f97a1aab3ca5c5511b4160a421 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Wed, 14 Jan 2015 13:55:50 -0500 Subject: [PATCH 44/59] add test to factorial.rb --- code/factorial.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/code/factorial.rb b/code/factorial.rb index a050533..a6a85b8 100644 --- a/code/factorial.rb +++ b/code/factorial.rb @@ -1,5 +1,8 @@ -def factorial(num) - (1..num).inject(1) {|a, b| a * b} # the "1" initial value allows it to work for 0 -end +class Fixnum + def factorial(num) + (1..num).inject(1) {|a, b| a * b} # the "1" initial value allows it to work for 0 + end +end -puts factorial(20) \ No newline at end of file +puts factorial(20) +puts factorial(45) \ No newline at end of file From 9bf2834a930e1b0a0c4eb65c2851f2086758cd70 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Wed, 14 Jan 2015 13:56:56 -0500 Subject: [PATCH 45/59] update num_to_words. should have already been added several branches ago. --- code/num_to_words.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/num_to_words.rb b/code/num_to_words.rb index 62f5eb2..672e9ea 100644 --- a/code/num_to_words.rb +++ b/code/num_to_words.rb @@ -47,4 +47,9 @@ def convert(number) word_equiv_result = [] num_digits_reversed = number.to_s.reverse digit_count = 0 - num_digits_reversed.chars.each_with_index do |digit, index| \ No newline at end of file + num_digits_reversed.chars.each_with_index do |digit, index| + digit_as_number = Integer(digit) + skip_zero(digit_as_number) do + if digit_count == 0 + word_equiv_result << "#{Num_to_word[digit_as_number]}" + elsif ten_to_twenty?(digit_as_number, digit_count) \ No newline at end of file From cd69ae01495b4f19ce284e4f8f9d0e2ba629165a Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Wed, 14 Jan 2015 14:29:05 -0500 Subject: [PATCH 46/59] no sure what this commit contains --- code/black_jack.rb | 0 code/black_jack_test.rb | 0 code/english_numbers.rb | 0 code/english_to_number.rb | 61 +++++++++++++++++++++++++++++++++++++++ docs/data_types.md | 15 ++++++++++ 5 files changed, 76 insertions(+) create mode 100644 code/black_jack.rb create mode 100644 code/black_jack_test.rb create mode 100644 code/english_numbers.rb create mode 100644 code/english_to_number.rb diff --git a/code/black_jack.rb b/code/black_jack.rb new file mode 100644 index 0000000..e69de29 diff --git a/code/black_jack_test.rb b/code/black_jack_test.rb new file mode 100644 index 0000000..e69de29 diff --git a/code/english_numbers.rb b/code/english_numbers.rb new file mode 100644 index 0000000..e69de29 diff --git a/code/english_to_number.rb b/code/english_to_number.rb new file mode 100644 index 0000000..098ff16 --- /dev/null +++ b/code/english_to_number.rb @@ -0,0 +1,61 @@ +# I want a function that will convert English language numbers into +# their numerical representation. +# For example: +# english_to_number('one') #=> 1 +# english_to_number('ninety six') #=> 96 +# The function should at least work up to 100. 1_000_000_000_000 would be better. + +def english_to_number(word_or_words) + if word_or_words == nil #in case recursive call has no argument + word_or_words = '' + end + number_hash = { + 'one' => 1, + 'two' => 2, + 'three' => 3, + 'four' => 4, + 'five' => 5, + 'six' => 6, + 'seven' => 7, + 'eight' => 8, + 'nine' => 9, + 'ten' => 10, + 'eleven' => 11, + 'twelve' => 12, + 'thirteen' => 13, + 'fourteen' => 14, + 'fifteen' => 15, + 'sixteen' => 16, + 'seventeen' => 17, + 'eighteen' => 18, + 'nineteen' => 19, + 'twenty' => 20, + 'thirty' => 30, + 'forty' => 40, + 'fifty' => 50, + 'sixty' => 60, + 'seventy' => 70, + 'eighty' => 80, + 'ninety' => 90 + } + if word_or_words.include?('million') + millions, remainder = word_or_words.split('million') + return english_to_number(millions) * 1_000_000 + english_to_number(remainder) + elsif word_or_words.include?('thousand') + thousands, remainder = word_or_words.split('thousand') + return english_to_number(thousands) * 1000 + english_to_number(remainder) + elsif word_or_words.include?('hundred') + hundreds, remainder = word_or_words.split('hundred') + return english_to_number(hundreds) * 100 + english_to_number(remainder) + end + array_of_words = word_or_words.split + array_of_words.inject(0){|sum, string| sum + number_hash[string]} +end + +puts english_to_number('one') #=> 1 +puts english_to_number('twenty') #=> 20 +puts english_to_number('twenty five') #=> 25 +puts english_to_number('one hundred') #=> 100 +puts english_to_number('six hundred thirty two') #=> 632 +puts english_to_number('four thousand eight hundred twelve') #=> 4812 +puts english_to_number('nine hundred seventeen million thirty six') #=> 917000036 \ No newline at end of file diff --git a/docs/data_types.md b/docs/data_types.md index b7b6b88..458c9fa 100644 --- a/docs/data_types.md +++ b/docs/data_types.md @@ -65,6 +65,21 @@ keep track of students `array = [Joe, Angela, Spencer,Kelly, Andell, Peter, Iva # You can sort an array: numbers.sort #=> [1, 2, 3, 6, 7] +<<<<<<< HEAD + + # You can use push to add to an array: + numbers.push '12' => [1, 2, 3, 6, 7, "12"] + + # You can remove items from an array with pop: + numbers.pop => "12" + + + + +``` + +======= +>>>>>>> 8965e49020640ae991075baf745a4ae885ec204f # You can use push to add to an array: numbers.push '12' => [1, 2, 3, 6, 7, "12"] From 2f679e061ec4c1c13dd94c1d5ea58bee21fab045 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Wed, 14 Jan 2015 14:36:29 -0500 Subject: [PATCH 47/59] add moguls subdirectory --- code/moguls/investment_club.rb | 12 +++++++++ code/moguls/investment_club_test.rb | 42 +++++++++++++++++++++++++++++ code/moguls/mogul.rb | 29 ++++++++++++++++++++ code/moguls/mogul_test.rb | 25 +++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 code/moguls/investment_club.rb create mode 100644 code/moguls/investment_club_test.rb create mode 100644 code/moguls/mogul.rb create mode 100644 code/moguls/mogul_test.rb diff --git a/code/moguls/investment_club.rb b/code/moguls/investment_club.rb new file mode 100644 index 0000000..991b53c --- /dev/null +++ b/code/moguls/investment_club.rb @@ -0,0 +1,12 @@ +class InvestmentClub + attr_accessor :members, :location + + def initialize(applicants,location) + @members = applicants.select{|applicant| applicant.is_a? (Mogul)} + @location = location + end + + def president + @members.max_by {|member| member.net_worth} + end +end \ No newline at end of file diff --git a/code/moguls/investment_club_test.rb b/code/moguls/investment_club_test.rb new file mode 100644 index 0000000..c09fce9 --- /dev/null +++ b/code/moguls/investment_club_test.rb @@ -0,0 +1,42 @@ +require 'minitest/autorun' +require './mogul' +require './investment_club' +# Billionaire investment club +# the investment club has mogul members +# and a snazzy meeting location +# when the club makes an investment, all the members make a billion dollars +# the richest member is President of the club +#(initially): members need to be worth > $2B to join + +class InvestmentClubTest < MiniTest::Unit::TestCase + def setup + @carlos_slim = Mogul.new("Carlos Slim", 75) + bill_gates = Mogul.new("Bill Gates", 60) + mark_zuckerberg = Mogul.new("Mark Zuckerberg", 19) + @members = [bill_gates, mark_zuckerberg, @carlos_slim] + @investment_club = InvestmentClub.new(@members, "Morocco") + end + + def test_investment_club_has_members + assert_equal @members, @investment_club.members + end + + def test_member_is_a_mogul + assert @investment_club.members[0].is_a?(Mogul) + end + + def test_club_only_allow_moguls_as_members + brian = "Brian Gates" + bill = Mogul.new("Bill Gates", 48) + ted = Mogul.new("Ted Turner", 13) + members = [brian,bill,ted] + club_with_sketchy_applicant = InvestmentClub.new(members, "Canvs") + assert_equal 2, club_with_sketchy_applicant.members.length + end + + # the richest member is president + def + assert_equal @carlos_slim, @investment_club.president + end + +end \ No newline at end of file diff --git a/code/moguls/mogul.rb b/code/moguls/mogul.rb new file mode 100644 index 0000000..684cab5 --- /dev/null +++ b/code/moguls/mogul.rb @@ -0,0 +1,29 @@ +class Mogul + attr_reader :name, :net_worth + def initialize(name,net_worth) + @name = name + @net_worth = net_worth #in billions + end + + def laughs_at?(other_mogul) + if @net_worth > other_mogul.net_worth + true + + end + true + end +end + +=begin +zuckerberg = Mogul.new('Mark Zuckerberg', 'Facebook', 24) +gates_no_relation = Mogul.new('Bill Gates', 'Microsoft', 46) +turner = Mogul.new('Ted Turner', 'CNN', 11) +rich_guys = [zuckerberg, gates_no_relation, turner] + + + ordered_rich_guys = rich_guys.sort_by {|mogul| mogul.net_worth} + last_guy = ordered_rich_guys.last + puts "#{ordered_rich_guys.last.name} is the richest dude in my list" + + puts ordered_rich_guys.last.class +=end diff --git a/code/moguls/mogul_test.rb b/code/moguls/mogul_test.rb new file mode 100644 index 0000000..1f9e59a --- /dev/null +++ b/code/moguls/mogul_test.rb @@ -0,0 +1,25 @@ +require 'minitest/autorun' +require './mogul' + +class MogulTest < MiniTest::Unit::TestCase + + #a mogul has a name and net worth + def setup + @mogul = Mogul.new("Steve Jobs", 20) + end + + def test_mogul_has_name_and_net_worth + assert_equal "Steve Jobs", @mogul.name + assert_equal 20, @mogul.net_worth + end + + def test_mogul_laughs_at_less_fortunate_mogul + less_fortunate_mogul = Mogul.new("Peter", 1) + assert_equal @mogul.laughs_at?(less_fortunate_mogul) + end + + def test_mogul_does_not_laugh_at_richer_mogul + richer_mogul = Mogul.new("Bill Gates(no relation", 42) + assert_equal @mogul.laughs_at?(richer_mogul), false + end +end From 5dff7df9b81b473ec505a10ddfe1353fbfeaa514 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Wed, 14 Jan 2015 17:03:21 -0500 Subject: [PATCH 48/59] move all wolf related files to /wolf directory --- code/black_jack.rb | 0 code/black_jack_test.rb | 0 code/day_1.rb | 162 ------------------------------- code/to_roman.rb | 75 -------------- code/{ => wolf}/wolf.rb | 0 code/{ => wolf}/wolf_test.rb | 0 code/{ => wolf}/wolfpack.rb | 0 code/{ => wolf}/wolfpack_test.rb | 0 8 files changed, 237 deletions(-) delete mode 100644 code/black_jack.rb delete mode 100644 code/black_jack_test.rb delete mode 100644 code/day_1.rb delete mode 100644 code/to_roman.rb rename code/{ => wolf}/wolf.rb (100%) rename code/{ => wolf}/wolf_test.rb (100%) rename code/{ => wolf}/wolfpack.rb (100%) rename code/{ => wolf}/wolfpack_test.rb (100%) diff --git a/code/black_jack.rb b/code/black_jack.rb deleted file mode 100644 index e69de29..0000000 diff --git a/code/black_jack_test.rb b/code/black_jack_test.rb deleted file mode 100644 index e69de29..0000000 diff --git a/code/day_1.rb b/code/day_1.rb deleted file mode 100644 index 4a26eee..0000000 --- a/code/day_1.rb +++ /dev/null @@ -1,162 +0,0 @@ -# Write code to answer each of the following questions. Show the code and, in a comment, its return value. -# Example: -# How many letters are in the word 'abbreviation'? -'abbreviation'.length #=> 12 - -# Is pi bigger than 22/7? -puts Math::PI > 22/7 #=> true - -# a person who's 6'5" is how many inches tall? -puts (6*12) + 5 #=> 77 - - -weather = "an absolutely beautiful day" -# write the shortest possible code that will print out the string "Hello! Isn't it an absolutely beautiful day today?" -puts "Hello! Isn't it " + weather + " today?" #=> "Hello! Isn't it an absolutely beautiful day today?" - -# Add a comment after the following code block showing its return value. -# Then add a second comment explaining in English what the code does. -"3 + 2 is #{3+2}" #=> "3 + 2 is 5" -# When using string interpolation, Ruby first evaluates whatever is between the #{ }, -# converts it into a string and then adds it back into the surrounding string. - -# Add a comment after the following code block showing its return value. -# Then add a second comment explaining in English why the code does what it does. -"Five is #{5 > 4 ? 'greater' : 'less'} than four." #=> "Five is greater than four." -# Ruby evaluates whether 5 > 4 is true or false. If it is true, then 'greater' is returned, if false 'less' is returned. -# And because of interpolation, the returned value is inserted back into the string. - -# Add a comment after the following code block showing its return value. -# Then add a second comment explaining in English why the code does what it does. -"Five is #{5 > 6 ? 'greater' : 'less'} than six." #=> "Five is less than six." -#If 5 is greater than 6 is true, Ruby returns 'greater' else it returns 'less' - -# Add a comment after the following code block showing its return value. -# Then add a second comment explaining in English why the code what it does. -"Five is #{5 == 100 ? '' : 'not '}the same as one hundred." #=> "Five is not the same as one hundred." -# If 5 equals 100 evaluates to true, Ruby returns an empty string and if it evaluates to false, 'not ' is returned. The returned value -# is inserted into the surrounding string. - -# Add a comment after the following code block showing its return value. -# Then add a second comment explaining in English what the code does. -[ 1, 2, 3, 4, 5].collect do |n| - n * 3 -end -#=>[3, 6, 9, 12, 15] -#Array#collect is an iterates through the array and applies the code block, n * 3 to each item in the array. - -# beginning with a list of the numbers 3, -2, 7.5, and 90, make a list containing their absolute values. -[3,-2,7.5,90].map {|a| a.abs } - -# Add a comment after the following code block showing its return value. -# Then add a second comment explaining in English what the code does. -[ 'David Rogers', 'Brian Gates', 'Jerry Seinfeld', 'Larry David' ].select do |name| - name.include?('David') -end -#=>["David Rogers", "Larry David"] -#Select is running the name.include?('David') block of code on every item in the array and it is returning -#a new object that contains only the items for which the original block returns a value of 'true'. The block of -#code is asking if "David" is included, if so, return 'true' - -# create a list of the names Joe, Kelly, Spencer, Peter, Ivan, Andell, Angela, Jeff to use for the next five tasks. -a = %w{Joe, Kelly, Spencer, Peter, Ivan, Andell, Angela, Jeff} - -# access the 5th name in the list -a[4] - -# add my name to the end of the list -a.push 'Brian' - -# make a list of the names in alphabetical order -a.sort - -# make a list of the names in reverse alphabetical order -a.sort.reverse - -# make a list of the names from shortest to longest -name_length = a.collect {|name| name.length} -name_length.sort - -# Add a comment after the following line of code showing its return value. -# Then add a second comment explaining in English what the code does. -%w(Joe Kelly Spencer Peter Ivan Andell Angela Jeff Brian).partition{|name| name.length == 5 } -#=>[["Kelly", "Peter", "Brian"], ["Joe", "Spencer", "Ivan", "Andell", "Angela", "Jeff"]] -#Partition method returns two arrays. The first array contains the elements for which the code block evaluated to true -#the second array contains the rest. - -# Split the above list of names into a group that starts with 'J' and a group that doesn't. -%w(Joe Kelly Spencer Peter Ivan Andell Angela Jeff Brian).partition{|name| name.include?('J') } - -president_birthdays = { - 'Abraham Lincoln' => 'February 12, 1809', - 'William Henry Harrison' => 'February 9, 1773', - 'George Washington' => 'February 22, 1732', - 'Ronald Reagan' => 'February 6, 1911' - } -# write code to access George Washington's birthday from the hash. -president_birthdays['George Washington'] - -# Add a comment after the following block of code showing its return value. -# Then add another comment explaining in English what the code does. -president_birthdays.each do |key, value| - puts "President #{key} was born on #{value}." -end -#=>President Abraham Lincoln was born on February 12, 1809. -#=>President William Henry Harrison was born on February 9, 1773. -#=>President George Washington was born on February 22, 1732. -#=>President Ronald Reagan was born on February 6, 1911. -#Each is a method that is iterating through the president_birthdays hash and string interpolation is used to inject the returned -#keys, value pairs into the code block's string. - -# Imagine you were talking to someone who missed today's class (and the prework). -# Write down how you would explain how to go about solving the next task. Then write code to solve it. -# Modify the code to print out only the Presidents born during the 18th century. -# First you need to establish which years made up the 18th century (1701 - 1800) -# Then, you need to select only those presidents whose birthdates fall within this time period and print the names. - -## WORK IN PROGRESS -#president_birthdays.each do |key, value| -# puts "#{value}[-4,-1]" -# century = '1701'..'1800' -# if century.include?(year) -# puts "#{key}" -# end -# end - - - - - -# Modify the code to print out only the President born during the 20th century. - -# Add James A. Garfield (born November 19, 1831) to the hash, and modify the code (if necessary) to print out only the President born during the 20th century. - -# Also add Bill Clinton (born August 19, 1946), and modify the code (if necessary) to print out the two Presidents born during the 20th century. - -# EXPERT LEVEL: modify the code to print out the Presidents in the order of their birth. - -# SUPER EXPERT LEVEL: Modify the code to print out the Presidents with February birthdays in the order their birthdays occur during the month. - -# SUPER DUPER EXPERT LEVEL: Print out the six Presidents in the order their birthdays occur during the year. - -# Create a data structure that has the numbers from one to ten that matches the -# representation of each as a word (like 'one') with the corresponding -# representation as a numeral (like 1). - - -# If you print out the names of the numbers from one to three in alphabetical order -# alongside the numeral for each, it could look like -# one (1) -# three (3) -# two (2) -# Create the same kind of print out for the numbers from one to ten. - -n = 3; puts "I have #{n} pizza#{n = 1 ? '' : 's'}" -# What is the typo in the above line, and why does it have the effect that it does? -# n= 1 is the typo. Using a single = is an assignment operator and will change the value of n from 3 to 1. The assignment operator -# will always return true and therefore the 's' needed to make the sentence gramatically correct will not be returned. -# The code block needs a comparative operator in order to work as expected. - -# Fix the typo in the above line of code. -n = 3; puts "I have #{n} pizza#{n == 1 ? '' : 's'}" - diff --git a/code/to_roman.rb b/code/to_roman.rb deleted file mode 100644 index e2a152c..0000000 --- a/code/to_roman.rb +++ /dev/null @@ -1,75 +0,0 @@ -# I want a method that will convert integers into their Roman numeral representation. -# For example: -# 3.to_roman => "III" -# 15.to_roman => "XV" - -class Fixnum - - def to_roman - if self == 0 - "" - elsif self <= 3 - "I" * self - elsif self == 4 - "IV" - elsif self <= 8 - "V" + (self - 5).to_roman - elsif self == 9 - "IX" - elsif self < 40 - "X" + (self - 10).to_roman - elsif self < 50 - "XL" + (self - 40).to_roman - elsif self < 90 - "L" + (self - 50).to_roman - elsif self < 100 - "XC" + (self - 90).to_roman - elsif self < 400 - "C" + (self - 100).to_roman - elsif self < 500 - "CD" + (self - 400).to_roman - elsif self < 900 - "D" + (self - 500 ).to_roman - elsif self < 1000 - "CM" + (self - 900).to_roman - else - "M" + (self - 1000).to_roman - end - end -end - -def test(actual_value, expectation) - if actual_value == expectation - puts "success" - else - puts "expected #{expectation} but got #{actual_value}" - end -end - -test 1.to_roman, "I" -test 2.to_roman, "II" -test 4.to_roman, "IV" -test 5.to_roman, "V" -test 6.to_roman, "VI" -test 9.to_roman, "IX" -test 10.to_roman, "X" -test 25.to_roman, "XXV" -test 40.to_roman, "XL" -test 45.to_roman, "XLV" -test 50.to_roman, "L" -test 58.to_roman, "LVIII" -test 59.to_roman, "LIX" -test 60.to_roman, "LX" -test 65.to_roman, "LXV" -test 80.to_roman, "LXXX" -test 89.to_roman, "LXXXIX" -test 90.to_roman, "XC" -test 97.to_roman, "XCVII" -test 399.to_roman, "CCCXCIX" -test 400.to_roman, "CD" -test 499.to_roman, "CDXCIX" -test 500.to_roman, "D" -test 600.to_roman, "DC" -test 799.to_roman, "DCCXCIX" -test 999.to_roman, "CMXCIX" -test 2015.to_roman, "MMXV" \ No newline at end of file diff --git a/code/wolf.rb b/code/wolf/wolf.rb similarity index 100% rename from code/wolf.rb rename to code/wolf/wolf.rb diff --git a/code/wolf_test.rb b/code/wolf/wolf_test.rb similarity index 100% rename from code/wolf_test.rb rename to code/wolf/wolf_test.rb diff --git a/code/wolfpack.rb b/code/wolf/wolfpack.rb similarity index 100% rename from code/wolfpack.rb rename to code/wolf/wolfpack.rb diff --git a/code/wolfpack_test.rb b/code/wolf/wolfpack_test.rb similarity index 100% rename from code/wolfpack_test.rb rename to code/wolf/wolfpack_test.rb From b070f50b0c1a7a1298f8bc29ba6eba5643728c14 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Wed, 14 Jan 2015 17:29:06 -0500 Subject: [PATCH 49/59] update factorial.rb and num_to_words.rb --- code/card.rb | 11 ------- code/card_test.rb | 14 --------- code/english_numbers.rb | 0 code/factorial.rb | 8 ----- code/num_to_words.rb | 55 --------------------------------- {code => docs}/array_methods.rb | 9 ++++-- 6 files changed, 6 insertions(+), 91 deletions(-) delete mode 100644 code/card.rb delete mode 100644 code/card_test.rb delete mode 100644 code/english_numbers.rb delete mode 100644 code/factorial.rb delete mode 100644 code/num_to_words.rb rename {code => docs}/array_methods.rb (89%) diff --git a/code/card.rb b/code/card.rb deleted file mode 100644 index e6caf2c..0000000 --- a/code/card.rb +++ /dev/null @@ -1,11 +0,0 @@ -class Card - attr_accessor :suit, :value - - def initialize(suit,value) - @suit = suit - @value = value - end - - def display_card - "#{@value} of #{suit}" - end \ No newline at end of file diff --git a/code/card_test.rb b/code/card_test.rb deleted file mode 100644 index a9eb1b5..0000000 --- a/code/card_test.rb +++ /dev/null @@ -1,14 +0,0 @@ -require 'minitest/autorun' -#require 'minitest/pride' -require './card' - -#card - -class TestCard < MiniTest::Unit::TestCase - def setup #this runs before each test - @card = Card.new( 'hearts', 3) - end - - def test_card_exists - assert @card - end \ No newline at end of file diff --git a/code/english_numbers.rb b/code/english_numbers.rb deleted file mode 100644 index e69de29..0000000 diff --git a/code/factorial.rb b/code/factorial.rb deleted file mode 100644 index a6a85b8..0000000 --- a/code/factorial.rb +++ /dev/null @@ -1,8 +0,0 @@ -class Fixnum - def factorial(num) - (1..num).inject(1) {|a, b| a * b} # the "1" initial value allows it to work for 0 - end -end - -puts factorial(20) -puts factorial(45) \ No newline at end of file diff --git a/code/num_to_words.rb b/code/num_to_words.rb deleted file mode 100644 index 672e9ea..0000000 --- a/code/num_to_words.rb +++ /dev/null @@ -1,55 +0,0 @@ -# Converting integers to their English equivalent is similar to the to_roman.rb #code in that we must first come up with the unique integers. -# 1. List unique -# 2. Return "zero" if number == 0 -# 3. Need array to hold the integers that are converted. -# 4. -# -# - -Num_to_word = { -1 => "one", -2 => "two", -3 => "three", -4 => "four", -5 => "five", -6 => "six", -7 => "seven", -8 => "eight", -9 => "nine", -10 => "ten", -11 => "eleven", -12 => "twelve", -13 => "thirteen", -14 => "fourteen", -15 => "fifteen", -16 => "sixteen", -17 => "seventeen", -18 => "eighteen", -19 => "nineteen", -20 => "twenty", -30 => "thirty", -40 => "forty", -50 => "fifty", -60 => "sixty", -70 => "seventy", -80 => "eighty", -90 => "ninety", -100 => "hundred", -1000 => "thousand", -1000000 => "million", -1000000000 => "billion", -} - -class Int_To_Eng_Wrd - class << self - def convert(number) - return "zero" if number == 0 - word_equiv_result = [] - num_digits_reversed = number.to_s.reverse - digit_count = 0 - num_digits_reversed.chars.each_with_index do |digit, index| - digit_as_number = Integer(digit) - skip_zero(digit_as_number) do - if digit_count == 0 - word_equiv_result << "#{Num_to_word[digit_as_number]}" - elsif ten_to_twenty?(digit_as_number, digit_count) \ No newline at end of file diff --git a/code/array_methods.rb b/docs/array_methods.rb similarity index 89% rename from code/array_methods.rb rename to docs/array_methods.rb index 4bd3512..914ab02 100644 --- a/code/array_methods.rb +++ b/docs/array_methods.rb @@ -1,6 +1,9 @@ -+ #[2, 6, 8] + [ 9, 12, 13] => [2, 6, 8, 9, 12, 13] -<< #[12, 4, 13, 6] << 45 ==> [12, 4, 13, 6, 45] -== # [1, 23, 45] == [1, 23, 45] ==> true ++ +[2, 6, 8] + [ 9, 12, 13] #=> [2, 6, 8, 9, 12, 13] +<< +[12, 4, 13, 6] << 45 #==> [12, 4, 13, 6, 45] +== +# [1, 23, 45] == [1, 23, 45] ==> true [] # []= collect(!) (aka map(!)) # an_array[1,2,3,6,5,6] an_array[1,2,3,6,5,6] From f2287b9a2b9cbf1ce912ef088cc96f45099b3ea3 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Thu, 15 Jan 2015 00:32:50 -0500 Subject: [PATCH 50/59] Delete data_types.md --- data_types.md | 59 --------------------------------------------------- 1 file changed, 59 deletions(-) delete mode 100644 data_types.md diff --git a/data_types.md b/data_types.md deleted file mode 100644 index 9650a41..0000000 --- a/data_types.md +++ /dev/null @@ -1,59 +0,0 @@ -Data Types -=================== -### `Numbers` -* **What does it mean?** Numbers can be integers or floats. Integers are numbers without decimal points and floats are numbers with decimal points -* **How do you make one?** `7` #integer `8.0` #float. -* **Why would you want one of those?** You can use numbers to perform arithmetic `5 + 6` or you can use floats as you would with a simple calculator `11.2 + 10.0` -* **What can you do with a number?** -```ruby - # You can convert it into a string: - 1543.to_s #=> 1543 - - - # You can convert it into a float: - 123.to_f #=> 123.0 - - # You can convert it into an integer: - 7654.46.to_i #=> 7654 - - # You can add, subtract, divide and multiply numbers: - 567.0 - 300 #=> 267.0 - 400 + 435 #=> 835 - 300 / 3.0 #=> 100.0 - 33 * 10 #=> 330 - - # You can get the absolute value: - -45.abs #=> 45 - -``` -### `Strings` -* **What does it mean?** Group of characters in a program including letters, numbers, symbols and spaces. -* **How do you make one?** `'I am a string!'` or `'I am a string with character :) and symbols #$(@*#)$'` -* **Why would you want one of those?** You can use strings for message output `puts 'Good Morning, Joe!'` -* **What can you do with a string?** -```ruby - # You can add it to another string: - 'I like' + ' mushrooms on my pizza!' #=> I like mushrooms on my pizza! - - # You can convert it to a float: - '123'.to_f #=> 123.0 - - # You can convert it to an integer: - '7654.46'.to_i #=> 7654 - - # You can multiply strings: - 'Ham & Cheese ' * 3 #=> Ham & Cheese Ham & Cheese Ham & Cheese - - # You can upcase, downcase and capitalize a string: - 'i want to grow up'.upcase #=> "I WANT TO GROW UP" - 'tUrn Me INto A ProPer SentencE.'.capitalize #=> "Turn me into a proper sentence" - 'STOP SHOUTING!!'.downcase #=> "stop shouting!!" - - -``` - - - - - - From 0b2488889d55acd35d8023c0b88116ec1c19e7e5 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Thu, 15 Jan 2015 05:38:56 -0500 Subject: [PATCH 51/59] clean up repo. update koans from feature/05 branch. --- .idea/codeStyleSettings.xml | 6 +- code/english_to_number.rb | 61 --- code/koans/GREED_RULES.txt | 66 --- code/koans/README.rdoc | 191 -------- code/koans/Rakefile | 12 - code/koans/about_array_assignment.rb | 0 code/koans/about_arrays.rb | 0 code/koans/about_asserts.rb | 0 code/koans/about_blocks.rb | 96 ---- code/koans/about_class_methods.rb | 169 ------- code/koans/about_classes.rb | 190 -------- code/koans/about_constants.rb | 87 ---- code/koans/about_control_statements.rb | 142 ------ code/koans/about_dice_project.rb | 63 --- code/koans/about_exceptions.rb | 68 --- code/koans/about_extra_credit.rb | 8 - code/koans/about_hashes.rb | 0 code/koans/about_inheritance.rb | 85 ---- code/koans/about_iteration.rb | 122 ------ code/koans/about_java_interop.rb | 137 ------ code/koans/about_keyword_arguments.rb | 31 -- code/koans/about_message_passing.rb | 185 -------- code/koans/about_methods.rb | 0 code/koans/about_modules.rb | 63 --- code/koans/about_nil.rb | 0 code/koans/about_objects.rb | 0 code/koans/about_open_classes.rb | 45 -- code/koans/about_proxy_object_project.rb | 156 ------- code/koans/about_regular_expressions.rb | 0 code/koans/about_sandwich_code.rb | 106 ----- code/koans/about_scope.rb | 79 ---- code/koans/about_scoring_project.rb | 77 ---- code/koans/about_strings.rb | 0 code/koans/about_symbols.rb | 0 code/koans/about_to_str.rb | 54 --- code/koans/about_triangle_project.rb | 24 - code/koans/about_triangle_project_2.rb | 16 - code/koans/about_true_and_false.rb | 33 -- code/koans/about_variable_scope.rb | 114 ----- code/koans/example_file.txt | 4 - code/koans/koans.watchr | 3 - code/koans/neo.rb | 535 ----------------------- code/koans/path_to_enlightenment.rb | 0 code/koans/triangle.rb | 22 - code/koans/versioning_spec.rb | 29 -- code/wolf-wolfpack.rb | 5 - 46 files changed, 5 insertions(+), 3079 deletions(-) delete mode 100644 code/english_to_number.rb delete mode 100644 code/koans/GREED_RULES.txt delete mode 100644 code/koans/README.rdoc delete mode 100644 code/koans/Rakefile mode change 100644 => 100755 code/koans/about_array_assignment.rb mode change 100644 => 100755 code/koans/about_arrays.rb mode change 100644 => 100755 code/koans/about_asserts.rb delete mode 100644 code/koans/about_blocks.rb delete mode 100644 code/koans/about_class_methods.rb delete mode 100644 code/koans/about_classes.rb delete mode 100644 code/koans/about_constants.rb delete mode 100644 code/koans/about_control_statements.rb delete mode 100644 code/koans/about_dice_project.rb delete mode 100644 code/koans/about_exceptions.rb delete mode 100644 code/koans/about_extra_credit.rb mode change 100644 => 100755 code/koans/about_hashes.rb delete mode 100644 code/koans/about_inheritance.rb delete mode 100644 code/koans/about_iteration.rb delete mode 100644 code/koans/about_java_interop.rb delete mode 100644 code/koans/about_keyword_arguments.rb delete mode 100644 code/koans/about_message_passing.rb mode change 100644 => 100755 code/koans/about_methods.rb delete mode 100644 code/koans/about_modules.rb mode change 100644 => 100755 code/koans/about_nil.rb mode change 100644 => 100755 code/koans/about_objects.rb delete mode 100644 code/koans/about_open_classes.rb delete mode 100644 code/koans/about_proxy_object_project.rb mode change 100644 => 100755 code/koans/about_regular_expressions.rb delete mode 100644 code/koans/about_sandwich_code.rb delete mode 100644 code/koans/about_scope.rb delete mode 100644 code/koans/about_scoring_project.rb mode change 100644 => 100755 code/koans/about_strings.rb mode change 100644 => 100755 code/koans/about_symbols.rb delete mode 100644 code/koans/about_to_str.rb delete mode 100644 code/koans/about_triangle_project.rb delete mode 100644 code/koans/about_triangle_project_2.rb delete mode 100644 code/koans/about_true_and_false.rb delete mode 100644 code/koans/about_variable_scope.rb delete mode 100644 code/koans/example_file.txt delete mode 100644 code/koans/koans.watchr delete mode 100644 code/koans/neo.rb mode change 100644 => 100755 code/koans/path_to_enlightenment.rb delete mode 100644 code/koans/triangle.rb delete mode 100644 code/koans/versioning_spec.rb delete mode 100644 code/wolf-wolfpack.rb diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml index c4c9543..7fb8ed0 100644 --- a/.idea/codeStyleSettings.xml +++ b/.idea/codeStyleSettings.xml @@ -2,7 +2,11 @@ diff --git a/code/english_to_number.rb b/code/english_to_number.rb deleted file mode 100644 index 098ff16..0000000 --- a/code/english_to_number.rb +++ /dev/null @@ -1,61 +0,0 @@ -# I want a function that will convert English language numbers into -# their numerical representation. -# For example: -# english_to_number('one') #=> 1 -# english_to_number('ninety six') #=> 96 -# The function should at least work up to 100. 1_000_000_000_000 would be better. - -def english_to_number(word_or_words) - if word_or_words == nil #in case recursive call has no argument - word_or_words = '' - end - number_hash = { - 'one' => 1, - 'two' => 2, - 'three' => 3, - 'four' => 4, - 'five' => 5, - 'six' => 6, - 'seven' => 7, - 'eight' => 8, - 'nine' => 9, - 'ten' => 10, - 'eleven' => 11, - 'twelve' => 12, - 'thirteen' => 13, - 'fourteen' => 14, - 'fifteen' => 15, - 'sixteen' => 16, - 'seventeen' => 17, - 'eighteen' => 18, - 'nineteen' => 19, - 'twenty' => 20, - 'thirty' => 30, - 'forty' => 40, - 'fifty' => 50, - 'sixty' => 60, - 'seventy' => 70, - 'eighty' => 80, - 'ninety' => 90 - } - if word_or_words.include?('million') - millions, remainder = word_or_words.split('million') - return english_to_number(millions) * 1_000_000 + english_to_number(remainder) - elsif word_or_words.include?('thousand') - thousands, remainder = word_or_words.split('thousand') - return english_to_number(thousands) * 1000 + english_to_number(remainder) - elsif word_or_words.include?('hundred') - hundreds, remainder = word_or_words.split('hundred') - return english_to_number(hundreds) * 100 + english_to_number(remainder) - end - array_of_words = word_or_words.split - array_of_words.inject(0){|sum, string| sum + number_hash[string]} -end - -puts english_to_number('one') #=> 1 -puts english_to_number('twenty') #=> 20 -puts english_to_number('twenty five') #=> 25 -puts english_to_number('one hundred') #=> 100 -puts english_to_number('six hundred thirty two') #=> 632 -puts english_to_number('four thousand eight hundred twelve') #=> 4812 -puts english_to_number('nine hundred seventeen million thirty six') #=> 917000036 \ No newline at end of file diff --git a/code/koans/GREED_RULES.txt b/code/koans/GREED_RULES.txt deleted file mode 100644 index 58b5a9c..0000000 --- a/code/koans/GREED_RULES.txt +++ /dev/null @@ -1,66 +0,0 @@ -= Playing Greed - -Greed is a dice game played among 2 or more players, using 5 -six-sided dice. - -== Playing Greed - -Each player takes a turn consisting of one or more rolls of the dice. -On the first roll of the game, a player rolls all five dice which are -scored according to the following: - - Three 1's => 1000 points - Three 6's => 600 points - Three 5's => 500 points - Three 4's => 400 points - Three 3's => 300 points - Three 2's => 200 points - One 1 => 100 points - One 5 => 50 points - -A single die can only be counted once in each roll. For example, -a "5" can only count as part of a triplet (contributing to the 500 -points) or as a single 50 points, but not both in the same roll. - -Example Scoring - - Throw Score - --------- ------------------ - 5 1 3 4 1 50 + 2 * 100 = 250 - 1 1 1 3 1 1000 + 100 = 1100 - 2 4 4 5 4 400 + 50 = 450 - -The dice not contributing to the score are called the non-scoring -dice. "3" and "4" are non-scoring dice in the first example. "3" is -a non-scoring die in the second, and "2" is a non-score die in the -final example. - -After a player rolls and the score is calculated, the scoring dice are -removed and the player has the option of rolling again using only the -non-scoring dice. If all of the thrown dice are scoring, then the -player may roll all 5 dice in the next roll. - -The player may continue to roll as long as each roll scores points. If -a roll has zero points, then the player loses not only their turn, but -also accumulated score for that turn. If a player decides to stop -rolling before rolling a zero-point roll, then the accumulated points -for the turn is added to his total score. - -== Getting "In The Game" - -Before a player is allowed to accumulate points, they must get at -least 300 points in a single turn. Once they have achieved 300 points -in a single turn, the points earned in that turn and each following -turn will be counted toward their total score. - -== End Game - -Once a player reaches 3000 (or more) points, the game enters the final -round where each of the other players gets one more turn. The winner -is the player with the highest score after the final round. - -== References - -Greed is described on Wikipedia at -http://en.wikipedia.org/wiki/Greed_(dice_game), however the rules are -a bit different from the rules given here. diff --git a/code/koans/README.rdoc b/code/koans/README.rdoc deleted file mode 100644 index 5908547..0000000 --- a/code/koans/README.rdoc +++ /dev/null @@ -1,191 +0,0 @@ -= Neo Ruby Koans - -The Ruby Koans walk you along the path to enlightenment in order to learn Ruby. -The goal is to learn the Ruby language, syntax, structure, and some common -functions and libraries. We also teach you culture by basing the koans on tests. -Testing is not just something we pay lip service to, but something we -live. Testing is essential in your quest to learn and do great things in Ruby. - -== The Structure - -The koans are broken out into areas by file, hashes are covered in +about_hashes.rb+, -modules are introduced in +about_modules.rb+, etc. They are presented in -order in the +path_to_enlightenment.rb+ file. - -Each koan builds up your knowledge of Ruby and builds upon itself. It will stop at -the first place you need to correct. - -Some koans simply need to have the correct answer substituted for an incorrect one. -Some, however, require you to supply your own answer. If you see the method +__+ (a -double underscore) listed, it is a hint to you to supply your own code in order to -make it work correctly. - -== Installing Ruby - -If you do not have Ruby setup, please visit http://ruby-lang.org/en/downloads/ for -operating specific instructions. In order to run the koans you need +ruby+ and -+rake+ installed. To check your installations simply type: - -*nix platforms from any terminal window: - - [~] $ ruby --version - [~] $ rake --version - -Windows from the command prompt (+cmd.exe+) - - c:\ruby --version - c:\rake --version - -If you don't have +rake+ installed, just run gem install rake - -Any response for Ruby with a version number greater than 1.8 is fine (should be -around 1.8.6 or more). Any version of +rake+ will do. - -== Generating the Koans - -A fresh checkout will not include the koans, you will need to generate -them. - - [ruby_koans] $ rake gen # generates the koans directory - -If you need to regenerate the koans, thus wiping your current `koans`, - - [ruby_koans] $ rake regen # regenerates the koans directory, wiping the original - -== The Path To Enlightenment - -You can run the tests through +rake+ or by calling the file itself (+rake+ is the -recommended way to run them as we might build more functionality into this task). - -*nix platforms, from the +ruby_koans+ directory - - [ruby_koans] $ rake # runs the default target :walk_the_path - [ruby_koans] $ ruby path_to_enlightenment.rb # simply call the file directly - -Windows is the same thing - - c:\ruby_koans\rake # runs the default target :walk_the_path - c:\ruby_koans\ruby path_to_enlightenment.rb # simply call the file directly - -=== Red, Green, Refactor - -In test-driven development the mantra has always been red, green, refactor. -Write a failing test and run it (red), make the test pass (green), -then look at the code and consider if you can make it any better (refactor). - -While walking the path to Ruby enlightenment you will need to run the koan and -see it fail (red), make the test pass (green), then take a moment -and reflect upon the test to see what it is teaching you and improve the code to -better communicate its intent (refactor). - -The very first time you run the koans you will see the following output: - - [ ruby_koans ] $ rake - (in /Users/person/dev/ruby_koans) - /usr/bin/ruby1.8 path_to_enlightenment.rb - - AboutAsserts#test_assert_truth has damaged your karma. - - The Master says: - You have not yet reached enlightenment. - - The answers you seek... - is not true. - - Please meditate on the following code: - ./about_asserts.rb:10:in `test_assert_truth' - path_to_enlightenment.rb:38:in `each_with_index' - path_to_enlightenment.rb:38 - - mountains are merely mountains - your path thus far [X_________________________________________________] 0/280 - -You have come to your first stage. Notice it is telling you where to look for -the first solution: - - Please meditate on the following code: - ./about_asserts.rb:10:in `test_assert_truth' - path_to_enlightenment.rb:38:in `each_with_index' - path_to_enlightenment.rb:38 - -Open the +about_asserts.rb+ file and look at the first test: - - # We shall contemplate truth by testing reality, via asserts. - def test_assert_truth - assert false # This should be true - end - -Change the +false+ to +true+ and re-run the test. After you are -done, think about what you are learning. In this case, ignore everything except -the method name (+test_assert_truth+) and the parts inside the method (everything -before the +end+). - -In this case the goal is for you to see that if you pass a value to the +assert+ -method, it will either ensure it is +true+ and continue on, or fail if -the statement is +false+. - -=== Running the Koans automatically - -This section is optional. - -Normally the path to enlightenment looks like this: - - cd ruby_koans - rake - # edit - rake - # edit - rake - # etc - -If you prefer, you can keep the koans running in the background so that after you -make a change in your editor, the koans will immediately run again. This will -hopefully keep your focus on learning Ruby instead of on the command line. - -Install the Ruby gem (library) called +watchr+ and then ask it to -"watch" the koans for changes: - - cd ruby_koans - rake - # decide to run rake automatically from now on as you edit - gem install watchr - watchr ./koans/koans.watchr - -== Inspiration - -A special thanks to Mike Clark and Ara Howard for inspiring this -project. Mike Clark wrote an excellent blog post about learning Ruby -through unit testing. This sparked an idea that has taken a bit to -solidify, that of bringing new rubyists into the community through -testing. Ara Howard then gave us the idea for the Koans in his ruby -quiz entry on Meta Koans (a must for any rubyist wanting to improve -their skills). Also, "The Little Lisper" taught us all the value of -the short questions/simple answers style of learning. - -Mike Clark's post :: http://www.clarkware.com/cgi/blosxom/2005/03/18 -Meta Koans :: http://rubyquiz.com/quiz67.html -The Little Lisper :: http://www.amazon.com/Little-LISPer-Third-Daniel-Friedman/dp/0023397632 - -== Other Resources - -The Ruby Language :: http://ruby-lang.org -Try Ruby in your browser :: http://tryruby.org - -Dave Thomas' introduction to Ruby Programming Ruby (the Pick Axe) :: http://pragprog.com/titles/ruby/programming-ruby - -Brian Marick's fantastic guide for beginners Everyday Scripting with Ruby :: http://pragprog.com/titles/bmsft/everyday-scripting-with-ruby - -= Other stuff - -Author :: Jim Weirich -Author :: Joe O'Brien -Issue Tracker :: http://www.pivotaltracker.com/projects/48111 -Requires :: Ruby 1.8.x or later and Rake (any recent version) - -= License - -http://i.creativecommons.org/l/by-nc-sa/3.0/88x31.png - -RubyKoans is released under a Creative Commons, -Attribution-NonCommercial-ShareAlike, Version 3.0 -(http://creativecommons.org/licenses/by-nc-sa/3.0/) License. diff --git a/code/koans/Rakefile b/code/koans/Rakefile deleted file mode 100644 index 1a2c7f2..0000000 --- a/code/koans/Rakefile +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env ruby -# -*- ruby -*- - -require 'rake/clean' -require 'rake/testtask' - -task :default => :test - -task :test do - ruby 'path_to_enlightenment.rb' -end - diff --git a/code/koans/about_array_assignment.rb b/code/koans/about_array_assignment.rb old mode 100644 new mode 100755 diff --git a/code/koans/about_arrays.rb b/code/koans/about_arrays.rb old mode 100644 new mode 100755 diff --git a/code/koans/about_asserts.rb b/code/koans/about_asserts.rb old mode 100644 new mode 100755 diff --git a/code/koans/about_blocks.rb b/code/koans/about_blocks.rb deleted file mode 100644 index 64ec2a9..0000000 --- a/code/koans/about_blocks.rb +++ /dev/null @@ -1,96 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutBlocks < Neo::Koan - def method_with_block - result = yield - result - end - - def test_methods_can_take_blocks - yielded_result = method_with_block { 1 + 2 } - assert_equal 3, yielded_result - end - - def test_blocks_can_be_defined_with_do_end_too - yielded_result = method_with_block do 1 + 2 end - assert_equal 3, yielded_result - end - - # ------------------------------------------------------------------ - - def method_with_block_arguments - yield("Jim") - end - - def test_blocks_can_take_arguments - method_with_block_arguments do |argument| - assert_equal "Jim", argument - end - end - - # ------------------------------------------------------------------ - - def many_yields - yield(:peanut) - yield(:butter) - yield(:and) - yield(:jelly) - end - - def test_methods_can_call_yield_many_times - result = [] - many_yields { |item| result << item } - assert_equal [:peanut,:butter,:and,:jelly], result - end - - # ------------------------------------------------------------------ - - def yield_tester - if block_given? - yield - else - :no_block - end - end - - def test_methods_can_see_if_they_have_been_called_with_a_block - assert_equal :with_block, yield_tester { :with_block } - assert_equal :no_block, yield_tester - end - - # ------------------------------------------------------------------ - - def test_block_can_affect_variables_in_the_code_where_they_are_created - value = :initial_value - method_with_block { value = :modified_in_a_block } - assert_equal :modified_in_a_block, value - end - - def test_blocks_can_be_assigned_to_variables_and_called_explicitly - add_one = lambda { |n| n + 1 } - assert_equal 11, add_one.call(10) - - # Alternative calling syntax - assert_equal 11, add_one[10] - end - - def test_stand_alone_blocks_can_be_passed_to_methods_expecting_blocks - make_upper = lambda { |n| n.upcase } - result = method_with_block_arguments(&make_upper) - assert_equal "JIM", result - end - - # ------------------------------------------------------------------ - - def method_with_explicit_block(&block) - block.call(10) - end - - def test_methods_can_take_an_explicit_block_argument - assert_equal 20, method_with_explicit_block { |n| n * 2 } - - add_one = lambda { |n| n + 1 } - assert_equal 11, method_with_explicit_block(&add_one) - end - -end diff --git a/code/koans/about_class_methods.rb b/code/koans/about_class_methods.rb deleted file mode 100644 index fa8f5b5..0000000 --- a/code/koans/about_class_methods.rb +++ /dev/null @@ -1,169 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutClassMethods < Neo::Koan - class Dog - end - - def test_objects_are_objects - fido = Dog.new - assert_equal true, fido.is_a?(Object) - end - - def test_classes_are_classes - assert_equal true, Dog.is_a?(Class) - end - - def test_classes_are_objects_too - assert_equal true, Dog.is_a?(Object) - end - - def test_objects_have_methods - fido = Dog.new - assert fido.methods.size > 4 - end - - def test_classes_have_methods - assert Dog.methods.size > 0 - end - - def test_you_can_define_methods_on_individual_objects - fido = Dog.new - def fido.wag - :fidos_wag - end - assert_equal :fidos_wag,fido.wag - end - - def test_other_objects_are_not_affected_by_these_singleton_methods - fido = Dog.new - rover = Dog.new - def fido.wag - :fidos_wag - end - - assert_raise(NoMethodError) do - rover.wag - end - end - - # ------------------------------------------------------------------ - - class Dog2 - def wag - :instance_level_wag - end - end - - def Dog2.wag - :class_level_wag - end - - def test_since_classes_are_objects_you_can_define_singleton_methods_on_them_too - assert_equal :class_level_wag, Dog2.wag - end - - def test_class_methods_are_independent_of_instance_methods - fido = Dog2.new - assert_equal :instance_level_wag, fido.wag - assert_equal :class_level_wag, Dog2.wag - end - - # ------------------------------------------------------------------ - - class Dog - attr_accessor :name - end - - def Dog.name - @name - end - - def test_classes_and_instances_do_not_share_instance_variables - fido = Dog.new - fido.name = "Fido" - assert_equal "Fido", fido.name - assert_equal nil, Dog.name - end - - # ------------------------------------------------------------------ - - class Dog - def Dog.a_class_method - :dogs_class_method - end - end - - def test_you_can_define_class_methods_inside_the_class - assert_equal :dogs_class_method, Dog.a_class_method - end - - # ------------------------------------------------------------------ - - LastExpressionInClassStatement = class Dog - 21 - end - - def test_class_statements_return_the_value_of_their_last_expression - assert_equal 21, LastExpressionInClassStatement - end - - # ------------------------------------------------------------------ - - SelfInsideOfClassStatement = class Dog - self - end - - def test_self_while_inside_class_is_class_object_not_instance - assert_equal true, Dog == SelfInsideOfClassStatement - end - - # ------------------------------------------------------------------ - - class Dog - def self.class_method2 - :another_way_to_write_class_methods - end - end - - def test_you_can_use_self_instead_of_an_explicit_reference_to_dog - assert_equal :another_way_to_write_class_methods, Dog.class_method2 - end - - # ------------------------------------------------------------------ - - class Dog - class << self - def another_class_method - :still_another_way - end - end - end - - def test_heres_still_another_way_to_write_class_methods - assert_equal :still_another_way, Dog.another_class_method - end - - # THINK ABOUT IT: - # - # The two major ways to write class methods are: - # class Demo - # def self.method - # end - # - # class << self - # def class_methods - # end - # end - # end - # - # Which do you prefer and why? - # Are there times you might prefer one over the other? - - # ------------------------------------------------------------------ - - def test_heres_an_easy_way_to_call_class_methods_from_instance_methods - fido = Dog.new - assert_equal :still_another_way, fido.class.another_class_method - end - -end diff --git a/code/koans/about_classes.rb b/code/koans/about_classes.rb deleted file mode 100644 index ac121ab..0000000 --- a/code/koans/about_classes.rb +++ /dev/null @@ -1,190 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutClasses < Neo::Koan - class Dog - end - - def test_instances_of_classes_can_be_created_with_new - fido = Dog.new - assert_equal Dog, fido.class - end - - # ------------------------------------------------------------------ - - class Dog2 - def set_name(a_name) - @name = a_name - end - end - - def test_instance_variables_can_be_set_by_assigning_to_them - fido = Dog2.new - assert_equal [], fido.instance_variables - - fido.set_name("Fido") - assert_equal [:@name], fido.instance_variables - end - - def test_instance_variables_cannot_be_accessed_outside_the_class - fido = Dog2.new - fido.set_name("Fido") - - assert_raise(NoMethodError) do - fido.name - end - - assert_raise(SyntaxError) do - eval "fido.@name" - # NOTE: Using eval because the above line is a syntax error. - end - end - - def test_you_can_politely_ask_for_instance_variable_values - fido = Dog2.new - fido.set_name("Fido") - - assert_equal "Fido", fido.instance_variable_get("@name") - end - - def test_you_can_rip_the_value_out_using_instance_eval - fido = Dog2.new - fido.set_name("Fido") - - assert_equal "Fido", fido.instance_eval("@name") # string version - assert_equal "Fido", fido.instance_eval { @name } # block version - end - - # ------------------------------------------------------------------ - - class Dog3 - def set_name(a_name) - @name = a_name - end - def name - @name - end - end - - def test_you_can_create_accessor_methods_to_return_instance_variables - fido = Dog3.new - fido.set_name("Fido") - - assert_equal "Fido", fido.name - end - - # ------------------------------------------------------------------ - - class Dog4 - attr_reader :name - - def set_name(a_name) - @name = a_name - end - end - - - def test_attr_reader_will_automatically_define_an_accessor - fido = Dog4.new - fido.set_name("Fido") - - assert_equal "Fido", fido.name - end - - # ------------------------------------------------------------------ - - class Dog5 - attr_accessor :name - end - - - def test_attr_accessor_will_automatically_define_both_read_and_write_accessors - fido = Dog5.new - - fido.name = "Fido" - assert_equal "Fido", fido.name - end - - # ------------------------------------------------------------------ - - class Dog6 - attr_reader :name - def initialize(initial_name) - @name = initial_name - end - end - - def test_initialize_provides_initial_values_for_instance_variables - fido = Dog6.new("Fido") - assert_equal "Fido", fido.name - end - - def test_args_to_new_must_match_initialize - assert_raise(ArgumentError) do - Dog6.new - end - # THINK ABOUT IT: - # Why is this so? - end - - def test_different_objects_have_different_instance_variables - fido = Dog6.new("Fido") - rover = Dog6.new("Rover") - - assert_equal true, rover.name != fido.name - end - - # ------------------------------------------------------------------ - - class Dog7 - attr_reader :name - - def initialize(initial_name) - @name = initial_name - end - - def get_self - self - end - - def to_s - @name - end - - def inspect - "" - end - end - - def test_inside_a_method_self_refers_to_the_containing_object - fido = Dog7.new("Fido") - - fidos_self = fido.get_self - assert_equal fido, fidos_self - end - - def test_to_s_provides_a_string_version_of_the_object - fido = Dog7.new("Fido") - assert_equal "Fido", fido.to_s - end - - def test_to_s_is_used_in_string_interpolation - fido = Dog7.new("Fido") - assert_equal "My dog is Fido", "My dog is #{fido}" - end - - def test_inspect_provides_a_more_complete_string_version - fido = Dog7.new("Fido") - assert_equal "", fido.inspect - end - - def test_all_objects_support_to_s_and_inspect - array = [1,2,3] - - assert_equal "[1, 2, 3]", array.to_s - assert_equal "[1, 2, 3]", array.inspect - - assert_equal "STRING", "STRING".to_s - assert_equal "\"STRING\"", "STRING".inspect - end - -end diff --git a/code/koans/about_constants.rb b/code/koans/about_constants.rb deleted file mode 100644 index 472792a..0000000 --- a/code/koans/about_constants.rb +++ /dev/null @@ -1,87 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -C = "top level" - -class AboutConstants < Neo::Koan - - C = "nested" - - def test_nested_constants_may_also_be_referenced_with_relative_paths - assert_equal "nested", C - end - - def test_top_level_constants_are_referenced_by_double_colons - assert_equal "top level", ::C - end - - def test_nested_constants_are_referenced_by_their_complete_path - assert_equal "nested", AboutConstants::C - assert_equal "nested", ::AboutConstants::C - end - - # ------------------------------------------------------------------ - - class Animal - LEGS = 4 - def legs_in_animal - LEGS - end - - class NestedAnimal - def legs_in_nested_animal - LEGS - end - end - end - - def test_nested_classes_inherit_constants_from_enclosing_classes - assert_equal 4, Animal::NestedAnimal.new.legs_in_nested_animal - end - - # ------------------------------------------------------------------ - - class Reptile < Animal - def legs_in_reptile - LEGS - end - end - - def test_subclasses_inherit_constants_from_parent_classes - assert_equal 4, Reptile.new.legs_in_reptile - end - - # ------------------------------------------------------------------ - - class MyAnimals - LEGS = 2 - - class Bird < Animal - def legs_in_bird - LEGS - end - end - end - - def test_who_wins_with_both_nested_and_inherited_constants - assert_equal 2, MyAnimals::Bird.new.legs_in_bird - end - - # QUESTION: Which has precedence: The constant in the lexical scope, - # or the constant from the inheritance hierarchy? - - # ------------------------------------------------------------------ - - class MyAnimals::Oyster < Animal - def legs_in_oyster - LEGS - end - end - - def test_who_wins_with_explicit_scoping_on_class_definition - assert_equal 4, MyAnimals::Oyster.new.legs_in_oyster - end - - # QUESTION: Now which has precedence: The constant in the lexical - # scope, or the constant from the inheritance hierarchy? Why is it - # different than the previous answer? -end diff --git a/code/koans/about_control_statements.rb b/code/koans/about_control_statements.rb deleted file mode 100644 index 22575d8..0000000 --- a/code/koans/about_control_statements.rb +++ /dev/null @@ -1,142 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutControlStatements < Neo::Koan - - def test_if_then_else_statements - if true - result = :true_value - else - result = :false_value - end - assert_equal :test_value, result - end - - def test_if_then_statements - result = :default_value - if true - result = :true_value - end - assert_equal :true_value, result - end - - def test_if_statements_return_values - value = if true - :true_value - else - :false_value - end - assert_equal __, value - - value = if false - :true_value - else - :false_value - end - assert_equal __, value - - # NOTE: Actually, EVERY statement in Ruby will return a value, not - # just if statements. - end - - def test_if_statements_with_no_else_with_false_condition_return_value - value = if false - :true_value - end - assert_equal __, value - end - - def test_condition_operators - assert_equal __, (true ? :true_value : :false_value) - assert_equal __, (false ? :true_value : :false_value) - end - - def test_if_statement_modifiers - result = :default_value - result = :true_value if true - - assert_equal __, result - end - - def test_unless_statement - result = :default_value - unless false # same as saying 'if !false', which evaluates as 'if true' - result = :false_value - end - assert_equal __, result - end - - def test_unless_statement_evaluate_true - result = :default_value - unless true # same as saying 'if !true', which evaluates as 'if false' - result = :true_value - end - assert_equal __, result - end - - def test_unless_statement_modifier - result = :default_value - result = :false_value unless false - - assert_equal __, result - end - - def test_while_statement - i = 1 - result = 1 - while i <= 10 - result = result * i - i += 1 - end - assert_equal __, result - end - - def test_break_statement - i = 1 - result = 1 - while true - break unless i <= 10 - result = result * i - i += 1 - end - assert_equal __, result - end - - def test_break_statement_returns_values - i = 1 - result = while i <= 10 - break i if i % 2 == 0 - i += 1 - end - - assert_equal __, result - end - - def test_next_statement - i = 0 - result = [] - while i < 10 - i += 1 - next if (i % 2) == 0 - result << i - end - assert_equal __, result - end - - def test_for_statement - array = ["fish", "and", "chips"] - result = [] - for item in array - result << item.upcase - end - assert_equal [__, __, __], result - end - - def test_times_statement - sum = 0 - 10.times do - sum += 1 - end - assert_equal __, sum - end - -end diff --git a/code/koans/about_dice_project.rb b/code/koans/about_dice_project.rb deleted file mode 100644 index 5a1848f..0000000 --- a/code/koans/about_dice_project.rb +++ /dev/null @@ -1,63 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -# Implement a DiceSet Class here: -# -# class DiceSet -# code ... -# end - -class AboutDiceProject < Neo::Koan - def test_can_create_a_dice_set - dice = DiceSet.new - assert_not_nil dice - end - - def test_rolling_the_dice_returns_a_set_of_integers_between_1_and_6 - dice = DiceSet.new - - dice.roll(5) - assert dice.values.is_a?(Array), "should be an array" - assert_equal 5, dice.values.size - dice.values.each do |value| - assert value >= 1 && value <= 6, "value #{value} must be between 1 and 6" - end - end - - def test_dice_values_do_not_change_unless_explicitly_rolled - dice = DiceSet.new - dice.roll(5) - first_time = dice.values - second_time = dice.values - assert_equal first_time, second_time - end - - def test_dice_values_should_change_between_rolls - dice = DiceSet.new - - dice.roll(5) - first_time = dice.values - - dice.roll(5) - second_time = dice.values - - assert_not_equal first_time, second_time, - "Two rolls should not be equal" - - # THINK ABOUT IT: - # - # If the rolls are random, then it is possible (although not - # likely) that two consecutive rolls are equal. What would be a - # better way to test this? - end - - def test_you_can_roll_different_numbers_of_dice - dice = DiceSet.new - - dice.roll(3) - assert_equal 3, dice.values.size - - dice.roll(1) - assert_equal 1, dice.values.size - end - -end diff --git a/code/koans/about_exceptions.rb b/code/koans/about_exceptions.rb deleted file mode 100644 index 464f57e..0000000 --- a/code/koans/about_exceptions.rb +++ /dev/null @@ -1,68 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutExceptions < Neo::Koan - - class MySpecialError < RuntimeError - end - - def test_exceptions_inherit_from_Exception - assert_equal __, MySpecialError.ancestors[1] - assert_equal __, MySpecialError.ancestors[2] - assert_equal __, MySpecialError.ancestors[3] - assert_equal __, MySpecialError.ancestors[4] - end - - def test_rescue_clause - result = nil - begin - fail "Oops" - rescue StandardError => ex - result = :exception_handled - end - - assert_equal __, result - - assert_equal __, ex.is_a?(StandardError), "Should be a Standard Error" - assert_equal __, ex.is_a?(RuntimeError), "Should be a Runtime Error" - - assert RuntimeError.ancestors.include?(StandardError), - "RuntimeError is a subclass of StandardError" - - assert_equal __, ex.message - end - - def test_raising_a_particular_error - result = nil - begin - # 'raise' and 'fail' are synonyms - raise MySpecialError, "My Message" - rescue MySpecialError => ex - result = :exception_handled - end - - assert_equal __, result - assert_equal __, ex.message - end - - def test_ensure_clause - result = nil - begin - fail "Oops" - rescue StandardError - # no code here - ensure - result = :always_run - end - - assert_equal __, result - end - - # Sometimes, we must know about the unknown - def test_asserting_an_error_is_raised - # A do-end is a block, a topic to explore more later - assert_raise(___) do - raise MySpecialError.new("New instances can be raised directly.") - end - end - -end diff --git a/code/koans/about_extra_credit.rb b/code/koans/about_extra_credit.rb deleted file mode 100644 index 5012edf..0000000 --- a/code/koans/about_extra_credit.rb +++ /dev/null @@ -1,8 +0,0 @@ -# EXTRA CREDIT: -# -# Create a program that will play the Greed Game. -# Rules for the game are in GREED_RULES.TXT. -# -# You already have a DiceSet class and score function you can use. -# Write a player class and a Game class to complete the project. This -# is a free form assignment, so approach it however you desire. diff --git a/code/koans/about_hashes.rb b/code/koans/about_hashes.rb old mode 100644 new mode 100755 diff --git a/code/koans/about_inheritance.rb b/code/koans/about_inheritance.rb deleted file mode 100644 index 61bc890..0000000 --- a/code/koans/about_inheritance.rb +++ /dev/null @@ -1,85 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutInheritance < Neo::Koan - class Dog - attr_reader :name - - def initialize(name) - @name = name - end - - def bark - "WOOF" - end - end - - class Chihuahua < Dog - def wag - :happy - end - - def bark - "yip" - end - end - - def test_subclasses_have_the_parent_as_an_ancestor - assert_equal __, Chihuahua.ancestors.include?(Dog) - end - - def test_all_classes_ultimately_inherit_from_object - assert_equal __, Chihuahua.ancestors.include?(Object) - end - - def test_subclasses_inherit_behavior_from_parent_class - chico = Chihuahua.new("Chico") - assert_equal __, chico.name - end - - def test_subclasses_add_new_behavior - chico = Chihuahua.new("Chico") - assert_equal __, chico.wag - - assert_raise(___) do - fido = Dog.new("Fido") - fido.wag - end - end - - def test_subclasses_can_modify_existing_behavior - chico = Chihuahua.new("Chico") - assert_equal __, chico.bark - - fido = Dog.new("Fido") - assert_equal __, fido.bark - end - - # ------------------------------------------------------------------ - - class BullDog < Dog - def bark - super + ", GROWL" - end - end - - def test_subclasses_can_invoke_parent_behavior_via_super - ralph = BullDog.new("Ralph") - assert_equal __, ralph.bark - end - - # ------------------------------------------------------------------ - - class GreatDane < Dog - def growl - super.bark + ", GROWL" - end - end - - def test_super_does_not_work_cross_method - george = GreatDane.new("George") - assert_raise(___) do - george.growl - end - end - -end diff --git a/code/koans/about_iteration.rb b/code/koans/about_iteration.rb deleted file mode 100644 index 6179c2c..0000000 --- a/code/koans/about_iteration.rb +++ /dev/null @@ -1,122 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutIteration < Neo::Koan - - # -- An Aside ------------------------------------------------------ - # Ruby 1.8 stores names as strings. Ruby 1.9 and later stores names - # as symbols. So we use a version dependent method "as_name" to - # convert to the right format in the koans. We will use "as_name" - # whenever comparing to lists of methods. - - in_ruby_version("1.8") do - def as_name(name) - name.to_s - end - end - - in_ruby_version("1.9", "2") do - def as_name(name) - name.to_sym - end - end - - # Ok, now back to the Koans. - # ------------------------------------------------------------------- - - def test_each_is_a_method_on_arrays - assert_equal __, [].methods.include?(as_name(:each)) - end - - def test_iterating_with_each - array = [1, 2, 3] - sum = 0 - array.each do |item| - sum += item - end - assert_equal __, sum - end - - def test_each_can_use_curly_brace_blocks_too - array = [1, 2, 3] - sum = 0 - array.each { |item| sum += item } - assert_equal __, sum - end - - def test_break_works_with_each_style_iterations - array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - sum = 0 - array.each do |item| - break if item > 3 - sum += item - end - assert_equal __, sum - end - - def test_collect_transforms_elements_of_an_array - array = [1, 2, 3] - new_array = array.collect { |item| item + 10 } - assert_equal __, new_array - - # NOTE: 'map' is another name for the 'collect' operation - another_array = array.map { |item| item + 10 } - assert_equal __, another_array - end - - def test_select_selects_certain_items_from_an_array - array = [1, 2, 3, 4, 5, 6] - - even_numbers = array.select { |item| (item % 2) == 0 } - assert_equal __, even_numbers - - # NOTE: 'find_all' is another name for the 'select' operation - more_even_numbers = array.find_all { |item| (item % 2) == 0 } - assert_equal __, more_even_numbers - end - - def test_find_locates_the_first_element_matching_a_criteria - array = ["Jim", "Bill", "Clarence", "Doug", "Eli"] - - assert_equal __, array.find { |item| item.size > 4 } - end - - def test_inject_will_blow_your_mind - result = [2, 3, 4].inject(0) { |sum, item| sum + item } - assert_equal __, result - - result2 = [2, 3, 4].inject(1) { |product, item| product * item } - assert_equal __, result2 - - # Extra Credit: - # Describe in your own words what inject does. - end - - def test_all_iteration_methods_work_on_any_collection_not_just_arrays - # Ranges act like a collection - result = (1..3).map { |item| item + 10 } - assert_equal __, result - - # Files act like a collection of lines - File.open("example_file.txt") do |file| - upcase_lines = file.map { |line| line.strip.upcase } - assert_equal __, upcase_lines - end - - # NOTE: You can create your own collections that work with each, - # map, select, etc. - end - - # Bonus Question: In the previous koan, we saw the construct: - # - # File.open(filename) do |file| - # # code to read 'file' - # end - # - # Why did we do it that way instead of the following? - # - # file = File.open(filename) - # # code to read 'file' - # - # When you get to the "AboutSandwichCode" koan, recheck your answer. - -end diff --git a/code/koans/about_java_interop.rb b/code/koans/about_java_interop.rb deleted file mode 100644 index 47fef28..0000000 --- a/code/koans/about_java_interop.rb +++ /dev/null @@ -1,137 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -include Java - -# Concepts -# * Pull in a java class -# * calling a method, Camel vs snake -# * Resolving module/class name conflicts -# * Showing what gets returned -# * Ruby Strings VS Java Strings -# * Calling custom java class -# * Calling Ruby from java??? - -class AboutJavaInterop < Neo::Koan - def test_using_a_java_library_class - java_array = java.util.ArrayList.new - assert_equal __, java_array.class - end - - def test_java_class_can_be_referenced_using_both_ruby_and_java_like_syntax - assert_equal __, Java::JavaUtil::ArrayList == java.util.ArrayList - end - - def test_include_class_includes_class_in_module_scope - assert_nil defined?(TreeSet) - include_class "java.util.TreeSet" - assert_equal __, defined?(TreeSet) - end - - # THINK ABOUT IT: - # - # What if we use: - # - # include_class "java.lang.String" - # - # What would be the value of the String constant after this - # include_class is run? Would it be useful to provide a way of - # aliasing java classes to different names? - - JString = java.lang.String - def test_also_java_class_can_be_given_ruby_aliases - java_string = JString.new("A Java String") - assert_equal __, java_string.class - assert_equal __, JString - end - - def test_can_directly_call_java_methods_on_java_objects - java_string = JString.new("A Java String") - assert_equal __, java_string.toLowerCase - end - - def test_jruby_provides_snake_case_versions_of_java_methods - java_string = JString.new("A Java String") - assert_equal __, java_string.to_lower_case - end - - def test_jruby_provides_question_mark_versions_of_boolean_methods - java_string = JString.new("A Java String") - assert_equal __, java_string.endsWith("String") - assert_equal __, java_string.ends_with("String") - assert_equal __, java_string.ends_with?("String") - end - - def test_java_string_are_not_ruby_strings - ruby_string = "A Java String" - java_string = java.lang.String.new(ruby_string) - assert_equal __, java_string.is_a?(java.lang.String) - assert_equal __, java_string.is_a?(String) - end - - def test_java_strings_can_be_compared_to_ruby_strings_maybe - ruby_string = "A Java String" - java_string = java.lang.String.new(ruby_string) - assert_equal __, ruby_string == java_string - assert_equal __, java_string == ruby_string - - # THINK ABOUT IT: - # - # Is there any possible way for this to be more wrong? - # - # SERIOUSLY, THINK ABOUT IT: - # - # Why do you suppose that Ruby and Java strings compare like that? - # - # ADVANCED THINK ABOUT IT: - # - # Is there a way to make Ruby/Java string comparisons commutative? - # How would you do it? - end - - def test_however_most_methods_returning_strings_return_ruby_strings - java_array = java.util.ArrayList.new - assert_equal __, java_array.toString - assert_equal __, java_array.toString.is_a?(String) - assert_equal __, java_array.toString.is_a?(java.lang.String) - end - - def test_some_ruby_objects_can_be_coerced_to_java - assert_equal __, "ruby string".to_java.class - assert_equal __, 1.to_java.class - assert_equal __, 9.32.to_java.class - assert_equal __, false.to_java.class - end - - def test_some_ruby_objects_are_not_coerced_to_what_you_might_expect - assert_equal __, [].to_java.class == Java::JavaUtil::ArrayList - assert_equal __, {}.to_java.class == Java::JavaUtil::HashMap - assert_equal __, Object.new.to_java.class == Java::JavaLang::Object - end - - def test_java_collections_are_enumerable - java_array = java.util.ArrayList.new - java_array << "one" << "two" << "three" - assert_equal __, java_array.map { |item| item.upcase } - end - - # ------------------------------------------------------------------ - - # Open the Java ArrayList class and add a new method. - class Java::JavaUtil::ArrayList - def multiply_all - result = 1 - each do |item| - result *= item - end - result - end - end - - def test_java_class_are_open_from_ruby - java_array = java.util.ArrayList.new - java_array.add_all([1,2,3,4,5]) - - assert_equal __, java_array.multiply_all - end - -end diff --git a/code/koans/about_keyword_arguments.rb b/code/koans/about_keyword_arguments.rb deleted file mode 100644 index 740d0c0..0000000 --- a/code/koans/about_keyword_arguments.rb +++ /dev/null @@ -1,31 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutKeywordArguments < Neo::Koan - - def method_with_keyword_arguments(one: 1, two: 'two') - [one, two] - end - - def test_keyword_arguments - assert_equal __, method_with_keyword_arguments.class - assert_equal __, method_with_keyword_arguments - assert_equal __, method_with_keyword_arguments(one: 'one') - assert_equal __, method_with_keyword_arguments(two: 2) - end - - def method_with_keyword_arguments_with_mandatory_argument(one, two: 2, three: 3) - [one, two, three] - end - - def test_keyword_arguments_with_wrong_number_of_arguments - exception = assert_raise (___) do - method_with_keyword_arguments_with_mandatory_argument - end - assert_match(/__/, exception.message) - end - - # THINK ABOUT IT: - # - # Keyword arguments always have a default value, making them optional to the caller - -end diff --git a/code/koans/about_message_passing.rb b/code/koans/about_message_passing.rb deleted file mode 100644 index c6d80a8..0000000 --- a/code/koans/about_message_passing.rb +++ /dev/null @@ -1,185 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutMessagePassing < Neo::Koan - - class MessageCatcher - def caught? - true - end - end - - def test_methods_can_be_called_directly - mc = MessageCatcher.new - - assert mc.caught? - end - - def test_methods_can_be_invoked_by_sending_the_message - mc = MessageCatcher.new - - assert mc.send(:caught?) - end - - def test_methods_can_be_invoked_more_dynamically - mc = MessageCatcher.new - - assert mc.send("caught?") - assert mc.send("caught" + __ ) # What do you need to add to the first string? - assert mc.send("CAUGHT?".____ ) # What would you need to do to the string? - end - - def test_send_with_underscores_will_also_send_messages - mc = MessageCatcher.new - - assert_equal __, mc.__send__(:caught?) - - # THINK ABOUT IT: - # - # Why does Ruby provide both send and __send__ ? - end - - def test_classes_can_be_asked_if_they_know_how_to_respond - mc = MessageCatcher.new - - assert_equal __, mc.respond_to?(:caught?) - assert_equal __, mc.respond_to?(:does_not_exist) - end - - # ------------------------------------------------------------------ - - class MessageCatcher - def add_a_payload(*args) - args - end - end - - def test_sending_a_message_with_arguments - mc = MessageCatcher.new - - assert_equal __, mc.add_a_payload - assert_equal __, mc.send(:add_a_payload) - - assert_equal __, mc.add_a_payload(3, 4, nil, 6) - assert_equal __, mc.send(:add_a_payload, 3, 4, nil, 6) - end - - # NOTE: - # - # Both obj.msg and obj.send(:msg) sends the message named :msg to - # the object. We use "send" when the name of the message can vary - # dynamically (e.g. calculated at run time), but by far the most - # common way of sending a message is just to say: obj.msg. - - # ------------------------------------------------------------------ - - class TypicalObject - end - - def test_sending_undefined_messages_to_a_typical_object_results_in_errors - typical = TypicalObject.new - - exception = assert_raise(___) do - typical.foobar - end - assert_match(/foobar/, exception.message) - end - - def test_calling_method_missing_causes_the_no_method_error - typical = TypicalObject.new - - exception = assert_raise(___) do - typical.method_missing(:foobar) - end - assert_match(/foobar/, exception.message) - - # THINK ABOUT IT: - # - # If the method :method_missing causes the NoMethodError, then - # what would happen if we redefine method_missing? - # - # NOTE: - # - # In Ruby 1.8 the method_missing method is public and can be - # called as shown above. However, in Ruby 1.9 (and later versions) - # the method_missing method is private. We explicitly made it - # public in the testing framework so this example works in both - # versions of Ruby. Just keep in mind you can't call - # method_missing like that after Ruby 1.9 normally. - # - # Thanks. We now return you to your regularly scheduled Ruby - # Koans. - end - - # ------------------------------------------------------------------ - - class AllMessageCatcher - def method_missing(method_name, *args, &block) - "Someone called #{method_name} with <#{args.join(", ")}>" - end - end - - def test_all_messages_are_caught - catcher = AllMessageCatcher.new - - assert_equal __, catcher.foobar - assert_equal __, catcher.foobaz(1) - assert_equal __, catcher.sum(1,2,3,4,5,6) - end - - def test_catching_messages_makes_respond_to_lie - catcher = AllMessageCatcher.new - - assert_nothing_raised do - catcher.any_method - end - assert_equal __, catcher.respond_to?(:any_method) - end - - # ------------------------------------------------------------------ - - class WellBehavedFooCatcher - def method_missing(method_name, *args, &block) - if method_name.to_s[0,3] == "foo" - "Foo to you too" - else - super(method_name, *args, &block) - end - end - end - - def test_foo_method_are_caught - catcher = WellBehavedFooCatcher.new - - assert_equal __, catcher.foo_bar - assert_equal __, catcher.foo_baz - end - - def test_non_foo_messages_are_treated_normally - catcher = WellBehavedFooCatcher.new - - assert_raise(___) do - catcher.normal_undefined_method - end - end - - # ------------------------------------------------------------------ - - # (note: just reopening class from above) - class WellBehavedFooCatcher - def respond_to?(method_name) - if method_name.to_s[0,3] == "foo" - true - else - super(method_name) - end - end - end - - def test_explicitly_implementing_respond_to_lets_objects_tell_the_truth - catcher = WellBehavedFooCatcher.new - - assert_equal __, catcher.respond_to?(:foo_bar) - assert_equal __, catcher.respond_to?(:something_else) - end - -end diff --git a/code/koans/about_methods.rb b/code/koans/about_methods.rb old mode 100644 new mode 100755 diff --git a/code/koans/about_modules.rb b/code/koans/about_modules.rb deleted file mode 100644 index 38652df..0000000 --- a/code/koans/about_modules.rb +++ /dev/null @@ -1,63 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutModules < Neo::Koan - module Nameable - def set_name(new_name) - @name = new_name - end - - def here - :in_module - end - end - - def test_cant_instantiate_modules - assert_raise(___) do - Nameable.new - end - end - - # ------------------------------------------------------------------ - - class Dog - include Nameable - - attr_reader :name - - def initialize - @name = "Fido" - end - - def bark - "WOOF" - end - - def here - :in_object - end - end - - def test_normal_methods_are_available_in_the_object - fido = Dog.new - assert_equal __, fido.bark - end - - def test_module_methods_are_also_available_in_the_object - fido = Dog.new - assert_nothing_raised do - fido.set_name("Rover") - end - end - - def test_module_methods_can_affect_instance_variables_in_the_object - fido = Dog.new - assert_equal __, fido.name - fido.set_name("Rover") - assert_equal __, fido.name - end - - def test_classes_can_override_module_methods - fido = Dog.new - assert_equal __, fido.here - end -end diff --git a/code/koans/about_nil.rb b/code/koans/about_nil.rb old mode 100644 new mode 100755 diff --git a/code/koans/about_objects.rb b/code/koans/about_objects.rb old mode 100644 new mode 100755 diff --git a/code/koans/about_open_classes.rb b/code/koans/about_open_classes.rb deleted file mode 100644 index 56d1817..0000000 --- a/code/koans/about_open_classes.rb +++ /dev/null @@ -1,45 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutOpenClasses < Neo::Koan - class Dog - def bark - "WOOF" - end - end - - def test_as_defined_dogs_do_bark - fido = Dog.new - assert_equal __, fido.bark - end - - # ------------------------------------------------------------------ - - # Open the existing Dog class and add a new method. - class Dog - def wag - "HAPPY" - end - end - - def test_after_reopening_dogs_can_both_wag_and_bark - fido = Dog.new - assert_equal __, fido.wag - assert_equal __, fido.bark - end - - # ------------------------------------------------------------------ - - class ::Integer - def even? - (self % 2) == 0 - end - end - - def test_even_existing_built_in_classes_can_be_reopened - assert_equal __, 1.even? - assert_equal __, 2.even? - end - - # NOTE: To understand why we need the :: before Integer, you need to - # become enlightened about scope. -end diff --git a/code/koans/about_proxy_object_project.rb b/code/koans/about_proxy_object_project.rb deleted file mode 100644 index 36d1cf0..0000000 --- a/code/koans/about_proxy_object_project.rb +++ /dev/null @@ -1,156 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -# Project: Create a Proxy Class -# -# In this assignment, create a proxy class (one is started for you -# below). You should be able to initialize the proxy object with any -# object. Any messages sent to the proxy object should be forwarded -# to the target object. As each message is sent, the proxy should -# record the name of the method sent. -# -# The proxy class is started for you. You will need to add a method -# missing handler and any other supporting methods. The specification -# of the Proxy class is given in the AboutProxyObjectProject koan. - -class Proxy - def initialize(target_object) - @object = target_object - # ADD MORE CODE HERE - end - - # WRITE CODE HERE -end - -# The proxy object should pass the following Koan: -# -class AboutProxyObjectProject < Neo::Koan - def test_proxy_method_returns_wrapped_object - # NOTE: The Television class is defined below - tv = Proxy.new(Television.new) - - # HINT: Proxy class is defined above, may need tweaking... - - assert tv.instance_of?(Proxy) - end - - def test_tv_methods_still_perform_their_function - tv = Proxy.new(Television.new) - - tv.channel = 10 - tv.power - - assert_equal 10, tv.channel - assert tv.on? - end - - def test_proxy_records_messages_sent_to_tv - tv = Proxy.new(Television.new) - - tv.power - tv.channel = 10 - - assert_equal [:power, :channel=], tv.messages - end - - def test_proxy_handles_invalid_messages - tv = Proxy.new(Television.new) - - assert_raise(NoMethodError) do - tv.no_such_method - end - end - - def test_proxy_reports_methods_have_been_called - tv = Proxy.new(Television.new) - - tv.power - tv.power - - assert tv.called?(:power) - assert ! tv.called?(:channel) - end - - def test_proxy_counts_method_calls - tv = Proxy.new(Television.new) - - tv.power - tv.channel = 48 - tv.power - - assert_equal 2, tv.number_of_times_called(:power) - assert_equal 1, tv.number_of_times_called(:channel=) - assert_equal 0, tv.number_of_times_called(:on?) - end - - def test_proxy_can_record_more_than_just_tv_objects - proxy = Proxy.new("Code Mash 2009") - - proxy.upcase! - result = proxy.split - - assert_equal ["CODE", "MASH", "2009"], result - assert_equal [:upcase!, :split], proxy.messages - end -end - - -# ==================================================================== -# The following code is to support the testing of the Proxy class. No -# changes should be necessary to anything below this comment. - -# Example class using in the proxy testing above. -class Television - attr_accessor :channel - - def power - if @power == :on - @power = :off - else - @power = :on - end - end - - def on? - @power == :on - end -end - -# Tests for the Television class. All of theses tests should pass. -class TelevisionTest < Neo::Koan - def test_it_turns_on - tv = Television.new - - tv.power - assert tv.on? - end - - def test_it_also_turns_off - tv = Television.new - - tv.power - tv.power - - assert ! tv.on? - end - - def test_edge_case_on_off - tv = Television.new - - tv.power - tv.power - tv.power - - assert tv.on? - - tv.power - - assert ! tv.on? - end - - def test_can_set_the_channel - tv = Television.new - - tv.channel = 11 - assert_equal 11, tv.channel - end -end diff --git a/code/koans/about_regular_expressions.rb b/code/koans/about_regular_expressions.rb old mode 100644 new mode 100755 diff --git a/code/koans/about_sandwich_code.rb b/code/koans/about_sandwich_code.rb deleted file mode 100644 index ca9c554..0000000 --- a/code/koans/about_sandwich_code.rb +++ /dev/null @@ -1,106 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutSandwichCode < Neo::Koan - - def count_lines(file_name) - file = open(file_name) - count = 0 - while file.gets - count += 1 - end - count - ensure - file.close if file - end - - def test_counting_lines - assert_equal __, count_lines("example_file.txt") - end - - # ------------------------------------------------------------------ - - def find_line(file_name) - file = open(file_name) - while line = file.gets - return line if line.match(/e/) - end - ensure - file.close if file - end - - def test_finding_lines - assert_equal __, find_line("example_file.txt") - end - - # ------------------------------------------------------------------ - # THINK ABOUT IT: - # - # The count_lines and find_line are similar, and yet different. - # They both follow the pattern of "sandwich code". - # - # Sandwich code is code that comes in three parts: (1) the top slice - # of bread, (2) the meat, and (3) the bottom slice of bread. The - # bread part of the sandwich almost always goes together, but - # the meat part changes all the time. - # - # Because the changing part of the sandwich code is in the middle, - # abstracting the top and bottom bread slices to a library can be - # difficult in many languages. - # - # (Aside for C++ programmers: The idiom of capturing allocated - # pointers in a smart pointer constructor is an attempt to deal with - # the problem of sandwich code for resource allocation.) - # - # Consider the following code: - # - - def file_sandwich(file_name) - file = open(file_name) - yield(file) - ensure - file.close if file - end - - # Now we write: - - def count_lines2(file_name) - file_sandwich(file_name) do |file| - count = 0 - while file.gets - count += 1 - end - count - end - end - - def test_counting_lines2 - assert_equal __, count_lines2("example_file.txt") - end - - # ------------------------------------------------------------------ - - def find_line2(file_name) - # Rewrite find_line using the file_sandwich library function. - end - - def test_finding_lines2 - assert_equal __, find_line2("example_file.txt") - end - - # ------------------------------------------------------------------ - - def count_lines3(file_name) - open(file_name) do |file| - count = 0 - while file.gets - count += 1 - end - count - end - end - - def test_open_handles_the_file_sandwich_when_given_a_block - assert_equal __, count_lines3("example_file.txt") - end - -end diff --git a/code/koans/about_scope.rb b/code/koans/about_scope.rb deleted file mode 100644 index 451e98b..0000000 --- a/code/koans/about_scope.rb +++ /dev/null @@ -1,79 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutScope < Neo::Koan - module Jims - class Dog - def identify - :jims_dog - end - end - end - - module Joes - class Dog - def identify - :joes_dog - end - end - end - - def test_dog_is_not_available_in_the_current_scope - assert_raise(___) do - Dog.new - end - end - - def test_you_can_reference_nested_classes_using_the_scope_operator - fido = Jims::Dog.new - rover = Joes::Dog.new - assert_equal __, fido.identify - assert_equal __, rover.identify - - assert_equal __, fido.class != rover.class - assert_equal __, Jims::Dog != Joes::Dog - end - - # ------------------------------------------------------------------ - - class String - end - - def test_bare_bones_class_names_assume_the_current_scope - assert_equal __, AboutScope::String == String - end - - def test_nested_string_is_not_the_same_as_the_system_string - assert_equal __, String == "HI".class - end - - def test_use_the_prefix_scope_operator_to_force_the_global_scope - assert_equal __, ::String == "HI".class - end - - # ------------------------------------------------------------------ - - PI = 3.1416 - - def test_constants_are_defined_with_an_initial_uppercase_letter - assert_equal __, PI - end - - # ------------------------------------------------------------------ - - MyString = ::String - - def test_class_names_are_just_constants - assert_equal __, MyString == ::String - assert_equal __, MyString == "HI".class - end - - def test_constants_can_be_looked_up_explicitly - assert_equal __, PI == AboutScope.const_get("PI") - assert_equal __, MyString == AboutScope.const_get("MyString") - end - - def test_you_can_get_a_list_of_constants_for_any_class_or_module - assert_equal __, Jims.constants - assert Object.constants.size > _n_ - end -end diff --git a/code/koans/about_scoring_project.rb b/code/koans/about_scoring_project.rb deleted file mode 100644 index bdc5dd1..0000000 --- a/code/koans/about_scoring_project.rb +++ /dev/null @@ -1,77 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -# Greed is a dice game where you roll up to five dice to accumulate -# points. The following "score" function will be used to calculate the -# score of a single roll of the dice. -# -# A greed roll is scored as follows: -# -# * A set of three ones is 1000 points -# -# * A set of three numbers (other than ones) is worth 100 times the -# number. (e.g. three fives is 500 points). -# -# * A one (that is not part of a set of three) is worth 100 points. -# -# * A five (that is not part of a set of three) is worth 50 points. -# -# * Everything else is worth 0 points. -# -# -# Examples: -# -# score([1,1,1,5,1]) => 1150 points -# score([2,3,4,6,2]) => 0 points -# score([3,4,5,3,3]) => 350 points -# score([1,5,1,2,4]) => 250 points -# -# More scoring examples are given in the tests below: -# -# Your goal is to write the score method. - -def score(dice) - # You need to write this method -end - -class AboutScoringProject < Neo::Koan - def test_score_of_an_empty_list_is_zero - assert_equal 0, score([]) - end - - def test_score_of_a_single_roll_of_5_is_50 - assert_equal 50, score([5]) - end - - def test_score_of_a_single_roll_of_1_is_100 - assert_equal 100, score([1]) - end - - def test_score_of_multiple_1s_and_5s_is_the_sum_of_individual_scores - assert_equal 300, score([1,5,5,1]) - end - - def test_score_of_single_2s_3s_4s_and_6s_are_zero - assert_equal 0, score([2,3,4,6]) - end - - def test_score_of_a_triple_1_is_1000 - assert_equal 1000, score([1,1,1]) - end - - def test_score_of_other_triples_is_100x - assert_equal 200, score([2,2,2]) - assert_equal 300, score([3,3,3]) - assert_equal 400, score([4,4,4]) - assert_equal 500, score([5,5,5]) - assert_equal 600, score([6,6,6]) - end - - def test_score_of_mixed_is_sum - assert_equal 250, score([2,5,2,2,3]) - assert_equal 550, score([5,5,5,5]) - assert_equal 1100, score([1,1,1,1]) - assert_equal 1200, score([1,1,1,1,1]) - assert_equal 1150, score([1,1,1,5,1]) - end - -end diff --git a/code/koans/about_strings.rb b/code/koans/about_strings.rb old mode 100644 new mode 100755 diff --git a/code/koans/about_symbols.rb b/code/koans/about_symbols.rb old mode 100644 new mode 100755 diff --git a/code/koans/about_to_str.rb b/code/koans/about_to_str.rb deleted file mode 100644 index c4e3484..0000000 --- a/code/koans/about_to_str.rb +++ /dev/null @@ -1,54 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutToStr < Neo::Koan - - class CanNotBeTreatedAsString - def to_s - "non-string-like" - end - end - - def test_to_s_returns_a_string_representation - not_like_a_string = CanNotBeTreatedAsString.new - assert_equal __, not_like_a_string.to_s - end - - def test_normally_objects_cannot_be_used_where_strings_are_expected - assert_raise(___) do - File.exist?(CanNotBeTreatedAsString.new) - end - end - - # ------------------------------------------------------------------ - - class CanBeTreatedAsString - def to_s - "string-like" - end - - def to_str - to_s - end - end - - def test_to_str_also_returns_a_string_representation - like_a_string = CanBeTreatedAsString.new - assert_equal __, like_a_string.to_str - end - - def test_to_str_allows_objects_to_be_treated_as_strings - assert_equal __, File.exist?(CanBeTreatedAsString.new) - end - - # ------------------------------------------------------------------ - - def acts_like_a_string?(string) - string = string.to_str if string.respond_to?(:to_str) - string.is_a?(String) - end - - def test_user_defined_code_can_check_for_to_str - assert_equal __, acts_like_a_string?(CanNotBeTreatedAsString.new) - assert_equal __, acts_like_a_string?(CanBeTreatedAsString.new) - end -end diff --git a/code/koans/about_triangle_project.rb b/code/koans/about_triangle_project.rb deleted file mode 100644 index 2ac9d9a..0000000 --- a/code/koans/about_triangle_project.rb +++ /dev/null @@ -1,24 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -# You need to write the triangle method in the file 'triangle.rb' -require './triangle' - -class AboutTriangleProject < Neo::Koan - def test_equilateral_triangles_have_equal_sides - assert_equal :equilateral, triangle(2, 2, 2) - assert_equal :equilateral, triangle(10, 10, 10) - end - - def test_isosceles_triangles_have_exactly_two_sides_equal - assert_equal :isosceles, triangle(3, 4, 4) - assert_equal :isosceles, triangle(4, 3, 4) - assert_equal :isosceles, triangle(4, 4, 3) - assert_equal :isosceles, triangle(10, 10, 2) - end - - def test_scalene_triangles_have_no_equal_sides - assert_equal :scalene, triangle(3, 4, 5) - assert_equal :scalene, triangle(10, 11, 12) - assert_equal :scalene, triangle(5, 4, 2) - end -end diff --git a/code/koans/about_triangle_project_2.rb b/code/koans/about_triangle_project_2.rb deleted file mode 100644 index fdeb8db..0000000 --- a/code/koans/about_triangle_project_2.rb +++ /dev/null @@ -1,16 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -# You need to write the triangle method in the file 'triangle.rb' -require './triangle.rb' - -class AboutTriangleProject2 < Neo::Koan - # The first assignment did not talk about how to handle errors. - # Let's handle that part now. - def test_illegal_triangles_throw_exceptions - assert_raise(TriangleError) do triangle(0, 0, 0) end - assert_raise(TriangleError) do triangle(3, 4, -5) end - assert_raise(TriangleError) do triangle(1, 1, 3) end - assert_raise(TriangleError) do triangle(2, 4, 2) end - # HINT: for tips, see http://stackoverflow.com/questions/3834203/ruby-koan-151-raising-exceptions - end -end diff --git a/code/koans/about_true_and_false.rb b/code/koans/about_true_and_false.rb deleted file mode 100644 index 0b876ee..0000000 --- a/code/koans/about_true_and_false.rb +++ /dev/null @@ -1,33 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutTrueAndFalse < Neo::Koan - def truth_value(condition) - if condition - :true_stuff - else - :false_stuff - end - end - - def test_true_is_treated_as_true - assert_equal __, truth_value(true) - end - - def test_false_is_treated_as_false - assert_equal __, truth_value(false) - end - - def test_nil_is_treated_as_false_too - assert_equal __, truth_value(nil) - end - - def test_everything_else_is_treated_as_true - assert_equal __, truth_value(1) - assert_equal __, truth_value(0) - assert_equal __, truth_value([]) - assert_equal __, truth_value({}) - assert_equal __, truth_value("Strings") - assert_equal __, truth_value("") - end - -end diff --git a/code/koans/about_variable_scope.rb b/code/koans/about_variable_scope.rb deleted file mode 100644 index 71a8087..0000000 --- a/code/koans/about_variable_scope.rb +++ /dev/null @@ -1,114 +0,0 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') - -class AboutVariableScope < Neo::Koan - - def bark - noise = "RUFF" - end - - def test_noise_is_not_available_in_the_current_scope - - assert_raise(___) do - noise - end - - end - - def test_we_can_get_noise_by_calling_method - assert_equal __, bark - end - - inaccessible = "Outside our universe" - def test_defs_cannot_access_variables_outside_scope - # defined? does not return true or false - assert_equal __, defined? inaccesible - end - - # ------------------------------------------------------ - - def test_blocks_can_access_variables_outside_scope - test = "Hi" - (1..2).each do - test = "Hey" - end - - assert_equal __, test - end - - def test_block_variables_cannot_be_accessed_outside_scope - (1..2).each do - x = 0 - end - assert_equal __, defined? x - end - - # ------------------------------------------------------ - - class Mouse - @@total = 0 - # Class variables are prefixed with two '@' characters. - - def initialize(n) - @name = n - # Instance variables are prefixed with one '@' character. - @@total += 1 - end - - def name - @name - end - - def Mouse.count - @@total - end - end - - def test_instance_variable - oscar = Mouse.new("Oscar") - assert_equal __, oscar.name - end - - def test_class_variable - (1..9).each { |i| Mouse.new("#{i}") } - # Things may appear easier than they actually are. - assert_equal __, Mouse.count - end - - # Meditate on the following: - # What is the difference between a class variable and instance variable? - - # ------------------------------------------------------ - - $anywhere = "Anywhere" - # Global variables are prefixed with the '$' character. - - def test_global_variables_can_be_accessed_from_any_scope - assert_equal __, $anywhere - end - - def test_global_variables_can_be_changed_from_any_scope - # From within a method - $anywhere = "Here" - assert_equal __, $anywhere - end - - def test_global_variables_retain_value_from_last_change - # What is $anywhere? - assert_equal __, $anywhere - end - - def test_global_variables_can_be_changed_from_any_scope_2 - # From within a block - (1..2).each do - $anywhere = "Hey" - end - - assert_equal __, $anywhere - end - -end - -# THINK ABOUT IT: -# -# What will $anywhere be down here, outside of the scope of the -# AboutVariableScope class? diff --git a/code/koans/example_file.txt b/code/koans/example_file.txt deleted file mode 100644 index ffe7cbd..0000000 --- a/code/koans/example_file.txt +++ /dev/null @@ -1,4 +0,0 @@ -this -is -a -test diff --git a/code/koans/koans.watchr b/code/koans/koans.watchr deleted file mode 100644 index b740cf9..0000000 --- a/code/koans/koans.watchr +++ /dev/null @@ -1,3 +0,0 @@ -watch( '.*\.rb' ) do - system 'rake' -end diff --git a/code/koans/neo.rb b/code/koans/neo.rb deleted file mode 100644 index 18e7ef7..0000000 --- a/code/koans/neo.rb +++ /dev/null @@ -1,535 +0,0 @@ -#!/usr/bin/env ruby -# -*- ruby -*- - -begin - require 'win32console' -rescue LoadError -end - -# -------------------------------------------------------------------- -# Support code for the Ruby Koans. -# -------------------------------------------------------------------- - -class FillMeInError < StandardError -end - -def ruby_version?(version) - RUBY_VERSION =~ /^#{version}/ || - (version == 'jruby' && defined?(JRUBY_VERSION)) || - (version == 'mri' && ! defined?(JRUBY_VERSION)) -end - -def in_ruby_version(*versions) - yield if versions.any? { |v| ruby_version?(v) } -end - -in_ruby_version("1.8") do - class KeyError < StandardError - end -end - -# Standard, generic replacement value. -# If value19 is given, it is used in place of value for Ruby 1.9. -def __(value="FILL ME IN", value19=:mu) - if RUBY_VERSION < "1.9" - value - else - (value19 == :mu) ? value : value19 - end -end - -# Numeric replacement value. -def _n_(value=999999, value19=:mu) - if RUBY_VERSION < "1.9" - value - else - (value19 == :mu) ? value : value19 - end -end - -# Error object replacement value. -def ___(value=FillMeInError, value19=:mu) - if RUBY_VERSION < "1.9" - value - else - (value19 == :mu) ? value : value19 - end -end - -# Method name replacement. -class Object - def ____(method=nil) - if method - self.send(method) - end - end - - in_ruby_version("1.9", "2") do - public :method_missing - end -end - -class String - def side_padding(width) - extra = width - self.size - if width < 0 - self - else - left_padding = extra / 2 - right_padding = (extra+1)/2 - (" " * left_padding) + self + (" " *right_padding) - end - end -end - -module Neo - class << self - def simple_output - ENV['SIMPLE_KOAN_OUTPUT'] == 'true' - end - end - - module Color - #shamelessly stolen (and modified) from redgreen - COLORS = { - :clear => 0, :black => 30, :red => 31, - :green => 32, :yellow => 33, :blue => 34, - :magenta => 35, :cyan => 36, - } - - module_function - - COLORS.each do |color, value| - module_eval "def #{color}(string); colorize(string, #{value}); end" - module_function color - end - - def colorize(string, color_value) - if use_colors? - color(color_value) + string + color(COLORS[:clear]) - else - string - end - end - - def color(color_value) - "\e[#{color_value}m" - end - - def use_colors? - return false if ENV['NO_COLOR'] - if ENV['ANSI_COLOR'].nil? - if using_windows? - using_win32console - else - return true - end - else - ENV['ANSI_COLOR'] =~ /^(t|y)/i - end - end - - def using_windows? - File::ALT_SEPARATOR - end - - def using_win32console - defined? Win32::Console - end - end - - module Assertions - FailedAssertionError = Class.new(StandardError) - - def flunk(msg) - raise FailedAssertionError, msg - end - - def assert(condition, msg=nil) - msg ||= "Failed assertion." - flunk(msg) unless condition - true - end - - def assert_equal(expected, actual, msg=nil) - msg ||= "Expected #{expected.inspect} to equal #{actual.inspect}" - assert(expected == actual, msg) - end - - def assert_not_equal(expected, actual, msg=nil) - msg ||= "Expected #{expected.inspect} to not equal #{actual.inspect}" - assert(expected != actual, msg) - end - - def assert_nil(actual, msg=nil) - msg ||= "Expected #{actual.inspect} to be nil" - assert(nil == actual, msg) - end - - def assert_not_nil(actual, msg=nil) - msg ||= "Expected #{actual.inspect} to not be nil" - assert(nil != actual, msg) - end - - def assert_match(pattern, actual, msg=nil) - msg ||= "Expected #{actual.inspect} to match #{pattern.inspect}" - assert pattern =~ actual, msg - end - - def assert_raise(exception) - begin - yield - rescue Exception => ex - expected = ex.is_a?(exception) - assert(expected, "Exception #{exception.inspect} expected, but #{ex.inspect} was raised") - return ex - end - flunk "Exception #{exception.inspect} expected, but nothing raised" - end - - def assert_nothing_raised - begin - yield - rescue Exception => ex - flunk "Expected nothing to be raised, but exception #{exception.inspect} was raised" - end - end - end - - class Sensei - attr_reader :failure, :failed_test, :pass_count - - FailedAssertionError = Assertions::FailedAssertionError - - def initialize - @pass_count = 0 - @failure = nil - @failed_test = nil - @observations = [] - end - - PROGRESS_FILE_NAME = '.path_progress' - - def add_progress(prog) - @_contents = nil - exists = File.exists?(PROGRESS_FILE_NAME) - File.open(PROGRESS_FILE_NAME,'a+') do |f| - f.print "#{',' if exists}#{prog}" - end - end - - def progress - if @_contents.nil? - if File.exists?(PROGRESS_FILE_NAME) - File.open(PROGRESS_FILE_NAME,'r') do |f| - @_contents = f.read.to_s.gsub(/\s/,'').split(',') - end - else - @_contents = [] - end - end - @_contents - end - - def observe(step) - if step.passed? - @pass_count += 1 - if @pass_count > progress.last.to_i - @observations << Color.green("#{step.koan_file}##{step.name} has expanded your awareness.") - end - else - @failed_test = step - @failure = step.failure - add_progress(@pass_count) - @observations << Color.red("#{step.koan_file}##{step.name} has damaged your karma.") - throw :neo_exit - end - end - - def failed? - ! @failure.nil? - end - - def assert_failed? - failure.is_a?(FailedAssertionError) - end - - def instruct - if failed? - @observations.each{|c| puts c } - encourage - guide_through_error - a_zenlike_statement - show_progress - else - end_screen - end - end - - def show_progress - bar_width = 50 - total_tests = Neo::Koan.total_tests - scale = bar_width.to_f/total_tests - print Color.green("your path thus far [") - happy_steps = (pass_count*scale).to_i - happy_steps = 1 if happy_steps == 0 && pass_count > 0 - print Color.green('.'*happy_steps) - if failed? - print Color.red('X') - print Color.cyan('_'*(bar_width-1-happy_steps)) - end - print Color.green(']') - print " #{pass_count}/#{total_tests}" - puts - end - - def end_screen - if Neo.simple_output - boring_end_screen - else - artistic_end_screen - end - end - - def boring_end_screen - puts "Mountains are again merely mountains" - end - - def artistic_end_screen - "JRuby 1.9.x Koans" - ruby_version = "(in #{'J' if defined?(JRUBY_VERSION)}Ruby #{defined?(JRUBY_VERSION) ? JRUBY_VERSION : RUBY_VERSION})" - ruby_version = ruby_version.side_padding(54) - completed = <<-ENDTEXT - ,, , ,, - : ::::, :::, - , ,,: :::::::::::::,, :::: : , - , ,,, ,:::::::::::::::::::, ,: ,: ,, - :, ::, , , :, ,::::::::::::::::::, ::: ,:::: - : : ::, ,:::::::: ::, ,:::: - , ,::::: :,:::::::,::::, - ,: , ,:,,: ::::::::::::: - ::,: ,,:::, ,::::::::::::, - ,:::, :,,::: ::::::::::::, - ,::: :::::::, Mountains are again merely mountains ,:::::::::::: - :::,,,:::::: :::::::::::: - ,:::::::::::, ::::::::::::, - :::::::::::, ,:::::::::::: -::::::::::::: ,:::::::::::: -:::::::::::: Ruby Koans :::::::::::: -::::::::::::#{ ruby_version },:::::::::::: -:::::::::::, , ::::::::::: -,:::::::::::::, brought to you by ,,:::::::::::: -:::::::::::::: ,:::::::::::: - ::::::::::::::, ,::::::::::::: - ::::::::::::, Neo Software Artisans , :::::::::::: - :,::::::::: :::: ::::::::::::: - ,::::::::::: ,: ,,:::::::::::::, - :::::::::::: ,::::::::::::::, - :::::::::::::::::, :::::::::::::::: - :::::::::::::::::::, :::::::::::::::: - ::::::::::::::::::::::, ,::::,:, , ::::,::: - :::::::::::::::::::::::, ::,: ::,::, ,,: :::: - ,:::::::::::::::::::: ::,, , ,, ,:::: - ,:::::::::::::::: ::,, , ,:::, - ,:::: , ,, - ,,, -ENDTEXT - puts completed - end - - def encourage - puts - puts "The Master says:" - puts Color.cyan(" You have not yet reached enlightenment.") - if ((recents = progress.last(5)) && recents.size == 5 && recents.uniq.size == 1) - puts Color.cyan(" I sense frustration. Do not be afraid to ask for help.") - elsif progress.last(2).size == 2 && progress.last(2).uniq.size == 1 - puts Color.cyan(" Do not lose hope.") - elsif progress.last.to_i > 0 - puts Color.cyan(" You are progressing. Excellent. #{progress.last} completed.") - end - end - - def guide_through_error - puts - puts "The answers you seek..." - puts Color.red(indent(failure.message).join) - puts - puts "Please meditate on the following code:" - puts embolden_first_line_only(indent(find_interesting_lines(failure.backtrace))) - puts - end - - def embolden_first_line_only(text) - first_line = true - text.collect { |t| - if first_line - first_line = false - Color.red(t) - else - Color.cyan(t) - end - } - end - - def indent(text) - text = text.split(/\n/) if text.is_a?(String) - text.collect{|t| " #{t}"} - end - - def find_interesting_lines(backtrace) - backtrace.reject { |line| - line =~ /neo\.rb/ - } - end - - # Hat's tip to Ara T. Howard for the zen statements from his - # metakoans Ruby Quiz (http://rubyquiz.com/quiz67.html) - def a_zenlike_statement - if !failed? - zen_statement = "Mountains are again merely mountains" - else - zen_statement = case (@pass_count % 10) - when 0 - "mountains are merely mountains" - when 1, 2 - "learn the rules so you know how to break them properly" - when 3, 4 - "remember that silence is sometimes the best answer" - when 5, 6 - "sleep is the best meditation" - when 7, 8 - "when you lose, don't lose the lesson" - else - "things are not what they appear to be: nor are they otherwise" - end - end - puts Color.green(zen_statement) - end - end - - class Koan - include Assertions - - attr_reader :name, :failure, :koan_count, :step_count, :koan_file - - def initialize(name, koan_file=nil, koan_count=0, step_count=0) - @name = name - @failure = nil - @koan_count = koan_count - @step_count = step_count - @koan_file = koan_file - end - - def passed? - @failure.nil? - end - - def failed(failure) - @failure = failure - end - - def setup - end - - def teardown - end - - def meditate - setup - begin - send(name) - rescue StandardError, Neo::Sensei::FailedAssertionError => ex - failed(ex) - ensure - begin - teardown - rescue StandardError, Neo::Sensei::FailedAssertionError => ex - failed(ex) if passed? - end - end - self - end - - # Class methods for the Neo test suite. - class << self - def inherited(subclass) - subclasses << subclass - end - - def method_added(name) - testmethods << name if !tests_disabled? && Koan.test_pattern =~ name.to_s - end - - def end_of_enlightenment - @tests_disabled = true - end - - def command_line(args) - args.each do |arg| - case arg - when /^-n\/(.*)\/$/ - @test_pattern = Regexp.new($1) - when /^-n(.*)$/ - @test_pattern = Regexp.new(Regexp.quote($1)) - else - if File.exist?(arg) - load(arg) - else - fail "Unknown command line argument '#{arg}'" - end - end - end - end - - # Lazy initialize list of subclasses - def subclasses - @subclasses ||= [] - end - - # Lazy initialize list of test methods. - def testmethods - @test_methods ||= [] - end - - def tests_disabled? - @tests_disabled ||= false - end - - def test_pattern - @test_pattern ||= /^test_/ - end - - def total_tests - self.subclasses.inject(0){|total, k| total + k.testmethods.size } - end - end - end - - class ThePath - def walk - sensei = Neo::Sensei.new - each_step do |step| - sensei.observe(step.meditate) - end - sensei.instruct - end - - def each_step - catch(:neo_exit) { - step_count = 0 - Neo::Koan.subclasses.each_with_index do |koan,koan_index| - koan.testmethods.each do |method_name| - step = koan.new(method_name, koan.to_s, koan_index+1, step_count+=1) - yield step - end - end - } - end - end -end - -END { - Neo::Koan.command_line(ARGV) - Neo::ThePath.new.walk -} diff --git a/code/koans/path_to_enlightenment.rb b/code/koans/path_to_enlightenment.rb old mode 100644 new mode 100755 diff --git a/code/koans/triangle.rb b/code/koans/triangle.rb deleted file mode 100644 index 8df052a..0000000 --- a/code/koans/triangle.rb +++ /dev/null @@ -1,22 +0,0 @@ -# Triangle Project Code. - -# Triangle analyzes the lengths of the sides of a triangle -# (represented by a, b and c) and returns the type of triangle. -# -# It returns: -# :equilateral if all sides are equal -# :isosceles if exactly 2 sides are equal -# :scalene if no sides are equal -# -# The tests for this method can be found in -# about_triangle_project.rb -# and -# about_triangle_project_2.rb -# -def triangle(a, b, c) - # WRITE THIS CODE -end - -# Error class used in part 2. No need to change this code. -class TriangleError < StandardError -end diff --git a/code/koans/versioning_spec.rb b/code/koans/versioning_spec.rb deleted file mode 100644 index 44cc763..0000000 --- a/code/koans/versioning_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ - -def version_ints(version) - version.split(".").map { |v| v.to_i } -end - -def at_least_ruby_version(version) - vints = version_ints(version) - ruby_vints = version_ints(RUBY_VERSION) - vints.zip(ruby_vints).all? { |v, rv| v.nil? || rv.nil? || v >= rv } -end - - -require 'rspec/given' - -describe "#version_ints" do - Then { version_ints("1.2") == [1, 2] } - Then { version_ints("2.1.20") == [2, 1, 20] } -end - -describe "at_least_ruby_version" do - Then { at_least_ruby_version("2") } - Then { at_least_ruby_version("2.0") } - Then { at_least_ruby_version("2.0.1") } - Then { at_least_ruby_version("2.1") } - Then { at_least_ruby_version("2.1.3.4.1") } - - Then { ! at_least_ruby_version("1.9") } - Then { ! at_least_ruby_version("1.9.9.9.9") } -end diff --git a/code/wolf-wolfpack.rb b/code/wolf-wolfpack.rb deleted file mode 100644 index c922fc4..0000000 --- a/code/wolf-wolfpack.rb +++ /dev/null @@ -1,5 +0,0 @@ -access Wolf @age and @name in Wolfpack? -Compare wolf1 to wolf2? -How to add wolves to array which is pack? -Sort wolves in array by age? -Name => Age Hash From b5c61c5d90961ebcae7bd392c2b841c3fa8b25df Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Thu, 15 Jan 2015 05:44:08 -0500 Subject: [PATCH 52/59] remove data_types.md --- docs/data_types.md | 97 ---------------------------------------------- 1 file changed, 97 deletions(-) delete mode 100644 docs/data_types.md diff --git a/docs/data_types.md b/docs/data_types.md deleted file mode 100644 index 458c9fa..0000000 --- a/docs/data_types.md +++ /dev/null @@ -1,97 +0,0 @@ -Data Types -=================== -### `Numbers` -* **What does it mean?** Numbers can be integers or floats. Integers are numbers without decimal points and floats are numbers with decimal points -* **How do you make one?** `7` #integer `8.0` #float. -* **Why would you want one of those?** You can use numbers to perform arithmetic `5 + 6` or you can use floats as you would with a simple calculator `11.2 + 10.0` -* **What can you do with a number?** -```ruby - # You can convert it into a string: - 1543.to_s #=> 1543 - - - # You can convert it into a float: - 123.to_f #=> 123.0 - - # You can convert it into an integer: - 7654.46.to_i #=> 7654 - - # You can add, subtract, divide and multiply numbers: - 567.0 - 300 #=> 267.0 - 400 + 435 #=> 835 - 300 / 3.0 #=> 100.0 - 33 * 10 #=> 330 - - # You can get the absolute value: - -45.abs #=> 45 - -``` -### `Strings` -* **What does it mean?** Group of characters in a program including letters, numbers, symbols and spaces. -* **How do you make one?** `'I am a string!'` or `'I am a string with character :) and symbols #$(@*#)$'` -* **Why would you want one of those?** You can use strings for message output `puts 'Good Morning, Joe!'` -* **What can you do with a string?** -```ruby - # You can add it to another string: - 'I like' + ' mushrooms on my pizza!' #=> I like mushrooms on my pizza! - - # You can convert it to a float: - '123'.to_f #=> 123.0 - - # You can convert it to an integer: - '7654.46'.to_i #=> 7654 - - # You can multiply strings: - 'Ham & Cheese ' * 3 #=> Ham & Cheese Ham & Cheese Ham & Cheese - - # You can upcase, downcase and capitalize a string: - 'i want to grow up'.upcase #=> "I WANT TO GROW UP" - 'tUrn Me INto A ProPer SentencE.'.capitalize #=> "Turn me into a proper sentence" - 'STOP SHOUTING!!'.downcase #=> "stop shouting!!" - - -``` - -### `Array` -* **What does it mean?** Arrays are ordered, integer-indexed collections of any object. -* **How do you make one?** `array = Array.new` or `array = [1,5,12,19,20]` -* **Why would you want one of those?** Arrays provide a way to store things and access them late. You could use an array to -keep track of students `array = [Joe, Angela, Spencer,Kelly, Andell, Peter, Ivan, Jeff]` you can also use them to -* **What can you do with a string?** -```ruby - # You can convert them into strings: - numbers = [1,2,3,6,7] - numbers.to_s #=> "[1, 2, 3, 6, 7]" - - # You can sort an array: - numbers.sort #=> [1, 2, 3, 6, 7] -<<<<<<< HEAD - - # You can use push to add to an array: - numbers.push '12' => [1, 2, 3, 6, 7, "12"] - - # You can remove items from an array with pop: - numbers.pop => "12" - - - - -``` - -======= ->>>>>>> 8965e49020640ae991075baf745a4ae885ec204f - - # You can use push to add to an array: - numbers.push '12' => [1, 2, 3, 6, 7, "12"] - - # You can remove items from an array with pop: - numbers.pop => "12" - - - - -``` - - - - From 31292932ba168d70befb99974facdfc680a15359 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Thu, 15 Jan 2015 06:29:44 -0500 Subject: [PATCH 53/59] complete examples for Array methoda --- docs/array_methods.rb | 192 +++++++++++++++++++++++++++++++----------- 1 file changed, 143 insertions(+), 49 deletions(-) diff --git a/docs/array_methods.rb b/docs/array_methods.rb index 914ab02..2f25e1a 100644 --- a/docs/array_methods.rb +++ b/docs/array_methods.rb @@ -1,38 +1,131 @@ + -[2, 6, 8] + [ 9, 12, 13] #=> [2, 6, 8, 9, 12, 13] +#[2, 6, 8] + [ 9, 12, 13] => [2, 6, 8, 9, 12, 13] + << -[12, 4, 13, 6] << 45 #==> [12, 4, 13, 6, 45] +#[12, 4, 13, 6] << 45 ==> [12, 4, 13, 6, 45] + == -# [1, 23, 45] == [1, 23, 45] ==> true -[] # +#[1, 23, 45] == [1, 23, 45] ==> true + +[] +# array = Array.new ==> [] + []= -collect(!) (aka map(!)) # an_array[1,2,3,6,5,6] an_array[1,2,3,6,5,6] +# array1 = [1,3,4,5,6] +# array1[2] ==> 4 + +collect(!) (aka map(!)) +# an_array = [1,2,3,6,5,6] +# another_array = Array.new +# an_array.collect { |a| another_array << a * 2 } +# another_array +#==> [2,4, 6, 12,10,12] + + compact(!) -each #new_array = [1, 2] newer_array = [] new_array.each{|n| newer_array << n * 5} -#newer_array = [] new_array.each{|n| newer_array << n * 5 if n > 1} -empty? ## newer_array.empty? ==> false -index # [20,45,60].index(45) ==> 1 +# array_blanks = [1,3, nil,1, nil] +# array_blanks.compact! +#==> [1,3,1] + +each +# ary = [1,2,3,4,5] +# ary.each do |each_a| +# puts each_a +# end +#==> +#1 +#2 +#3 +#4 +#5 + + +empty? +# new_array = [1,2,3] +# new_array.empty? ==> false + + +index +# [20,45,60].index(45) ==> 1 + first +# array = [40,3,4,6] +# array.first ==> 40 + flatten(!) +# array1 = [4, 12, 34, [45, 56]] +# array1.flatten! ==> [4,12,34,45,56] + include? -index -join #comic_book_guy_words = %w(worst episode ever) ==> ["worst", "episode","ever"] +# array2 = [ 32, 12, 56] +# array2.include?(32) ==> true + + +join +#comic_book_guy_words = %w(worst episode ever) ==> ["worst", "episode","ever"] #comic_book_guy_words.join('!') ==>"worst!episode!ever!" + last +# array2 = [ 32, 12, 56] +# array2.last ==> 56 + length (aka size) +# array2 = [ 32, 12, 56] +# array2.length ==> 3 + pop +# array2 = [ 32, 12, 56] +# array2.pop ==> 56 + push -reject(!) #strange_array.reject{|thing| thing.is_a?String} +# array3 = [ 13, 32, 34, 12, 56] +# array3.push(12) ==> [12, 13, 32, 34, 12, 56] + +reject(!) +# strange_array = ['dog', 'cat', 1, 'boo', 4, 5, 6] +# strange_array.reject{|thing| thing.is_a?String} ==> [1, 4, 5, 6] + + reverse +# strange_array = ['dog', 'cat', 1, 'boo', 4, 5, 6] +# strange_array.reverse ==> [6, 5, 4, 'boo', 1, 'cat', 'dog'] + select(!) +# strange_array = ['dog', 'cat', 1, 'boo', 4, 5, 6] +# strange_array.select {|a| a.is_a?String} ==> ['dog', 'cat', 'boo'] + shift +# strange_array = ['dog', 'cat', 1, 'boo', 4, 5, 6] +# strange_array.shift ==> ['cat', 1, 'boo', 4, 5, 6] + shuffle +# array_shuf = ['cat', 1, 'boo', 4, 5, 6] +# will be random, example return ==> [5, "boo", 4, 6, "cat", 1] + sort(!) +# array4 = [4, 2, 3] +# array4.sort ==> [2, 3, 4] + sort_by(!) +# array = [] +# john = {:name => "john", :age => 23} +# tom = {:name => "tom", :age => 45} +# adam = {:name => "adam", :age => 3} +# array.push(john, tom, adam) +# guys = array.sort_by do |guy| guy[:age] +# end +# puts guys ==> [{:name=>"adam", :age=>3}, {:name=>"john", :age=>23}, {:name=>"tom", :age=>45}] + uniq(!) +# array_u = [1, 4, 6, 7, 4, 4, 1, 7] +# array_u.uniq ==> [1, 4, 6, 7] + unshift -Enumerable +# array_u = [1, 4, 6, 7, 4, 4, 1, 7] +# array_u.unshift(34) ==> [34, 1, 4, 6, 7, 4, 4, 1, 7] + +Enumerable all? any? detect @@ -47,15 +140,15 @@ min_by partition reduce -String +String * + << =~ - [] +[] []= - capitalize(!) +capitalize(!) chomp(!) downcase(!) each_line @@ -66,39 +159,40 @@ to_i to_f to_sym -Object + +Object class inspect - instance_of? - is_a? - kind_of? - methods - nil? - respond_to? - send - tap - Hash - - [] - []=delete - each - each_key - each_value - empty? - fetch - has_key? - has_value? - include? - invert - keep_if - key - keys - length - merge(!) - reject(!) - select(!) - values - Range - - nested_array = \ No newline at end of file +instance_of? +is_a? +kind_of? +methods +nil? +respond_to? +send +tap + +Hash +[] +[]=delete +each +each_key +each_value +empty? +fetch +has_key? +has_value? +include? +invert +keep_if +key +keys +length +merge(!) +reject(!) +select(!) +values + +Range +nested_array = \ No newline at end of file From 1f4d84c7388786cbf88be0aab80ae163afdaceea Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Thu, 15 Jan 2015 06:39:52 -0500 Subject: [PATCH 54/59] remove methods that do not have examples --- docs/array_methods.rb | 71 ---------------------- docs/frequently_used_methods_incomplete.rb | 0 2 files changed, 71 deletions(-) create mode 100644 docs/frequently_used_methods_incomplete.rb diff --git a/docs/array_methods.rb b/docs/array_methods.rb index 2f25e1a..413110b 100644 --- a/docs/array_methods.rb +++ b/docs/array_methods.rb @@ -125,74 +125,3 @@ # array_u.unshift(34) ==> [34, 1, 4, 6, 7, 4, 4, 1, 7] -Enumerable -all? -any? -detect -each_with_index -grep -group_by -inject -max -max_by -member? -min -min_by -partition -reduce - -String -* -+ -<< -=~ -[] -[]= -capitalize(!) -chomp(!) -downcase(!) -each_line -empty? -gsub(!) -include? -sub(!) -to_i -to_f -to_sym - - -Object -class -inspect -instance_of? -is_a? -kind_of? -methods -nil? -respond_to? -send -tap - -Hash -[] -[]=delete -each -each_key -each_value -empty? -fetch -has_key? -has_value? -include? -invert -keep_if -key -keys -length -merge(!) -reject(!) -select(!) -values - -Range -nested_array = \ No newline at end of file diff --git a/docs/frequently_used_methods_incomplete.rb b/docs/frequently_used_methods_incomplete.rb new file mode 100644 index 0000000..e69de29 From eab53b2175ae4966f606c5bdcf44d9e6d36d39d0 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Thu, 15 Jan 2015 06:40:40 -0500 Subject: [PATCH 55/59] create separate file for frequently used methods that do not have examples yet --- docs/frequently_used_methods_incomplete.rb | 71 ++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/docs/frequently_used_methods_incomplete.rb b/docs/frequently_used_methods_incomplete.rb index e69de29..c0bc070 100644 --- a/docs/frequently_used_methods_incomplete.rb +++ b/docs/frequently_used_methods_incomplete.rb @@ -0,0 +1,71 @@ +Enumerable +all? +any? +detect +each_with_index +grep +group_by +inject +max +max_by +member? +min +min_by +partition +reduce + +String +* ++ +<< +=~ + [] +[]= + capitalize(!) +chomp(!) +downcase(!) +each_line +empty? +gsub(!) +include? +sub(!) +to_i +to_f +to_sym + + +Object +class +inspect + instance_of? + is_a? + kind_of? + methods + nil? + respond_to? + send + tap + + Hash + [] + []=delete + each + each_key + each_value + empty? + fetch + has_key? + has_value? + include? + invert + keep_if + key + keys + length + merge(!) + reject(!) + select(!) + values + + Range + nested_array = \ No newline at end of file From a4d5ef5b955d06f67d20e7b9365772388101bfca Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Thu, 15 Jan 2015 07:02:42 -0500 Subject: [PATCH 56/59] add join_pack test --- code/wolf/wolf_test.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/wolf/wolf_test.rb b/code/wolf/wolf_test.rb index a23224f..5384ad4 100644 --- a/code/wolf/wolf_test.rb +++ b/code/wolf/wolf_test.rb @@ -11,7 +11,6 @@ class TestWolf < MiniTest::Unit::TestCase def setup #this runs before each test @wolf = Wolf.new('wolfie', 23) - @wolves = [] end def test_wolf_exists @@ -37,8 +36,7 @@ def test_wolf_is_submissive_to end def test_wolf_can_join_pack - assert_equal ['wolfie'],@wolf.join_pack + assert_equal ['wolfie'], @wolf.join_pack end - end \ No newline at end of file From 58935142b4b20b760c17c9a72dd641dbc2a06214 Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Thu, 15 Jan 2015 07:03:18 -0500 Subject: [PATCH 57/59] add join_pack method --- code/wolf/wolf.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/wolf/wolf.rb b/code/wolf/wolf.rb index cf1cc59..8524fbc 100644 --- a/code/wolf/wolf.rb +++ b/code/wolf/wolf.rb @@ -42,7 +42,8 @@ def dominant_to(wolf) end def join_pack - @wolves = [] unless @wolves - @wolves << wolf.name + @wolves = [] + @wolves << @name + @wolves end end From 9fbd9841e487f5c6e37ddfc882174c2dc00ea57b Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Thu, 15 Jan 2015 07:42:35 -0500 Subject: [PATCH 58/59] edit setup and test_more_than_one_wolf --- code/wolf/wolfpack_test.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/code/wolf/wolfpack_test.rb b/code/wolf/wolfpack_test.rb index bbf1d24..bf303f1 100644 --- a/code/wolf/wolfpack_test.rb +++ b/code/wolf/wolfpack_test.rb @@ -14,7 +14,11 @@ class TestWolfpack < MiniTest::Unit::TestCase def setup - @wolfpack = Wolfpack.new + wolfie = Wolf.new('wolfie', 12) + wolfram = Wolf.new('wolfram', 34) + @bob = Wolf.new('bob', 56) + @wolves = [wolfie, wolfram, @bob] + @wolfpack = Wolfpack.new(@wolves) end def test_wolfpack_exists @@ -22,7 +26,7 @@ def test_wolfpack_exists end def test_more_than_one_wolf - assert_equal true, @wolfpack.wolves + assert @wolfpack.more_than_one_wolf end end \ No newline at end of file From f7c51c25910b795fb52249dce83f2dfc6de9ad6e Mon Sep 17 00:00:00 2001 From: Angela Bier Date: Thu, 15 Jan 2015 07:43:09 -0500 Subject: [PATCH 59/59] edit initialize and more_than_one_wolf methods --- code/wolf/wolfpack.rb | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/code/wolf/wolfpack.rb b/code/wolf/wolfpack.rb index 1e76bbe..eb53bb8 100644 --- a/code/wolf/wolfpack.rb +++ b/code/wolf/wolfpack.rb @@ -7,26 +7,47 @@ # A pack of 30 wolves can eat a rhinoceros class Wolfpack - attr_accessor :wolves + attr_accessor :leader, :wolfpack,:name, :age - def initialize - @wolves = [] unless @wolves + def initialize(wolves) + @wolfpack = wolves end def is_leader - @wolves.sort_by(age) + @leader = @wolfpack.sort_by {|wolf| wolf.age }.last end - def can_hunt - if @wolves.length > 2 && < 5 - "The Wolfpack can hunt a gazelle! " - elsif @wolves.length > 5 && < 30 - "The Wolfpack can hunt a water buffalo" + def more_than_one_wolf + if @wolfpack.length > 1 + true + end + end + +=begin + def can_hunt_gazelle + if @wolfpack.length > 2 && < 5 + true + else + false + end + end + + def can_hunt_water_buffalo + if @wolfpack.length > 5 && < 30 + true + else + false + end + end + + def can_hunt_rhino + if @wolfpack.length > 30 + true else - @wolves.length > 30 - "The Wolfpack can hunt a rhinoceros" + false end end +=end end \ No newline at end of file