From 929a20d066925153f35cb377217682f7c871433b Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Mon, 24 Oct 2016 15:39:33 -0400 Subject: [PATCH 01/15] added name to README.md and completed 00_hello --- 00_hello/.rspec | 2 + 00_hello/hello.rb | 7 +++ 00_hello/spec/spec_helper.rb | 89 ++++++++++++++++++++++++++++++++++++ README.md | 2 + 4 files changed, 100 insertions(+) create mode 100644 00_hello/.rspec create mode 100644 00_hello/hello.rb create mode 100644 00_hello/spec/spec_helper.rb diff --git a/00_hello/.rspec b/00_hello/.rspec new file mode 100644 index 000000000..83e16f804 --- /dev/null +++ b/00_hello/.rspec @@ -0,0 +1,2 @@ +--color +--require spec_helper diff --git a/00_hello/hello.rb b/00_hello/hello.rb new file mode 100644 index 000000000..9374e7b9c --- /dev/null +++ b/00_hello/hello.rb @@ -0,0 +1,7 @@ +def hello + "Hello!" +end + +def greet(name) + "Hello, " + name + "!" +end \ No newline at end of file diff --git a/00_hello/spec/spec_helper.rb b/00_hello/spec/spec_helper.rb new file mode 100644 index 000000000..607474b24 --- /dev/null +++ b/00_hello/spec/spec_helper.rb @@ -0,0 +1,89 @@ +# This file was generated by the `rspec --init` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause this +# file to always be loaded, without a need to explicitly require it in any files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need it. +# +# The `.rspec` file also contains a few flags that are not defaults but that +# users commonly want. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # These two settings work together to allow you to limit a spec run + # to individual examples or groups you care about by tagging them with + # `:focus` metadata. When nothing is tagged with `:focus`, all examples + # get run. + config.filter_run :focus + config.run_all_when_everything_filtered = true + + # Limits the available syntax to the non-monkey patched syntax that is recommended. + # For more details, see: + # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax + # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching + config.disable_monkey_patching! + + # This setting enables warnings. It's recommended, but in some cases may + # be too noisy due to issues in dependencies. + config.warnings = true + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = 'doc' + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end diff --git a/README.md b/README.md index 706b785e9..c4e460156 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +PRAMOD JACOB + Test First Ruby -- RSpec 3 Edition ========== From 37418b4a47ce3855ecfa1e7e73e21ad2f0931621 Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Mon, 24 Oct 2016 16:03:44 -0400 Subject: [PATCH 02/15] completed 01_temperature --- 01_temperature/temperature.rb | 9 +++++++++ 1 file changed, 9 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..744f75db8 --- /dev/null +++ b/01_temperature/temperature.rb @@ -0,0 +1,9 @@ +# fahrenheit to celsius +def ftoc(f) + 5.0/9.0 * (f - 32) +end + +# celsius to fahrenheit +def ctof(c) + 9.0/5.0 * c + 32 +end From 064825890bce697bb7caae01ef9c4c4fa0d9648f Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Mon, 24 Oct 2016 16:46:22 -0400 Subject: [PATCH 03/15] completed 02_calculator --- 02_calculator/calculator.rb | 38 +++++++++++++++++ 02_calculator/calculator_spec.rb | 73 ++++++++++++++++++++++++++------ 2 files changed, 98 insertions(+), 13 deletions(-) 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..c6186a8a4 --- /dev/null +++ b/02_calculator/calculator.rb @@ -0,0 +1,38 @@ +# add +def add(a,b) + a + b +end + +# subtact +def subtract(a,b) + a - b +end + +# sum +def sum(arr) + return 0 if arr.length == 0 + return arr[0] if arr.length == 1 + arr.reduce { |prev, curr| prev + curr } +end + +# multiply +def mult(*args) + return false if args.length < 2 + args.reduce { |prev, curr| prev * curr } +end + +# power +def pow(a,b) + return 1 if b == 0 + result = a + (b.abs-1).times do + result *= a + end + b > 0 ? result : 1.0/result +end + +# factorial +def fac(num) + return 1 if num < 2 + num * fac(num-1) +end \ No newline at end of file diff --git a/02_calculator/calculator_spec.rb b/02_calculator/calculator_spec.rb index fef7e9d00..3e5b69545 100644 --- a/02_calculator/calculator_spec.rb +++ b/02_calculator/calculator_spec.rb @@ -77,23 +77,70 @@ # once the above tests pass, # write tests and code for the following: -describe "#multiply" do +# describe "#multiply" do +# it "multiplies two numbers" +# it "multiplies several numbers" +# end - it "multiplies two numbers" +describe "multiply" do + it "does not multiply 0 numbers" do + expect(mult()).to eq(false) + end + + it "does not multiply 1 number" do + expect(mult(2)).to eq(false) + end + + it "multiplies 2 and 3" do + expect(mult(2,3)).to eq(6) + end - it "multiplies several numbers" - + it "multiplies 8, 12, 16, 2, and 11" do + expect(mult(8,12,16,2,11)).to eq(33792) + end end -describe "#power" do - it "raises one number to the power of another number" +# describe "#power" do +# it "raises one number to the power of another number" +# end + +describe "power" do + it "raises one number to the power of a positive number" do + expect(pow(3,2)).to eq(9) + end + + it "raises one number to the power of a negative number" do + expect(pow(2,-4)).to eq(0.0625) + end + + it "raises one number to the power of 0" do + expect(pow(1000000,0)).to eq(1) + end end # 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" -end +# 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" +# end + +describe "factorial" do + it "computes the factorial of 0" do + expect(fac(0)).to eq(1) + end + it "computes the factorial of 1" do + expect(fac(1)).to eq(1) + end + it "computes the factorial of 2" do + expect(fac(2)).to eq(2) + end + it "computes the factorial of 5" do + expect(fac(5)).to eq(120) + end + it "computes the factorial of 10" do + expect(fac(10)).to eq(3628800) + end +end \ No newline at end of file From 63df339294d560dae7af1651233b1e8f6d845813 Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Mon, 24 Oct 2016 17:08:13 -0400 Subject: [PATCH 04/15] completed 03_simion_says --- 03_simon_says/simon_says.rb | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 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..813539042 --- /dev/null +++ b/03_simon_says/simon_says.rb @@ -0,0 +1,45 @@ +# Simon Says + +# Echo +def echo(word) + word +end + +# Shout +def shout(word) + word.upcase +end + +# Repeat +def repeat(word, times_said=2) + phrase = word + (times_said-1).times do + phrase += " " + word + end + phrase +end + +# Start of word +def start_of_word(word, location) + word[0...location] # 0 to location-1 +end + +# First word +def first_word(phrase) + phrase_arr = phrase.split(" ") + phrase_arr[0] +end + +# Capitalize +def titleize(phrase) + little_words = ["the", "a", "and", "over"] + phrase_arr = phrase.split(" ") + phrase_arr = phrase_arr.each_with_index do |word, location| + if location == 0 || !little_words.include?(word.downcase) + word[0] = word[0].upcase + end + end + phrase_arr.join(" ") +end + + From 87432fd9052be8ce68fdc4203d15d37b92f0bac8 Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Mon, 24 Oct 2016 17:42:30 -0400 Subject: [PATCH 05/15] completed 04_pig_latin --- 04_pig_latin/pig_latin.rb | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 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..42b1819c0 --- /dev/null +++ b/04_pig_latin/pig_latin.rb @@ -0,0 +1,44 @@ +# Pig Latin + +# Translate +def translate(phrase) + + # get all vowels in an array + vowels = ['a','e','i','o','u'] + + # break up phrase into array + phrase_array = phrase.split(" ") + + # initialize translated array + phrase_array_translated = [] + + # translate each word + phrase_array.each do |word| + + # check if word begins with a vowel + if vowels.include?(word[0].downcase) + phrase_array_translated << word += "ay" + next + + # check if word begins with a consonant or consonant "chunk" + else + consonant_chunk = "" + letter_tracker = 0 + + while !vowels.include?(word[letter_tracker].downcase) || # keep going until a vowel is hit, unless... + word[letter_tracker].downcase == "u" && word[letter_tracker-1].downcase == "q" # ...special case "qu" is found + + consonant_chunk += word[letter_tracker] + letter_tracker += 1 + + end + + phrase_array_translated << word[letter_tracker..word.length] + consonant_chunk + "ay" + end + + end + + phrase_array_translated.join(" ") + +end + From 6984750c2be32cadacb4b082734f3047d81b5e6c Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Mon, 24 Oct 2016 19:08:12 -0400 Subject: [PATCH 06/15] completed 05_silly_blocks --- 05_silly_blocks/silly_blocks.rb | 20 ++++++++++++++++++++ 1 file changed, 20 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..f936121c7 --- /dev/null +++ b/05_silly_blocks/silly_blocks.rb @@ -0,0 +1,20 @@ +# Reverser +def reverser(&block) + phrase_arr = block.call.split(" ") # get content of block + phrase_arr.each do |word| + word.reverse! # reverse element on phrase_arr directly (no copies made, potentially dangerous!) + end + phrase_arr.join(" ") +end + +# Adder +def adder(val=1) # block doesn't need to be mentioned + yield + val +end + +# Repeater +def repeater(val=1) # again, block doesn't need to be mentioned + val.times do + yield + end +end From b48002f9ccf7cc1d911b458a1917349e8bef7d11 Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Mon, 24 Oct 2016 19:32:34 -0400 Subject: [PATCH 07/15] completed 06_performance_monitor --- 06_performance_monitor/performance_monitor.rb | 7 +++++++ 1 file changed, 7 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..20d4cef3a --- /dev/null +++ b/06_performance_monitor/performance_monitor.rb @@ -0,0 +1,7 @@ +# Performance Monitor + +def measure(val=1) + start_time = Time.now + val.times { yield } + (Time.now - start_time) / val.to_f +end \ No newline at end of file From f5c3f2b2f09ec0ec5b9141b26f43c43964371e1d Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Mon, 24 Oct 2016 19:39:09 -0400 Subject: [PATCH 08/15] completed 07_hello_friend --- 07_hello_friend/friend.rb | 8 ++++++++ 1 file changed, 8 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..f68d5c675 --- /dev/null +++ b/07_hello_friend/friend.rb @@ -0,0 +1,8 @@ +class Friend + + def greeting(name = nil) + return "Hello!" if !name + "Hello, " + name + "!" + end + +end \ No newline at end of file From 2ef3ef8c137dcfee85e2bc669cb9a1247f18b0a9 Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Mon, 24 Oct 2016 20:40:08 -0400 Subject: [PATCH 09/15] completed 08_book_titles --- 08_book_titles/book.rb | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 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..b997d1c35 --- /dev/null +++ b/08_book_titles/book.rb @@ -0,0 +1,30 @@ +class Book + + # Constructor + def initialize + @title = "" + end + + # Read + def title + @title + end + + # Write + def title=(phrase) + phrase_array = [] + non_caps = ["and", "in", "the", "of", "a", "an"] + phrase.split(" ").each_with_index do |word, location| + if non_caps.include?(word.downcase) && location != 0 + phrase_array << word + else + phrase_array << word[0].upcase + word[1..word.length] + end + end + @title = phrase_array.join(" ") + end + +end + + + From e219f0d24aeb222af9531910fcfdb1b59473e8a3 Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Mon, 24 Oct 2016 21:12:43 -0400 Subject: [PATCH 10/15] completed 09_timer --- 09_timer/timer.rb | 47 ++++++++++++++++++++++++++++++++++++++++++ 09_timer/timer_spec.rb | 22 ++++++++++---------- 2 files changed, 58 insertions(+), 11 deletions(-) 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..c2fc73053 --- /dev/null +++ b/09_timer/timer.rb @@ -0,0 +1,47 @@ +# Timer + +class Timer + + # read & write access + attr_accessor :seconds + + # constructor + def initialize + @seconds = 0 + end + + # display seconds & string + def time_string + # initialize + seconds_copy = @seconds + time = [0,0,0] # [hours, mins, secs] + + # reduce seconds_copy iteratively to get hour/min/sec count + while seconds_copy > 3600 + time[0] += 1 + seconds_copy -= 3600 + end + while seconds_copy > 60 + time[1] += 1 + seconds_copy -= 60 + end + time[2] = seconds_copy + + # use hash to build string + time_str = "" + time.each_with_index do |value, location| # hour value, then minute value, then second value + time_str += padded(value) + time_str += ":" unless location == time.length - 1 + end + time_str + end + + # pads single-digit numbers for time_string + def padded(num) + num < 10 ? "0" + num.to_s : num.to_s + end + +end + +t = Timer.new +puts t.seconds \ No newline at end of file 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 cc8b6e788330a34be8d30941210138988d7ea7af Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Mon, 24 Oct 2016 22:52:50 -0400 Subject: [PATCH 11/15] completed 10_temperature_object --- 10_temperature_object/temperature.rb | 56 +++++++++++++++++++ .../temperature_object_spec.rb | 2 +- 2 files changed, 57 insertions(+), 1 deletion(-) 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..e0d40fb02 --- /dev/null +++ b/10_temperature_object/temperature.rb @@ -0,0 +1,56 @@ +# Temperature +class Temperature + + # Instance methods + + def initialize(options = {}) # options are :f (Fahrenheiet) and :c (Celsius) + if options.has_key?(:f) + @@fahrenheit = options[:f] + @@celsius = 5.0/9.0 * (@@fahrenheit - 32) + elsif options.has_key?(:c) + @@celsius = options[:c] + @@fahrenheit = 9.0/5.0 * @@celsius + 32 + else + raise "Invalid option" + end + end + + def in_fahrenheit + @@fahrenheit + end + + def in_celsius + @@celsius + end + + # Class (factory) methods + + def self.from_celsius(val) + Temperature.new(:c => val) + end + + def self.from_fahrenheit(val) + Temperature.new(:f => val) + end + +end + +# Celsius (subclass) +class Celsius < Temperature + + def initialize(val) + @@celsius = val + @@fahrenheit = 9.0/5.0 * @@celsius + 32 + end + +end + +# Fahrenheit (subclass) +class Fahrenheit < Temperature + + def initialize(val) + @@fahrenheit = val + @@celsius = 5.0/9.0 * (@@fahrenheit - 32) + end + +end diff --git a/10_temperature_object/temperature_object_spec.rb b/10_temperature_object/temperature_object_spec.rb index 5c0af8685..eaf169e5f 100644 --- a/10_temperature_object/temperature_object_spec.rb +++ b/10_temperature_object/temperature_object_spec.rb @@ -1,4 +1,4 @@ -# # Topics: + # # Topics: # * floating-point math # * objects # * constructors From 34cb227fba193a022f67b5f3747c79d7aee56944 Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Mon, 24 Oct 2016 23:31:32 -0400 Subject: [PATCH 12/15] completed 11_dictionary --- 11_dictionary/dictionary.rb | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 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..fc14269e2 --- /dev/null +++ b/11_dictionary/dictionary.rb @@ -0,0 +1,46 @@ +# Dictionary +class Dictionary + + # Read & write access + attr_accessor :entries + + # Constructor + def initialize + @entries = {} + end + + # Add entries + def add(entry) + entry = { entry => nil } if entry.is_a?(String) # only key provided, as string + @entries = @entries.merge(entry) # combine hashes together + end + + # Collect keys in array + def keywords + @entries.keys.sort + end + + # Check if key is present + def include?(key) + @entries.has_key?(key) + end + + # Find all keys with "word" inside it (fi should get entries for fish, fiend, figure) + def find(word) + @entries.select { |key, value| key.include?(word) } + end + + # Printable format + def printable + print_form = "" + entry_count = 0 + @entries.sort.each do |key, value| + print_form += "[#{key}] \"#{value}\"" + entry_count += 1 + print_form += "\n" unless entry_count == @entries.length + end + print_form + end + +end + From fbe363dfbda094ee8fdf3a4f5032743bd8c47fe6 Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Tue, 25 Oct 2016 14:07:34 -0400 Subject: [PATCH 13/15] completed 12_rpn_calculator --- 12_rpn_calculator/rpn_calculator.rb | 98 +++++++++++++++++++++++++++++ 1 file changed, 98 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..ccc4e2819 --- /dev/null +++ b/12_rpn_calculator/rpn_calculator.rb @@ -0,0 +1,98 @@ +class RPNCalculator + + # Class variables + @@operations = ["+", "-", "*", "/"] + + # Constructor + def initialize + @calc_array = [] + end + + # Collect pushed values + def push(val) + @calc_array.push(val.to_f) # Convert ints to floats + end + + # Collect operations (as symbols rather than strings - symbols take up less memory) + def plus + raise "calculator is empty" if @calc_array.length < 2 + @calc_array.push(:+) + end + def minus + raise "calculator is empty" if @calc_array.length < 2 + @calc_array.push(:-) + end + def times + raise "calculator is empty" if @calc_array.length < 2 + @calc_array.push(:*) + end + def divide + raise "calculator is empty" if @calc_array.length < 2 + @calc_array.push(:/) + end + + # Calculate result from @calc_array + def value + @calc_array_copy = @calc_array.dup + @calc_array_copy.each_with_index do |val, i| + # Look for operation + if ([:+, :-, :*, :/].include?(val)) + # Collect operation & two values before it in array "main" + main = [@calc_array_copy[i-2], @calc_array_copy[i-1], val] + # Collect everything in front of & behind "main" in separate arrays + front = i < 3 ? [] : @calc_array_copy[0..i-3] + back = i == @calc_array_copy.length - 1 ? [] : @calc_array_copy[i+1..-1] + # Rebuild @calc_array_copy after solving "main" + @calc_array_copy = front + solve(main) + back + # Set new value for @calc_array + @calc_array = @calc_array_copy.dup + # Recursion - run "value" again if an operation is still present within @calc_array + value if @calc_array.include?(:+) || @calc_array.include?(:-) || @calc_array.include?(:*) || @calc_array.include?(:/) + # Return last value in array + return @calc_array_copy[-1] + end + end + end + + # Tokenize a string expression - convert string argument to @calc_array + def tokens(expression) + @calc_array = [] + expression.split("").each do |char| + @calc_array << char.to_f if /[0-9]/.match(char) + @calc_array << :+ if /[+]/.match(char) + @calc_array << :- if /[-]/.match(char) + @calc_array << :* if /[*]/.match(char) + @calc_array << :/ if /[\/]/.match(char) + end + @calc_array + end + + # Evaluate a string expression + def evaluate(expression) + # Convert string expression to @calc_array + tokens(expression) + # Get value from @calc_array + value + end + + # Everything below "private" cannot be accessed outside of class + private + + # Solve operation in 3-part array form [m, n, op] + def solve(arr) + case arr[2] + when :+ + [arr[0] + arr[1]] + when :- + [arr[0] - arr[1]] + when :* + [arr[0] * arr[1]] + when :/ + [arr[0] / arr[1]] + else + raise "Error: RPNCalculator method \"solve\"" + end + end + +end + From c2ff88e6a0ee4cc507054cfa01e5a3567fcd3727 Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Tue, 25 Oct 2016 17:31:48 -0400 Subject: [PATCH 14/15] completed 14_array_extensions and 15_in_words --- 14_array_extensions/array_extensions.rb | 21 +++ 15_in_words/in_words.rb | 187 ++++++++++++++++++++++++ 15_in_words/in_words_spec.rb | 2 +- 3 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 14_array_extensions/array_extensions.rb create mode 100644 15_in_words/in_words.rb diff --git a/14_array_extensions/array_extensions.rb b/14_array_extensions/array_extensions.rb new file mode 100644 index 000000000..d17dbe8ce --- /dev/null +++ b/14_array_extensions/array_extensions.rb @@ -0,0 +1,21 @@ +class Array + + # Add all elements + def sum + return 0 if self.length == 0 + self.inject { |prev,curr| prev + curr } + end + + # Squares each element & rreturns copy + def square + return self if self.length == 0 + self.map { |val| val**2 } + end + + # Squares each element of original array + def square! + return self if self.length == 0 + self.map! { |val| val**2 } + end + +end \ No newline at end of file diff --git a/15_in_words/in_words.rb b/15_in_words/in_words.rb new file mode 100644 index 000000000..2dd84038a --- /dev/null +++ b/15_in_words/in_words.rb @@ -0,0 +1,187 @@ +class Fixnum + + def in_words + + # Automatically return on zero + return "zero" if self == 0 + + # Initialize array that will collect each individual word, to control spacing + phrase = [] + + # Initialize parameters that will keep track of numbers, from ones to trillions + trillions = 0 + billions = 0 + millions = 0 + thousands = 0 + hundreds = 0 + tens = 0 + ones = 0 + + # Initialize number that will be used to determine "ones" to "trillions" + num = self + + # Count number of trillions + while num >= 1000000000000 + trillions += 1 + num -= 1000000000000 + end + + # Add words for millions + if trillions > 0 # from 1 to 999 + phrase << trillions.in_words # put number from 1 to 999 into in_words recursively + phrase << "trillion" + phrase << num.in_words if num != 0 # add words for numbers less than 1 trillion + return phrase.join(" ") # combine all words in array, adding one space in between + end + + # Same logic for trillions applies to billions, millions, thousands, and hundreds! + + # Count number of billions + while num >= 1000000000 + billions += 1 + num -= 1000000000 + end + + # Add words for billions + if billions > 0 + phrase << billions.in_words + phrase << "billion" + phrase << num.in_words if num != 0 + return phrase.join(" ") + end + + # Count number of millions + while num >= 1000000 + millions += 1 + num -= 1000000 + end + + # Add words for millions + if millions > 0 + phrase << millions.in_words + phrase << "million" + phrase << num.in_words if num != 0 + return phrase.join(" ") + end + + # Count number of thousands + while num >= 1000 + thousands += 1 + num -= 1000 + end + + # Add words for thousands + if thousands > 0 + phrase << thousands.in_words + phrase << "thousand" + phrase << num.in_words if num != 0 + return phrase.join(" ") + end + + # Count number of hundreds + while num >= 100 + hundreds += 1 + num -= 100 + end + + # Add words for hundreds + if hundreds > 0 + phrase << hundreds.in_words + phrase << "hundred" + phrase << num.in_words if num != 0 + return phrase.join(" ") + end + + # Count number of tens + while num >= 10 + tens += 1 + num -= 10 + end + + # Count number of ones + while num >= 1 + ones += 1 + num -= 1 + end + + # Add words for tens & ones + if tens > 1 && ones > 0 # from 21 to 99 + return (tens*10).in_words + " " + ones.in_words + end + + # Explicit values 1 - every 10 numbers from 20 to 90 + # Need "return" keywords since they're not the last statement in this method + if self < 100 && self % 10 == 0 && self != 10 + case self + when 20 + return "twenty" + when 30 + return "thirty" + when 40 + return "forty" + when 50 + return "fifty" + when 60 + return "sixty" + when 70 + return "seventy" + when 80 + return "eighty" + when 90 + return "ninety" + else + raise "Error - in_words, 20 to 90" + end + end + + # Explicit values 2 - ever number from 1 to 19 + # No "return" keywords needed - last statement in array + if self < 20 + case self + when 1 + "one" + when 2 + "two" + when 3 + "three" + when 4 + "four" + when 5 + "five" + when 6 + "six" + when 7 + "seven" + when 8 + "eight" + when 9 + "nine" + when 10 + "ten" + when 11 + "eleven" + when 12 + "twelve" + when 13 + "thirteen" + when 14 + "fourteen" + when 15 + "fifteen" + when 16 + "sixteen" + when 17 + "seventeen" + when 18 + "eighteen" + when 19 + "nineteen" + else + raise "Error - in_words, 1 to 19" + end + end + + end + +end + diff --git a/15_in_words/in_words_spec.rb b/15_in_words/in_words_spec.rb index 1f5768575..c7f824cc0 100644 --- a/15_in_words/in_words_spec.rb +++ b/15_in_words/in_words_spec.rb @@ -38,7 +38,7 @@ it "reads 10 to 12" do expect(10.in_words).to eq('ten') expect(11.in_words).to eq('eleven') - expect(12.in_words).to eq ('twelve') + expect(12.in_words).to eq('twelve') end it "reads teens" do From 52c7239873039cba418a8264c1a31ff52e2a7d44 Mon Sep 17 00:00:00 2001 From: Pramod Jacob Date: Tue, 25 Oct 2016 17:37:49 -0400 Subject: [PATCH 15/15] renamed 13_xml_document to 13_xml_document_SKIPPED --- {13_xml_document => 13_xml_document_SKIPPED}/index.html | 0 {13_xml_document => 13_xml_document_SKIPPED}/xml_document_spec.rb | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {13_xml_document => 13_xml_document_SKIPPED}/index.html (100%) rename {13_xml_document => 13_xml_document_SKIPPED}/xml_document_spec.rb (100%) diff --git a/13_xml_document/index.html b/13_xml_document_SKIPPED/index.html similarity index 100% rename from 13_xml_document/index.html rename to 13_xml_document_SKIPPED/index.html diff --git a/13_xml_document/xml_document_spec.rb b/13_xml_document_SKIPPED/xml_document_spec.rb similarity index 100% rename from 13_xml_document/xml_document_spec.rb rename to 13_xml_document_SKIPPED/xml_document_spec.rb