From 5e3a50ea4f66710e3f83ef85c145e75433a3fbe1 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Sun, 22 Jan 2017 10:52:14 +0800 Subject: [PATCH 01/42] finished 00_hello --- 00_hello/hello.rb | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 00_hello/hello.rb diff --git a/00_hello/hello.rb b/00_hello/hello.rb new file mode 100644 index 000000000..4967a31d0 --- /dev/null +++ b/00_hello/hello.rb @@ -0,0 +1,7 @@ +def hello + "Hello!" +end + +def greet(person) + "Hello, #{person}!" +end \ No newline at end of file From 9b308c9c5d838429093447e9ee266914d07d9345 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Sun, 22 Jan 2017 21:21:02 +0800 Subject: [PATCH 02/42] completed 01_temperature --- 01_temperature/temperature.rb | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 01_temperature/temperature.rb diff --git a/01_temperature/temperature.rb b/01_temperature/temperature.rb new file mode 100644 index 000000000..55a18e678 --- /dev/null +++ b/01_temperature/temperature.rb @@ -0,0 +1,7 @@ +def ftoc(f) + (f - 32) * 5.0 / 9 +end + +def ctof(c) + (c * 9.0 / 5) + 32 +end \ No newline at end of file From d333f6614936380b9abe4e0e80d70374e2a89aad Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 09:35:08 +0800 Subject: [PATCH 03/42] completed minimum requirements for 02_calculator --- 02_calculator/calculator.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 02_calculator/calculator.rb diff --git a/02_calculator/calculator.rb b/02_calculator/calculator.rb new file mode 100644 index 000000000..c993c90e2 --- /dev/null +++ b/02_calculator/calculator.rb @@ -0,0 +1,11 @@ +def add(a, b) + a + b +end + +def subtract(a, b) + a - b +end + +def sum(numbers) + numbers.inject(0) { |sum, number| sum + number } +end \ No newline at end of file From 7199b20e88d4c8b714195028de56d067a96a89bb Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 09:43:47 +0800 Subject: [PATCH 04/42] completed tests and code for #multiply --- 02_calculator/calculator.rb | 4 ++++ 02_calculator/calculator_spec.rb | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/02_calculator/calculator.rb b/02_calculator/calculator.rb index c993c90e2..79a2f9b50 100644 --- a/02_calculator/calculator.rb +++ b/02_calculator/calculator.rb @@ -8,4 +8,8 @@ def subtract(a, b) def sum(numbers) numbers.inject(0) { |sum, number| sum + number } +end + +def multiply(numbers) + numbers.inject(1) { |product, number| product * number } end \ No newline at end of file diff --git a/02_calculator/calculator_spec.rb b/02_calculator/calculator_spec.rb index fef7e9d00..b275da5fd 100644 --- a/02_calculator/calculator_spec.rb +++ b/02_calculator/calculator_spec.rb @@ -78,11 +78,15 @@ # write tests and code for the following: describe "#multiply" do + it "multiplies two numbers" do + expect(multiply([2, 5])).to eq(10) + expect(multiply([5, 10])).to eq(50) + end - it "multiplies two numbers" - - it "multiplies several numbers" - + it "multiplies several numbers" do + expect(multiply([1, 2, 3])).to eq(6) + expect(multiply([0, 5, 10])).to eq(0) + end end describe "#power" do From b7b324935ab74cfd8aff36141a411d281561e42b Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 09:46:02 +0800 Subject: [PATCH 05/42] completed tests and code for #power --- 02_calculator/calculator.rb | 4 ++++ 02_calculator/calculator_spec.rb | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/02_calculator/calculator.rb b/02_calculator/calculator.rb index 79a2f9b50..16a1430f0 100644 --- a/02_calculator/calculator.rb +++ b/02_calculator/calculator.rb @@ -12,4 +12,8 @@ def sum(numbers) def multiply(numbers) numbers.inject(1) { |product, number| product * number } +end + +def power(base, exponent) + base ** exponent end \ No newline at end of file diff --git a/02_calculator/calculator_spec.rb b/02_calculator/calculator_spec.rb index b275da5fd..a15118672 100644 --- a/02_calculator/calculator_spec.rb +++ b/02_calculator/calculator_spec.rb @@ -90,7 +90,11 @@ end describe "#power" do - it "raises one number to the power of another number" + it "raises one number to the power of another number" do + expect(power(2, 2)).to eq(4) + expect(power(5, 2)).to eq(25) + expect(power(10, 0)).to eq(1) + end end # http://en.wikipedia.org/wiki/Factorial From 49f5cc629d843e1f7e289021160a19bf54c2a4e9 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 09:51:20 +0800 Subject: [PATCH 06/42] completed tests and code for #factorial --- 02_calculator/calculator.rb | 10 ++++++++++ 02_calculator/calculator_spec.rb | 24 +++++++++++++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/02_calculator/calculator.rb b/02_calculator/calculator.rb index 16a1430f0..dcdac7c2b 100644 --- a/02_calculator/calculator.rb +++ b/02_calculator/calculator.rb @@ -16,4 +16,14 @@ def multiply(numbers) def power(base, exponent) base ** exponent +end + +def factorial(number) + raise "Invalid input" if number < 0 + + 1 if number == 0 || number == 1 + + result = 1 + number.downto(1) { |n| result *= n } + result end \ No newline at end of file diff --git a/02_calculator/calculator_spec.rb b/02_calculator/calculator_spec.rb index a15118672..ee254cab8 100644 --- a/02_calculator/calculator_spec.rb +++ b/02_calculator/calculator_spec.rb @@ -99,9 +99,23 @@ # http://en.wikipedia.org/wiki/Factorial describe "#factorial" do - it "computes the factorial of 0" - it "computes the factorial of 1" - it "computes the factorial of 2" - it "computes the factorial of 5" - it "computes the factorial of 10" + it "computes the factorial of 0" do + expect(factorial(0)).to eq(1) + end + + it "computes the factorial of 1" do + expect(factorial(1)).to eq(1) + end + + it "computes the factorial of 2" do + expect(factorial(2)).to eq(2) + end + + it "computes the factorial of 5" do + expect(factorial(5)).to eq(120) + end + + it "computes the factorial of 10" do + expect(factorial(10)).to eq(3628800) + end end From 3eff41ce18441b0a72ef2f2d379bc35a2eb205cb Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 09:53:41 +0800 Subject: [PATCH 07/42] completed echo method --- 03_simon_says/simon_says.rb | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 03_simon_says/simon_says.rb diff --git a/03_simon_says/simon_says.rb b/03_simon_says/simon_says.rb new file mode 100644 index 000000000..45d01cb92 --- /dev/null +++ b/03_simon_says/simon_says.rb @@ -0,0 +1,4 @@ +def echo(phrase) + phrase +end + From 39e5334e1363f255b6f3eeb8f6f4bd61ed86b627 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 10:21:49 +0800 Subject: [PATCH 08/42] completed shout method --- 03_simon_says/simon_says.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/03_simon_says/simon_says.rb b/03_simon_says/simon_says.rb index 45d01cb92..31b88831b 100644 --- a/03_simon_says/simon_says.rb +++ b/03_simon_says/simon_says.rb @@ -2,3 +2,6 @@ def echo(phrase) phrase end +def shout(phrase) + phrase.upcase +end \ No newline at end of file From bdcbc2f14f5e635d2da7f1b5ba2e4ff1dfbe5bd0 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 10:22:09 +0800 Subject: [PATCH 09/42] completed repeat method --- 03_simon_says/simon_says.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/03_simon_says/simon_says.rb b/03_simon_says/simon_says.rb index 31b88831b..9084d5ede 100644 --- a/03_simon_says/simon_says.rb +++ b/03_simon_says/simon_says.rb @@ -4,4 +4,9 @@ def echo(phrase) def shout(phrase) phrase.upcase -end \ No newline at end of file +end + +def repeat(phrase, num_times=2) + output = (" " + phrase) * num_times + output.strip +end From 5d56219f753f62efe820a28ff6f3ed43f3847780 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 10:24:10 +0800 Subject: [PATCH 10/42] completed start_of_word method --- 03_simon_says/simon_says.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/03_simon_says/simon_says.rb b/03_simon_says/simon_says.rb index 9084d5ede..3404388e7 100644 --- a/03_simon_says/simon_says.rb +++ b/03_simon_says/simon_says.rb @@ -10,3 +10,7 @@ def repeat(phrase, num_times=2) output = (" " + phrase) * num_times output.strip end + +def start_of_word(word, num_letters) + word[0..(num_letters - 1)] +end \ No newline at end of file From fff00c46cefd1218175d1668db77189142f1498f Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 10:26:53 +0800 Subject: [PATCH 11/42] completed first_word method --- 03_simon_says/simon_says.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/03_simon_says/simon_says.rb b/03_simon_says/simon_says.rb index 3404388e7..b47eb3b8b 100644 --- a/03_simon_says/simon_says.rb +++ b/03_simon_says/simon_says.rb @@ -13,4 +13,8 @@ def repeat(phrase, num_times=2) def start_of_word(word, num_letters) word[0..(num_letters - 1)] +end + +def first_word(sentence) + sentence.split[0] end \ No newline at end of file From ee042292146bd4ed90e83adf740943cab983029f Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 10:42:20 +0800 Subject: [PATCH 12/42] completed titleize method --- 03_simon_says/simon_says.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/03_simon_says/simon_says.rb b/03_simon_says/simon_says.rb index b47eb3b8b..139e25aa4 100644 --- a/03_simon_says/simon_says.rb +++ b/03_simon_says/simon_says.rb @@ -17,4 +17,15 @@ def start_of_word(word, num_letters) def first_word(sentence) sentence.split[0] +end + +def titleize(sentence) + excluded_words = %w(a an the for and nor but or yet so + at around by after along for from of + on to with without over) + + words = sentence.split(" ") + words.map { |word| word.capitalize! unless excluded_words.include?(word) } + words[0].capitalize! + words.join(" ") end \ No newline at end of file From 397b9758970a15731f0b436ec9a2c3cdb759f29c Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 13:34:07 +0800 Subject: [PATCH 13/42] completed code for all tests in pig_latin_spec.rb --- 04_pig_latin/pig_latin.rb | 59 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 04_pig_latin/pig_latin.rb diff --git a/04_pig_latin/pig_latin.rb b/04_pig_latin/pig_latin.rb new file mode 100644 index 000000000..c5f5cf32f --- /dev/null +++ b/04_pig_latin/pig_latin.rb @@ -0,0 +1,59 @@ +def translate(sentence) + words = sentence.split + translated_words = words.map { |word| translate_word(word) } + translated_words.join(" ") +end + +def translate_word(word) + vowels = %w(a e i o u) + ay_sound = "ay" + + # word starts with a vowel + if vowels.include?(word[0]) + return word + ay_sound + end + + # word contains "qu" phoneme + if has_qu_phoneme?(word) + # check if "qu" is preceded by a consonant + qu_index = word.index("qu") + + # word starts with "qu" + if qu_index == 0 + return word[2..-1] + "qu" + ay_sound + else + # "qu" is preceded by another character, check if it's a consonant + if !vowels.include?(word[qu_index - 1]) + return word[qu_index + 2..-1] + word[qu_index - 1..qu_index + 1] + "ay" + end + end + end + + # word starts with a variable number of consonants (up to 3) + case num_starting_consonants(word) + when 1 + return word[1..-1] + word[0] + ay_sound + when 2 + return word[2..-1] + word[0..1] + ay_sound + when 3 + return word[3..-1] + word[0..2] + ay_sound + end +end + +# check how many consonants the word starts with +def num_starting_consonants(word) + vowels = %w(a e i o u) + count = 0 + + word.downcase.chars.each do |char| + vowels.include?(char) ? break : count += 1 + end + + count +end + +# check if word has the "qu" phoneme +def has_qu_phoneme?(word) + word[0..2].include?("qu") +end + From 364350ed1b7adc490d597373709d4dd306ee99d7 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 14:11:37 +0800 Subject: [PATCH 14/42] completed extra credit problem to capitalize translated words --- 04_pig_latin/pig_latin.rb | 21 ++++++++++++++------- 04_pig_latin/pig_latin_spec.rb | 8 ++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/04_pig_latin/pig_latin.rb b/04_pig_latin/pig_latin.rb index c5f5cf32f..ec8c15e16 100644 --- a/04_pig_latin/pig_latin.rb +++ b/04_pig_latin/pig_latin.rb @@ -1,7 +1,8 @@ def translate(sentence) words = sentence.split - translated_words = words.map { |word| translate_word(word) } - translated_words.join(" ") + words = words.map { |word| translate_word(word) } + words = words.map { |word| correct_capitalization(word) } + words.join(" ") end def translate_word(word) @@ -15,16 +16,15 @@ def translate_word(word) # word contains "qu" phoneme if has_qu_phoneme?(word) - # check if "qu" is preceded by a consonant - qu_index = word.index("qu") + qu_index = word.index(/[Qq]u/) # word starts with "qu" if qu_index == 0 - return word[2..-1] + "qu" + ay_sound + return word[2..-1] + word[qu_index..qu_index + 1] + ay_sound else # "qu" is preceded by another character, check if it's a consonant if !vowels.include?(word[qu_index - 1]) - return word[qu_index + 2..-1] + word[qu_index - 1..qu_index + 1] + "ay" + return word[qu_index + 2..-1] + word[qu_index - 1..qu_index + 1] + ay_sound end end end @@ -54,6 +54,13 @@ def num_starting_consonants(word) # check if word has the "qu" phoneme def has_qu_phoneme?(word) - word[0..2].include?("qu") + word.downcase[0..2].include?("qu") end +def correct_capitalization(word) + if word.downcase != word + return word.downcase.capitalize + else + return word + end +end diff --git a/04_pig_latin/pig_latin_spec.rb b/04_pig_latin/pig_latin_spec.rb index cc659edfd..a204fdc34 100644 --- a/04_pig_latin/pig_latin_spec.rb +++ b/04_pig_latin/pig_latin_spec.rb @@ -68,5 +68,13 @@ # Test-driving bonus: # * write a test asserting that capitalized words are still capitalized (but with a different initial capital letter, of course) # * retain the punctuation from the original phrase + it "ensures that words that were originally capitalized are still capitalized (with a different initial capital letter, of course)" do + s = translate("The Quick Brown Fox") + expect(s).to eq("Ethay Ickquay Ownbray Oxfay") + end + xit "retains the punctuation from the original phrase" do + s = translate("The Good, The Bad, and The Ugly") + expect(s).to eq("Ethay Oodgay, Ethay Adbay, anday Ethay Uglyay") + end end From 10b80ccae09f5ceb15925ec8b5ba0f7072212e40 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 14:30:25 +0800 Subject: [PATCH 15/42] completed reverser method --- 05_silly_blocks/silly_blocks.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 05_silly_blocks/silly_blocks.rb diff --git a/05_silly_blocks/silly_blocks.rb b/05_silly_blocks/silly_blocks.rb new file mode 100644 index 000000000..a8feaf66e --- /dev/null +++ b/05_silly_blocks/silly_blocks.rb @@ -0,0 +1,10 @@ +def reverser + block = yield + if block.split(" ").length > 1 + strings = block.split(" ") + strings.map { |string| string.reverse! } + return strings.join(" ") + else + return block.reverse + end +end \ No newline at end of file From c5d5e3e701457f2a50cb17fa5e53f554a7511457 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 14:33:45 +0800 Subject: [PATCH 16/42] modified reverser method to only run if block is provided to it --- 05_silly_blocks/silly_blocks.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/05_silly_blocks/silly_blocks.rb b/05_silly_blocks/silly_blocks.rb index a8feaf66e..6e23e7459 100644 --- a/05_silly_blocks/silly_blocks.rb +++ b/05_silly_blocks/silly_blocks.rb @@ -1,10 +1,12 @@ def reverser - block = yield - if block.split(" ").length > 1 - strings = block.split(" ") - strings.map { |string| string.reverse! } - return strings.join(" ") - else - return block.reverse + if block_given? + block = yield + if block.split(" ").length > 1 + strings = block.split(" ") + strings.map { |string| string.reverse! } + return strings.join(" ") + else + return block.reverse + end end end \ No newline at end of file From 62764b0ee6dc0ca5ca2ed0c390d5a4f02c49050e Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 14:44:04 +0800 Subject: [PATCH 17/42] completed adder method --- 05_silly_blocks/silly_blocks.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/05_silly_blocks/silly_blocks.rb b/05_silly_blocks/silly_blocks.rb index 6e23e7459..bd46b7f59 100644 --- a/05_silly_blocks/silly_blocks.rb +++ b/05_silly_blocks/silly_blocks.rb @@ -9,4 +9,16 @@ def reverser return block.reverse end end +end + +def adder(input=0) + if block_given? + block = yield + + if input == 0 + return block + 1 + else + return input + 5 + end + end end \ No newline at end of file From 3dd15dc934cd86dafb25ab2f005ec27037d4064c Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 14:45:44 +0800 Subject: [PATCH 18/42] completed repeater method --- 05_silly_blocks/silly_blocks.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/05_silly_blocks/silly_blocks.rb b/05_silly_blocks/silly_blocks.rb index bd46b7f59..5a73a3626 100644 --- a/05_silly_blocks/silly_blocks.rb +++ b/05_silly_blocks/silly_blocks.rb @@ -21,4 +21,14 @@ def adder(input=0) return input + 5 end end +end + +def repeater(num_times=1) + if block_given? + if num_times == 1 + yield + else + num_times.times { yield } + end + end end \ No newline at end of file From fecdce8c61537b96f6325993cb07719283e82997 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 20:57:03 +0800 Subject: [PATCH 19/42] completed measure method --- 06_performance_monitor/performance_monitor.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 06_performance_monitor/performance_monitor.rb diff --git a/06_performance_monitor/performance_monitor.rb b/06_performance_monitor/performance_monitor.rb new file mode 100644 index 000000000..a24c659ab --- /dev/null +++ b/06_performance_monitor/performance_monitor.rb @@ -0,0 +1,12 @@ +def measure(passes = 1) + if block_given? + start_time = Time.now + passes.times do |pass| + yield + end + return (Time.now - start_time) / passes.to_f + end + + start_time = Time.now + Time.now - start_time +end \ No newline at end of file From cd445a68bcb4fbe1bc7e875d7e5943eb46d85369 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 20:58:03 +0800 Subject: [PATCH 20/42] refactored measure method --- 06_performance_monitor/performance_monitor.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/06_performance_monitor/performance_monitor.rb b/06_performance_monitor/performance_monitor.rb index a24c659ab..08d290c46 100644 --- a/06_performance_monitor/performance_monitor.rb +++ b/06_performance_monitor/performance_monitor.rb @@ -1,9 +1,7 @@ def measure(passes = 1) if block_given? start_time = Time.now - passes.times do |pass| - yield - end + passes.times { |pass| yield } return (Time.now - start_time) / passes.to_f end From 733048bab6885da379331d6e8cbf7e7784e354e8 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 21:03:03 +0800 Subject: [PATCH 21/42] completed Friend class and greeting method --- 07_hello_friend/friend.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 07_hello_friend/friend.rb diff --git a/07_hello_friend/friend.rb b/07_hello_friend/friend.rb new file mode 100644 index 000000000..a020530b2 --- /dev/null +++ b/07_hello_friend/friend.rb @@ -0,0 +1,5 @@ +class Friend + def greeting(person = nil) + person ? "Hello, #{person}!" : "Hello!" + end +end \ No newline at end of file From 977a46228c006057e890e72557fdcb2b95bd901c Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 21:12:54 +0800 Subject: [PATCH 22/42] completed Book class and title attr_accessor --- 08_book_titles/book.rb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 08_book_titles/book.rb diff --git a/08_book_titles/book.rb b/08_book_titles/book.rb new file mode 100644 index 000000000..126bdc7ed --- /dev/null +++ b/08_book_titles/book.rb @@ -0,0 +1,20 @@ +class Book + attr_accessor :title + + def title + words_always_in_lowercase = %w(the a an and in the of) + + words_in_title = @title.split + words_in_title.each do |word| + if words_always_in_lowercase.include?(word) + next + else + word.capitalize! + end + end + + words_in_title[0].capitalize! + + @title = words_in_title.join(" ") + end +end \ No newline at end of file From b7ff10a4d6f1755f44279cec3aac56b82163ce4d Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 21:17:11 +0800 Subject: [PATCH 23/42] initial class and method definitions --- 09_timer/timer.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 09_timer/timer.rb diff --git a/09_timer/timer.rb b/09_timer/timer.rb new file mode 100644 index 000000000..eb2e86aed --- /dev/null +++ b/09_timer/timer.rb @@ -0,0 +1,10 @@ +class Timer + attr_accessor :seconds + + def initialize + @seconds = 0 + end + + def time_string + end +end \ No newline at end of file From 1ddaf837190f11520a286d119e50304a004cf667 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 21:17:43 +0800 Subject: [PATCH 24/42] uncommenting specs for helper method --- 09_timer/timer_spec.rb | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/09_timer/timer_spec.rb b/09_timer/timer_spec.rb index 40b33f23f..0ae1dd31f 100644 --- a/09_timer/timer_spec.rb +++ b/09_timer/timer_spec.rb @@ -45,16 +45,16 @@ # Uncomment these specs if you want to test-drive that # method, then call that method from inside of time_string. # - # describe 'padded' do - # it 'pads zero' do - # expect(@timer.padded(0)).to eq('00') - # end - # it 'pads one' do - # expect(@timer.padded(1)).to eq('01') - # end - # it "doesn't pad a two-digit number" do - # expect(@timer.padded(12)).to eq('12') - # end - # end + describe 'padded' do + it 'pads zero' do + expect(@timer.padded(0)).to eq('00') + end + it 'pads one' do + expect(@timer.padded(1)).to eq('01') + end + it "doesn't pad a two-digit number" do + expect(@timer.padded(12)).to eq('12') + end + end end From 5bc9124357830df26c4742e2f4d2846254e66282 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 21:25:35 +0800 Subject: [PATCH 25/42] completed time_string and padded methods --- 09_timer/timer.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/09_timer/timer.rb b/09_timer/timer.rb index eb2e86aed..5013914e9 100644 --- a/09_timer/timer.rb +++ b/09_timer/timer.rb @@ -6,5 +6,18 @@ def initialize end def time_string + hours = @seconds / 60 / 60 + minutes = @seconds / 60 % 60 + seconds = @seconds % 60 + + "#{padded(hours)}:#{padded(minutes)}:#{padded(seconds)}" + end + + def padded(number) + if number.to_s.length == 2 + number.to_s + else + "0#{number}" + end end end \ No newline at end of file From aad72b0652d0f799ffdee95697a7ea389a1bd892 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 21:43:44 +0800 Subject: [PATCH 26/42] completed Temperature class --- 10_temperature_object/temperature.rb | 38 ++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 10_temperature_object/temperature.rb diff --git a/10_temperature_object/temperature.rb b/10_temperature_object/temperature.rb new file mode 100644 index 000000000..1deefd4b4 --- /dev/null +++ b/10_temperature_object/temperature.rb @@ -0,0 +1,38 @@ +class Temperature + @fahrenheit = nil + @celsius = nil + + attr_accessor :celsius, :fahrenheit + + def self.from_celsius(degrees) + temperature = Temperature.new(c: degrees) + end + + def self.from_fahrenheit(degrees) + temperature = Temperature.new(f: degrees) + end + + def initialize(options = {}) + if options.has_key?(:f) + @fahrenheit = options[:f] + elsif options.has_key?(:c) + @celsius = options[:c] + end + end + + def in_fahrenheit + unless @fahrenheit.nil? + @fahrenheit + else + (@celsius * 9.0 / 5) + 32 + end + end + + def in_celsius + unless @celsius.nil? + @celsius + else + (@fahrenheit - 32) * 5.0 / 9 + end + end +end \ No newline at end of file From 54d883031daedfabbfdd4741b3b0e0cc617ea9b6 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Mon, 23 Jan 2017 21:48:51 +0800 Subject: [PATCH 27/42] completed Celsius and Fahrenheit subclasses --- 10_temperature_object/temperature.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/10_temperature_object/temperature.rb b/10_temperature_object/temperature.rb index 1deefd4b4..68532f31c 100644 --- a/10_temperature_object/temperature.rb +++ b/10_temperature_object/temperature.rb @@ -35,4 +35,20 @@ def in_celsius (@fahrenheit - 32) * 5.0 / 9 end end +end + +class Celsius < Temperature + attr_accessor :celsius + + def initialize(degrees) + @celsius = degrees + end +end + +class Fahrenheit < Temperature + attr_accessor :fahrenheit + + def initialize(degrees) + @fahrenheit = degrees + end end \ No newline at end of file From d01b00e2f446f816bfbc4dc7b723d3019dd47df7 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Tue, 24 Jan 2017 09:59:16 +0800 Subject: [PATCH 28/42] completed Dictionary class and required methods --- 11_dictionary/dictionary.rb | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 11_dictionary/dictionary.rb diff --git a/11_dictionary/dictionary.rb b/11_dictionary/dictionary.rb new file mode 100644 index 000000000..7f85e04b1 --- /dev/null +++ b/11_dictionary/dictionary.rb @@ -0,0 +1,47 @@ +class Dictionary + attr_accessor :entries, :keywords + + def initialize + @entries = {} + @keywords = [] + end + + def add(items = {}) + if items.is_a?(String) + @keywords.push(items) + @entries[items] = nil + else + items.each do |key, value| + @entries[key] = value + @keywords.push(key) + end + end + + @keywords.sort! + end + + def include?(keyword) + @keywords.include?(keyword) + end + + def find(word) + output = {} + @keywords.each do |keyword| + + if keyword.start_with?(word) + output[keyword] = @entries[keyword] + end + end + + output + end + + def printable + output = "" + @keywords.each do |keyword| + output += "[#{keyword}] \"#{@entries[keyword]}\"\n" + end + + output.chomp + end +end From 0b6ccab30c215f0996ec02e8e0657aea3c68f945 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Tue, 24 Jan 2017 10:01:08 +0800 Subject: [PATCH 29/42] refactored find and printable methods --- 11_dictionary/dictionary.rb | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/11_dictionary/dictionary.rb b/11_dictionary/dictionary.rb index 7f85e04b1..bd95053b9 100644 --- a/11_dictionary/dictionary.rb +++ b/11_dictionary/dictionary.rb @@ -26,21 +26,14 @@ def include?(keyword) def find(word) output = {} - @keywords.each do |keyword| - - if keyword.start_with?(word) - output[keyword] = @entries[keyword] - end - end + @keywords.each { |keyword| output[keyword] = @entries[keyword] if keyword.start_with?(word) } output end def printable output = "" - @keywords.each do |keyword| - output += "[#{keyword}] \"#{@entries[keyword]}\"\n" - end + @keywords.each { |keyword| output += "[#{keyword}] \"#{@entries[keyword]}\"\n" } output.chomp end From 4a133f6189054905babd7a6a4b03fb7f02258d86 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Wed, 25 Jan 2017 10:59:17 +0800 Subject: [PATCH 30/42] first working implementation of value method --- 12_rpn_calculator/rpn_calculator.rb | 74 +++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 12_rpn_calculator/rpn_calculator.rb diff --git a/12_rpn_calculator/rpn_calculator.rb b/12_rpn_calculator/rpn_calculator.rb new file mode 100644 index 000000000..a8f7c8da4 --- /dev/null +++ b/12_rpn_calculator/rpn_calculator.rb @@ -0,0 +1,74 @@ +class RPNCalculator + attr_accessor :expression, :stack + + def initialize + @expression = "" + @stack = [] + end + + def push(operand) + @expression << operand.to_s + " " + end + + def plus + @expression << "+ " + end + + def minus + @expression << "- " + end + + def divide + @expression << "/ " + end + + def times + @expression << "* " + end + + def value + tokens = @expression.split + + until tokens.empty? + token = tokens.shift + p token + + unless operator?(token) + @stack.push(token) + else + second_operand = @stack.pop.to_f + first_operand = @stack.pop.to_f + result = nil + + case token + when "+" + result = first_operand + second_operand + when "-" + result = first_operand - second_operand + when "/" + result = first_operand / second_operand + when "*" + result = first_operand * second_operand + end + + @stack.push(result) + end + end + + return @stack.last + end + + def operator?(value) + operators = %w(+ - / *) + operators.include?(value) + end +end + +# calc = RPNCalculator.new +# calc.push(2) +# calc.push(3) +# calc.push(4) +# calc.divide +# calc.times +# p calc.expression +# p calc.value \ No newline at end of file From 43ac8114deb322bb1bb81cfff24a4fe1f86cf62c Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Wed, 25 Jan 2017 11:37:45 +0800 Subject: [PATCH 31/42] completed tokens method --- 12_rpn_calculator/rpn_calculator.rb | 41 +++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/12_rpn_calculator/rpn_calculator.rb b/12_rpn_calculator/rpn_calculator.rb index a8f7c8da4..8614e79fb 100644 --- a/12_rpn_calculator/rpn_calculator.rb +++ b/12_rpn_calculator/rpn_calculator.rb @@ -11,19 +11,36 @@ def push(operand) end def plus - @expression << "+ " + # @expression.empty? ? raise "calculator is empty" : @expression << "+ " + if @expression.empty? + raise "calculator is empty" + else + @expression << "+ " + end end def minus - @expression << "- " + if @expression.empty? + raise "calculator is empty" + else + @expression << "- " + end end def divide - @expression << "/ " + if @expression.empty? + raise "calculator is empty" + else + @expression << "/ " + end end def times - @expression << "* " + if @expression.empty? + raise "calculator is empty" + else + @expression << "* " + end end def value @@ -31,7 +48,6 @@ def value until tokens.empty? token = tokens.shift - p token unless operator?(token) @stack.push(token) @@ -58,6 +74,21 @@ def value return @stack.last end + def tokens(string) + tokens = string.split + result = [] + + tokens.each do |token| + if operator?(token) + result << token.to_sym + else + result << token.to_f + end + end + + result + end + def operator?(value) operators = %w(+ - / *) operators.include?(value) From ddbe4257c77fddb5568c2c56d6823a5e6b48571f Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Wed, 25 Jan 2017 12:24:34 +0800 Subject: [PATCH 32/42] completed evaluate method --- 12_rpn_calculator/rpn_calculator.rb | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/12_rpn_calculator/rpn_calculator.rb b/12_rpn_calculator/rpn_calculator.rb index 8614e79fb..42d100cda 100644 --- a/12_rpn_calculator/rpn_calculator.rb +++ b/12_rpn_calculator/rpn_calculator.rb @@ -11,7 +11,6 @@ def push(operand) end def plus - # @expression.empty? ? raise "calculator is empty" : @expression << "+ " if @expression.empty? raise "calculator is empty" else @@ -89,17 +88,14 @@ def tokens(string) result end + def evaluate(string) + calc = RPNCalculator.new + calc.expression = string + calc.value + end + def operator?(value) operators = %w(+ - / *) operators.include?(value) end end - -# calc = RPNCalculator.new -# calc.push(2) -# calc.push(3) -# calc.push(4) -# calc.divide -# calc.times -# p calc.expression -# p calc.value \ No newline at end of file From d0477d47825a83cb3a8ff6f1257940c781b8b95c Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Wed, 25 Jan 2017 12:40:32 +0800 Subject: [PATCH 33/42] completed hello method --- 13_xml_document/xml_document.rb | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 13_xml_document/xml_document.rb diff --git a/13_xml_document/xml_document.rb b/13_xml_document/xml_document.rb new file mode 100644 index 000000000..568a1562c --- /dev/null +++ b/13_xml_document/xml_document.rb @@ -0,0 +1,21 @@ +class XmlDocument + def initialize + end + + def hello(options = {}) + if options.empty? + return "" + end + + start_tag = " Date: Wed, 25 Jan 2017 12:45:45 +0800 Subject: [PATCH 34/42] finished send method --- 13_xml_document/xml_document.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/13_xml_document/xml_document.rb b/13_xml_document/xml_document.rb index 568a1562c..3ee833606 100644 --- a/13_xml_document/xml_document.rb +++ b/13_xml_document/xml_document.rb @@ -18,4 +18,8 @@ def hello(options = {}) "#{start_tag} #{attributes.rstrip!}#{end_tag}" end + + def send(tag_name) + "<#{tag_name}/>" + end end \ No newline at end of file From c519d98c979a34eb1b1c9f0f032cacc7ec057be1 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Wed, 25 Jan 2017 12:50:22 +0800 Subject: [PATCH 35/42] modified hello method --- 13_xml_document/xml_document.rb | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/13_xml_document/xml_document.rb b/13_xml_document/xml_document.rb index 3ee833606..7bf46db54 100644 --- a/13_xml_document/xml_document.rb +++ b/13_xml_document/xml_document.rb @@ -3,20 +3,26 @@ def initialize end def hello(options = {}) - if options.empty? - return "" - end + # do we need to consider the case where + # both a block and options hash are given? - start_tag = "#{text}" + elsif options.empty? + return "" + else + start_tag = " Date: Wed, 25 Jan 2017 12:51:17 +0800 Subject: [PATCH 36/42] added goodbye method --- 13_xml_document/xml_document.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/13_xml_document/xml_document.rb b/13_xml_document/xml_document.rb index 7bf46db54..d77126a54 100644 --- a/13_xml_document/xml_document.rb +++ b/13_xml_document/xml_document.rb @@ -28,4 +28,8 @@ def hello(options = {}) def send(tag_name) "<#{tag_name}/>" end + + def goodbye + "" + end end \ No newline at end of file From 0e145a620e34a4bbb42ebede66cc79c602c4955a Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Wed, 25 Jan 2017 12:54:30 +0800 Subject: [PATCH 37/42] replaced goodbye method with method_missing method --- 13_xml_document/xml_document.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/13_xml_document/xml_document.rb b/13_xml_document/xml_document.rb index d77126a54..ea79f12a4 100644 --- a/13_xml_document/xml_document.rb +++ b/13_xml_document/xml_document.rb @@ -29,7 +29,7 @@ def send(tag_name) "<#{tag_name}/>" end - def goodbye - "" + def method_missing(symbol) + self.send(symbol) end -end \ No newline at end of file +end From 9916d648942140a5452b665b5e685cbc00796809 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Wed, 25 Jan 2017 14:39:53 +0800 Subject: [PATCH 38/42] rewrote send method, removed hello method since it's no longer required --- 13_xml_document/xml_document.rb | 54 +++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/13_xml_document/xml_document.rb b/13_xml_document/xml_document.rb index ea79f12a4..2a3caefad 100644 --- a/13_xml_document/xml_document.rb +++ b/13_xml_document/xml_document.rb @@ -2,34 +2,44 @@ class XmlDocument def initialize end - def hello(options = {}) - # do we need to consider the case where - # both a block and options hash are given? - - if block_given? - text = yield - return "#{text}" - elsif options.empty? - return "" - else - start_tag = "" end - end - def send(tag_name) - "<#{tag_name}/>" + # block provided, with no attributes + if !block_content.empty? && attributes.empty? + return "<#{tag_name}>#{block_content}" + end + + # no block provided, but attributes provided + if block_content.empty? && !attributes.empty? + return "<#{tag_name} #{attributes}/>" + end + + # both block and attributes provided + if !block_content.empty? && !attributes.empty? + "<#{tag_name} #{attributes}>#{block_content}" + end end - def method_missing(symbol) - self.send(symbol) + def method_missing(symbol, options = {}, &block) + send(symbol, options, &block) end end From aebcd8a9e09f9e22dba963459d089b39cc10ad88 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Thu, 26 Jan 2017 09:19:37 +0800 Subject: [PATCH 39/42] first attempt at methods to indent output --- 13_xml_document/xml_document.rb | 54 +++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/13_xml_document/xml_document.rb b/13_xml_document/xml_document.rb index 2a3caefad..95c84b964 100644 --- a/13_xml_document/xml_document.rb +++ b/13_xml_document/xml_document.rb @@ -1,5 +1,9 @@ class XmlDocument - def initialize + attr_accessor :content + + def initialize(to_indent = false) + @to_indent = to_indent + @content = "" end def send(tag_name, options = {}, &block) @@ -35,11 +39,55 @@ def send(tag_name, options = {}, &block) # both block and attributes provided if !block_content.empty? && !attributes.empty? - "<#{tag_name} #{attributes}>#{block_content}" + return "<#{tag_name} #{attributes}>#{block_content}" end end def method_missing(symbol, options = {}, &block) - send(symbol, options, &block) + @content = send(symbol, options, &block) + end + + def indent_content(content) + indented_content = "" + indentation_hash = build_indentation_hash(content) + elements = content.gsub(">", ">,").split(",") + + # go through each element, indent it accordingly based on its + # assigned indentation level, then add it to the output + elements.each do |element| + indentation_level = indentation_hash[element.gsub(/[<>\/]/, "")] + indented_element = (" " * indentation_level) + element + "\n" + p indented_element + indented_content += indented_element + p indented_content + end + + indented_content + end + + def build_indentation_hash(content) + indentation_hash = {} + indentation_level = 0 + elements = content.gsub(">", ">,").split(",") + + # go through each element, and build a hash with each element + # as the key, and the level of indentation as the value + elements.each do |element| + element.gsub!(/[<>\/]/, "") + + if indentation_hash.has_key?(element) + next + else + indentation_hash[element] = indentation_level + indentation_level += 1 + end + end + + indentation_hash end end + + +test_string = "" +xml = XmlDocument.new(true) +puts xml.indent_content(test_string) From 6debb8eeaefb3dec3620d13af69fc3cf038b4ffd Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Thu, 26 Jan 2017 14:21:28 +0800 Subject: [PATCH 40/42] completed exercise --- 14_array_extensions/array_extensions.rb | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 14_array_extensions/array_extensions.rb diff --git a/14_array_extensions/array_extensions.rb b/14_array_extensions/array_extensions.rb new file mode 100644 index 000000000..b603fb9d6 --- /dev/null +++ b/14_array_extensions/array_extensions.rb @@ -0,0 +1,23 @@ +class Array + def sum + return 0 if self.size == 0 + + total = 0 + self.each { |element| total += element } + + total + end + + def square + return self if self.size == 0 + + squares = [] + self.each { |element| squares.push(element ** 2) } + + squares + end + + def square! + self.map! { |element| element ** 2} + end +end \ No newline at end of file From 976edc188b50927f7d515c61542752018369ff1e Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Thu, 26 Jan 2017 14:35:04 +0800 Subject: [PATCH 41/42] removed incorrect attempt at indenting output --- 13_xml_document/xml_document.rb | 48 +++------------------------------ 1 file changed, 4 insertions(+), 44 deletions(-) diff --git a/13_xml_document/xml_document.rb b/13_xml_document/xml_document.rb index 95c84b964..db22274a8 100644 --- a/13_xml_document/xml_document.rb +++ b/13_xml_document/xml_document.rb @@ -11,7 +11,10 @@ def send(tag_name, options = {}, &block) attributes = "" # handle block if a block is provided - block_content = yield if block_given? + # block_content = yield if block_given? + if block_given? + block_content = yield + end # build attributes string unless options.empty? @@ -47,47 +50,4 @@ def method_missing(symbol, options = {}, &block) @content = send(symbol, options, &block) end - def indent_content(content) - indented_content = "" - indentation_hash = build_indentation_hash(content) - elements = content.gsub(">", ">,").split(",") - - # go through each element, indent it accordingly based on its - # assigned indentation level, then add it to the output - elements.each do |element| - indentation_level = indentation_hash[element.gsub(/[<>\/]/, "")] - indented_element = (" " * indentation_level) + element + "\n" - p indented_element - indented_content += indented_element - p indented_content - end - - indented_content - end - - def build_indentation_hash(content) - indentation_hash = {} - indentation_level = 0 - elements = content.gsub(">", ">,").split(",") - - # go through each element, and build a hash with each element - # as the key, and the level of indentation as the value - elements.each do |element| - element.gsub!(/[<>\/]/, "") - - if indentation_hash.has_key?(element) - next - else - indentation_hash[element] = indentation_level - indentation_level += 1 - end - end - - indentation_hash - end end - - -test_string = "" -xml = XmlDocument.new(true) -puts xml.indent_content(test_string) From d16f514c9f68ec292a0f1dda8a3b0fb99494bfb6 Mon Sep 17 00:00:00 2001 From: Roy Chen Date: Thu, 26 Jan 2017 18:00:23 +0800 Subject: [PATCH 42/42] first attempt at solution with naive algorithm --- 15_in_words/in_words.rb | 61 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 15_in_words/in_words.rb diff --git a/15_in_words/in_words.rb b/15_in_words/in_words.rb new file mode 100644 index 000000000..86fb87bdc --- /dev/null +++ b/15_in_words/in_words.rb @@ -0,0 +1,61 @@ +class Fixnum + def in_words + number_to_word = { + 0 => "zero", + 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", + 1_000_000 => "million" + } + + # determine length of number + length = self.to_s.length + + # number within 0 to 20 + # or a multiple of 10 within 20 to 90 + if (0..20).include?(self) || (length == 2 && self % 10 == 0) + return number_to_word[self] + end + + # 2-digit number that does not fit the above case + if length == 2 + tens = self / 10 * 10 + ones = self % 10 + return "#{number_to_word[tens]} #{number_to_word[ones]}" + end + + # 3-digit number and a multiple of 100 + if (length == 3 && self % 100 == 0) + hundreds = self / 100 + return "#{number_to_word[hundreds]} hundred" + end + + + end +end