From 97c6af53063c3c2a80c2bbb89d757549aadc65b7 Mon Sep 17 00:00:00 2001 From: masaki okamoto Date: Fri, 18 Jun 2021 15:48:46 +0900 Subject: [PATCH 01/12] first commit From 9389a72fa22cb9f4f8e8922185c8bd412edaaa90 Mon Sep 17 00:00:00 2001 From: masaki okamoto Date: Sun, 20 Jun 2021 11:10:08 +0900 Subject: [PATCH 02/12] =?UTF-8?q?simulator=E3=81=AE=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- challengeA/okamoto/.gitignore | 1 + challengeA/okamoto/.rspec | 1 + challengeA/okamoto/Gemfile | 3 + challengeA/okamoto/Gemfile.lock | 26 +++ challengeA/okamoto/lib/simulator.rb | 241 ++++++++++++++++++++++ challengeA/okamoto/spec/simulator_spec.rb | 230 +++++++++++++++++++++ challengeA/okamoto/spec/spec_helper.rb | 100 +++++++++ 7 files changed, 602 insertions(+) create mode 100644 challengeA/okamoto/.gitignore create mode 100644 challengeA/okamoto/.rspec create mode 100644 challengeA/okamoto/Gemfile create mode 100644 challengeA/okamoto/Gemfile.lock create mode 100644 challengeA/okamoto/lib/simulator.rb create mode 100644 challengeA/okamoto/spec/simulator_spec.rb create mode 100644 challengeA/okamoto/spec/spec_helper.rb diff --git a/challengeA/okamoto/.gitignore b/challengeA/okamoto/.gitignore new file mode 100644 index 000000000..f05cf8c8d --- /dev/null +++ b/challengeA/okamoto/.gitignore @@ -0,0 +1 @@ +/spec/examples.txt diff --git a/challengeA/okamoto/.rspec b/challengeA/okamoto/.rspec new file mode 100644 index 000000000..c99d2e739 --- /dev/null +++ b/challengeA/okamoto/.rspec @@ -0,0 +1 @@ +--require spec_helper diff --git a/challengeA/okamoto/Gemfile b/challengeA/okamoto/Gemfile new file mode 100644 index 000000000..8e9e159ba --- /dev/null +++ b/challengeA/okamoto/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem 'rspec' diff --git a/challengeA/okamoto/Gemfile.lock b/challengeA/okamoto/Gemfile.lock new file mode 100644 index 000000000..f7f91fc03 --- /dev/null +++ b/challengeA/okamoto/Gemfile.lock @@ -0,0 +1,26 @@ +GEM + remote: https://rubygems.org/ + specs: + diff-lcs (1.4.4) + rspec (3.10.0) + rspec-core (~> 3.10.0) + rspec-expectations (~> 3.10.0) + rspec-mocks (~> 3.10.0) + rspec-core (3.10.1) + rspec-support (~> 3.10.0) + rspec-expectations (3.10.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.10.0) + rspec-mocks (3.10.2) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.10.0) + rspec-support (3.10.2) + +PLATFORMS + x64-mingw32 + +DEPENDENCIES + rspec + +BUNDLED WITH + 2.2.20 diff --git a/challengeA/okamoto/lib/simulator.rb b/challengeA/okamoto/lib/simulator.rb new file mode 100644 index 000000000..141371f2d --- /dev/null +++ b/challengeA/okamoto/lib/simulator.rb @@ -0,0 +1,241 @@ +class Simulator + attr_reader :contract_amp, :power_usage, :plans + + def initialize(contract_amp, power_usage) + @contract_amp = contract_amp + @power_usage = power_usage + @plans = Plan.new(contract_amp, power_usage) + end + + def simulate + plans.show_plans + end +end + +class Plan + attr_reader :contract_amp, :power_usage, :plans + + def initialize(contract_amp, power_usage) + @plans = plans + @contract_amp = contract_amp + @power_usage = power_usage + end + + def show_plans + plans.map { |plan| available?(plan)? plan_with_price(plan) : nil }.compact + end + + private + + def available?(plan) + plan[:basic_price].find { |price| price[:ampere] == contract_amp } + end + + def plan_with_price(plan) + { + provider_name: plan[:provider_name], + plan_name: plan[:name], + price: sum_price(plan) + } + end + + def sum_price(plan) + (basic_price(plan) + pay_per_use_price(plan)).floor + end + + def basic_price(plan) + plan[:basic_price].find { |price| price[:ampere] == contract_amp }[:price] + end + + def pay_per_use_price(plan) + sum = 0 + power_usage_before_stage = 0 + sorted_pay_per_use_price_lists(plan).each do |price_list| + power_usage_current_stage = power_usage - price_list[:min_kwh] - power_usage_before_stage + #丸め誤差が生じるため小数点第四位を四捨五入とする + sum += (price_list[:price_per_kwh] * power_usage_current_stage).round(3) + power_usage_before_stage += power_usage_current_stage + end + sum + end + + def sorted_pay_per_use_price_lists(plan) + pay_per_use_price_lists(plan).sort_by {|list| list[:min_kwh]}.reverse + end + + def pay_per_use_price_lists(plan) + plan[:pay_per_use_price].select { |price| price[:min_kwh] <= power_usage } + end + + def plans + [ + { + name: '従量電灯B', + provider_name: '東京電力エナジーパートナー', + basic_price: [ + { + "ampere": 10, + "price": 286.0 + }, + { + "ampere": 15, + "price": 429.0 + }, + { + "ampere": 20, + "price": 572.0 + }, + { + "ampere": 30, + "price": 858.0 + }, + { + "ampere": 40, + "price": 1144.0 + }, + { + "ampere": 50, + "price": 1430.0 + }, + { + "ampere": 60, + "price": 1716.0 + } + ], + pay_per_use_price: [ + { + "price_per_kwh": 19.88, + "min_kwh": 0 + }, + { + "price_per_kwh": 26.48, + "min_kwh": 120 + }, + { + "price_per_kwh": 30.57, + "min_kwh": 300 + } + ] + }, + { + name: 'おうちプラン', + provider_name: 'Looopでんき', + basic_price: [ + { + "ampere": 10, + "price": 0 + }, + { + "ampere": 15, + "price": 0 + }, + { + "ampere": 20, + "price": 0 + }, + { + "ampere": 30, + "price": 0 + }, + { + "ampere": 40, + "price": 0 + }, + { + "ampere": 50, + "price": 0 + }, + { + "ampere": 60, + "price": 0 + } + ], + pay_per_use_price: [ + { + "price_per_kwh": 26.40, + "min_kwh": 0 + } + ] + }, + { + name: 'ずっとも電気1', + provider_name: '東京ガス', + basic_price: [ + { + "ampere": 30, + "price": 858.0 + }, + { + "ampere": 40, + "price": 1144.0 + }, + { + "ampere": 50, + "price": 1430.0 + }, + { + "ampere": 60, + "price": 1716.0 + } + ], + pay_per_use_price: [ + { + "price_per_kwh": 23.67, + "min_kwh": 0 + }, + { + "price_per_kwh": 23.88, + "min_kwh": 140 + }, + { + "price_per_kwh": 26.41, + "min_kwh": 350 + } + ] + }, + { + name: '従量電灯Bたっぷりプラン', + provider_name: 'JXTGでんき', + basic_price: [ + { + "ampere": 30, + "price": 858.0 + }, + { + "ampere": 40, + "price": 1144.0 + }, + { + "ampere": 50, + "price": 1430.0 + }, + { + "ampere": 60, + "price": 1716.8 + } + ], + pay_per_use_price: [ + { + "price_per_kwh": 19.88, + "min_kwh": 0 + }, + { + "price_per_kwh": 26.48, + "min_kwh": 120 + }, + { + "price_per_kwh": 25.08, + "min_kwh": 300 + }, + { + "price_per_kwh": 26.15, + "min_kwh": 600 + } + ] + } + ] + end +end + +simulator = Simulator.new(30,600) +puts simulator.simulate diff --git a/challengeA/okamoto/spec/simulator_spec.rb b/challengeA/okamoto/spec/simulator_spec.rb new file mode 100644 index 000000000..a7d44a7f3 --- /dev/null +++ b/challengeA/okamoto/spec/simulator_spec.rb @@ -0,0 +1,230 @@ +require 'spec_helper' + +RSpec.describe Plan do + TEPCO = '東京電力エナジーパートナー' + TEPCO_PLAN1 = '従量電灯B' + LOOOP = 'Looopでんき' + LOOOP_PLAN1 = 'おうちプラン' + TOKYOGAS = '東京ガス' + TOKYOGAS_PLAN1 = 'ずっとも電気1' + JXTG = 'JXTGでんき' + JXTG_PLAN1 = '従量電灯Bたっぷりプラン' + + describe '#show_plans' do + let(:plans) { Plan.new(amp, power) } + let(:tepco_plan1_price) { plans.show_plans.find {|plan| plan[:provider_name] == TEPCO && plan[:plan_name] == TEPCO_PLAN1 }[:price] } + let(:looop_plan1_price) { plans.show_plans.find {|plan| plan[:provider_name] == LOOOP && plan[:plan_name] == LOOOP_PLAN1 }[:price] } + let(:tokyogas_plan1_price) { plans.show_plans.find {|plan| plan[:provider_name] == TOKYOGAS && plan[:plan_name] == TOKYOGAS_PLAN1 }[:price] } + let(:jxtg_plan1_price) { plans.show_plans.find {|plan| plan[:provider_name] == JXTG && plan[:plan_name] == JXTG_PLAN1 }[:price] } + + shared_examples 'planが2件ヒットすること' do + it { expect(plans.show_plans.count).to eq 2 } + end + + shared_examples 'planが4件ヒットすること' do + it { expect(plans.show_plans.count).to eq 4 } + end + + context 'planヒット件数毎のテスト' do + context '141kwhの場合' do + let(:power) { 141 } + context '10Aの場合' do + let(:amp) { 10 } + + it_behaves_like 'planが2件ヒットすること' + it 'tepco_plan1_の価格が正常であること' do + expect(tepco_plan1_price).to eq (286.0 + 120 * 19.88 + (141 - 120) * 26.48).floor + end + it 'looop_plan1_の価格が正常であること' do + expect(looop_plan1_price).to eq (141 * 26.4).floor + end + end + + context '60Aの場合' do + let(:amp) { 60 } + + it_behaves_like 'planが4件ヒットすること' + it 'tepco_plan1_の価格が正常であること' do + expect(tepco_plan1_price).to eq (1716.0 + 120 * 19.88 + (141 - 120) * 26.48).floor + end + it 'looop_plan1_の価格が正常であること' do + expect(looop_plan1_price).to eq (141 * 26.4).floor + end + it 'tokyogas_plan1_の価格が正常であること' do + expect(tokyogas_plan1_price).to eq (1716.0 + 140 * 23.67 + (141 - 140) * 23.88).floor + end + it 'jxtg_plan1_の価格が正常であること' do + expect(jxtg_plan1_price).to eq (1716.8 + 120 * 19.88 + (141 - 120) * 26.48).floor + end + end + end + end + + context '従量制プランの境界値テスト' do + context '30Aのとき' do + let(:amp) { 30 } + context '0kwhのとき' do + let(:power) { 0 } + + it_behaves_like 'planが4件ヒットすること' + it 'tepco_plan1_の価格が正常であること' do + expect(tepco_plan1_price).to eq 858 + end + it 'looop_plan1_の価格が正常であること' do + expect(looop_plan1_price).to eq 0 + end + it 'tokyogas_plan1_の価格が正常であること' do + expect(tokyogas_plan1_price).to eq 858 + end + it 'jxtg_plan1_の価格が正常であること' do + expect(jxtg_plan1_price).to eq 858 + end + end + + context '120kwhのとき' do + let(:power) { 120 } + + it_behaves_like 'planが4件ヒットすること' + it 'tepco_plan1_の価格が正常であること' do + expect(tepco_plan1_price).to eq (858.0 + 120 * 19.88).floor + end + it 'looop_plan1_の価格が正常であること' do + expect(looop_plan1_price).to eq (120 * 26.4).floor + end + it 'tokyogas_plan1_の価格が正常であること' do + expect(tokyogas_plan1_price).to eq (858.0 + 120 * 23.67).floor + end + it 'jxtg_plan1_の価格が正常であること' do + expect(jxtg_plan1_price).to eq (858.0 + 120 * 19.88).floor + end + end + + context '120kwhのとき' do + let(:power) { 120 } + + it_behaves_like 'planが4件ヒットすること' + it 'tepco_plan1_の価格が正常であること' do + expect(tepco_plan1_price).to eq (858.0 + 120 * 19.88).floor + end + it 'looop_plan1_の価格が正常であること' do + expect(looop_plan1_price).to eq (120 * 26.4).floor + end + it 'tokyogas_plan1_の価格が正常であること' do + expect(tokyogas_plan1_price).to eq (858.0 + 120 * 23.67).floor + end + it 'jxtg_plan1_の価格が正常であること' do + expect(jxtg_plan1_price).to eq (858.0 + 120 * 19.88).floor + end + end + + context '140kwhのとき' do + let(:power) { 140 } + + it_behaves_like 'planが4件ヒットすること' + it 'tepco_plan1_の価格が正常であること' do + expect(tepco_plan1_price).to eq (858.0 + 120 * 19.88 + (140 - 120) * 26.48).floor + end + it 'looop_plan1_の価格が正常であること' do + expect(looop_plan1_price).to eq (140 * 26.4).floor + end + it 'tokyogas_plan1_の価格が正常であること' do + expect(tokyogas_plan1_price).to eq (858.0 + 140 * 23.67).floor + end + it 'jxtg_plan1_の価格が正常であること' do + expect(jxtg_plan1_price).to eq (858.0 + 120 * 19.88 + (140 - 120) * 26.48).floor + end + end + + context '300kwhのとき' do + let(:power) { 300 } + + it_behaves_like 'planが4件ヒットすること' + it 'tepco_plan1_の価格が正常であること' do + expect(tepco_plan1_price).to eq (858.0 + 120 * 19.88 + (300 - 120) * 26.48).floor + end + it 'looop_plan1_の価格が正常であること' do + expect(looop_plan1_price).to eq (300 * 26.4).floor + end + it 'tokyogas_plan1_の価格が正常であること' do + expect(tokyogas_plan1_price).to eq (858.0 + 140 * 23.67 + (300 - 140) * 23.88).floor + end + it 'jxtg_plan1_の価格が正常であること' do + expect(jxtg_plan1_price).to eq (858.0 + 120 * 19.88 + (300 - 120) * 26.48).floor + end + end + + context '300kwhのとき' do + let(:power) { 300 } + + it_behaves_like 'planが4件ヒットすること' + it 'tepco_plan1_の価格が正常であること' do + expect(tepco_plan1_price).to eq (858.0 + 120 * 19.88 + (300 - 120) * 26.48).floor + end + it 'looop_plan1_の価格が正常であること' do + expect(looop_plan1_price).to eq (300 * 26.4).floor + end + it 'tokyogas_plan1_の価格が正常であること' do + expect(tokyogas_plan1_price).to eq (858.0 + 140 * 23.67 + (300 - 140) * 23.88).floor + end + it 'jxtg_plan1_の価格が正常であること' do + expect(jxtg_plan1_price).to eq (858.0 + 120 * 19.88 + (300 - 120) * 26.48).floor + end + end + + context '350kwhのとき' do + let(:power) { 350 } + + it_behaves_like 'planが4件ヒットすること' + it 'tepco_plan1_の価格が正常であること' do + expect(tepco_plan1_price).to eq (858.0 + 120 * 19.88 + (300 - 120) * 26.48 + (350 - 300) * 30.57).floor + end + it 'looop_plan1_の価格が正常であること' do + expect(looop_plan1_price).to eq (350 * 26.4).floor + end + it 'tokyogas_plan1_の価格が正常であること' do + expect(tokyogas_plan1_price).to eq (858.0 + 140 * 23.67 + (350 - 140) * 23.88).floor + end + it 'jxtg_plan1_の価格が正常であること' do + expect(jxtg_plan1_price).to eq (858.0 + 120 * 19.88 + (300 - 120) * 26.48 + (350 - 300) * 25.08).floor + end + end + + context '600kwhのとき' do + let(:power) { 600 } + + it_behaves_like 'planが4件ヒットすること' + it 'tepco_plan1_の価格が正常であること' do + expect(tepco_plan1_price).to eq (858.0 + 120 * 19.88 + (300 - 120) * 26.48 + (600 - 300) * 30.57).floor + end + it 'looop_plan1_の価格が正常であること' do + expect(looop_plan1_price).to eq (600 * 26.4).floor + end + it 'tokyogas_plan1_の価格が正常であること' do + expect(tokyogas_plan1_price).to eq (858.0 + 140 * 23.67 + (350 - 140) * 23.88 + (600 - 350) * 26.41).floor + end + it 'jxtg_plan1_の価格が正常であること' do + expect(jxtg_plan1_price).to eq (858.0 + 120 * 19.88 + (300 - 120) * 26.48 + (600 - 300) * 25.08).floor + end + end + + context '601kwhのとき' do + let(:power) { 601 } + + it_behaves_like 'planが4件ヒットすること' + it 'tepco_plan1_の価格が正常であること' do + expect(tepco_plan1_price).to eq (858.0 + 120 * 19.88 + (300 - 120) * 26.48 + (601 - 300) * 30.57).floor + end + it 'looop_plan1_の価格が正常であること' do + expect(looop_plan1_price).to eq (601 * 26.4).floor + end + it 'tokyogas_plan1_の価格が正常であること' do + expect(tokyogas_plan1_price).to eq (858.0 + 140 * 23.67 + (350 - 140) * 23.88 + (601 - 350) * 26.41).floor + end + it 'jxtg_plan1_の価格が正常であること' do + expect(jxtg_plan1_price).to eq (858.0 + 120 * 19.88 + (300 - 120) * 26.48 + (600 - 300) * 25.08 + (601 - 600) * 26.15).floor + end + end + end + end + end +end diff --git a/challengeA/okamoto/spec/spec_helper.rb b/challengeA/okamoto/spec/spec_helper.rb new file mode 100644 index 000000000..a57ece4ab --- /dev/null +++ b/challengeA/okamoto/spec/spec_helper.rb @@ -0,0 +1,100 @@ +# 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. +# +# 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 + + # This option will default to `:apply_to_host_groups` in RSpec 4 (and will + # have no way to turn it off -- the option exists only for backwards + # compatibility in RSpec 3). It causes shared context metadata to be + # inherited by the metadata hash of host groups and examples, rather than + # triggering implicit auto-inclusion in groups with matching metadata. + config.shared_context_metadata_behavior = :apply_to_host_groups + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. + # This allows 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. RSpec also provides + # aliases for `it`, `describe`, and `context` that include `:focus` + # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + config.filter_run_when_matching :focus + + # Allows RSpec to persist some state between runs in order to support + # the `--only-failures` and `--next-failure` CLI options. We recommend + # you configure your source control system to ignore this file. + config.example_status_persistence_file_path = "spec/examples.txt" + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ + # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode + 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 + +Dir[File.join(File.dirname(__FILE__), "../lib/**/*.rb")].each { |f| require f } From d410aff2632ac53bab23e0f5db1c03c14d765ec2 Mon Sep 17 00:00:00 2001 From: masaki okamoto Date: Sun, 20 Jun 2021 11:19:31 +0900 Subject: [PATCH 03/12] =?UTF-8?q?spec=E3=81=AE=E9=87=8D=E8=A4=87=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- challengeA/okamoto/spec/simulator_spec.rb | 36 ----------------------- 1 file changed, 36 deletions(-) diff --git a/challengeA/okamoto/spec/simulator_spec.rb b/challengeA/okamoto/spec/simulator_spec.rb index a7d44a7f3..8db8aed2d 100644 --- a/challengeA/okamoto/spec/simulator_spec.rb +++ b/challengeA/okamoto/spec/simulator_spec.rb @@ -99,24 +99,6 @@ end end - context '120kwhのとき' do - let(:power) { 120 } - - it_behaves_like 'planが4件ヒットすること' - it 'tepco_plan1_の価格が正常であること' do - expect(tepco_plan1_price).to eq (858.0 + 120 * 19.88).floor - end - it 'looop_plan1_の価格が正常であること' do - expect(looop_plan1_price).to eq (120 * 26.4).floor - end - it 'tokyogas_plan1_の価格が正常であること' do - expect(tokyogas_plan1_price).to eq (858.0 + 120 * 23.67).floor - end - it 'jxtg_plan1_の価格が正常であること' do - expect(jxtg_plan1_price).to eq (858.0 + 120 * 19.88).floor - end - end - context '140kwhのとき' do let(:power) { 140 } @@ -153,24 +135,6 @@ end end - context '300kwhのとき' do - let(:power) { 300 } - - it_behaves_like 'planが4件ヒットすること' - it 'tepco_plan1_の価格が正常であること' do - expect(tepco_plan1_price).to eq (858.0 + 120 * 19.88 + (300 - 120) * 26.48).floor - end - it 'looop_plan1_の価格が正常であること' do - expect(looop_plan1_price).to eq (300 * 26.4).floor - end - it 'tokyogas_plan1_の価格が正常であること' do - expect(tokyogas_plan1_price).to eq (858.0 + 140 * 23.67 + (300 - 140) * 23.88).floor - end - it 'jxtg_plan1_の価格が正常であること' do - expect(jxtg_plan1_price).to eq (858.0 + 120 * 19.88 + (300 - 120) * 26.48).floor - end - end - context '350kwhのとき' do let(:power) { 350 } From e7e777ead573a14f77b73e104d2922ef4fdda239 Mon Sep 17 00:00:00 2001 From: masaki okamoto Date: Sun, 20 Jun 2021 12:36:08 +0900 Subject: [PATCH 04/12] =?UTF-8?q?plans=E8=AA=AD=E3=81=BF=E8=BE=BC=E3=81=BF?= =?UTF-8?q?=E3=82=92JSON=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=81=8B?= =?UTF-8?q?=E3=82=89=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- challengeA/okamoto/data/plans.json | 166 +++++++++++++++++++++++ challengeA/okamoto/lib/simulator.rb | 195 +++------------------------- 2 files changed, 183 insertions(+), 178 deletions(-) create mode 100644 challengeA/okamoto/data/plans.json diff --git a/challengeA/okamoto/data/plans.json b/challengeA/okamoto/data/plans.json new file mode 100644 index 000000000..70d7c550b --- /dev/null +++ b/challengeA/okamoto/data/plans.json @@ -0,0 +1,166 @@ +[ + { + "name": "従量電灯B", + "provider_name": "東京電力エナジーパートナー", + "basic_price": [ + { + "ampere": 10, + "price": 286.0 + }, + { + "ampere": 15, + "price": 429.0 + }, + { + "ampere": 20, + "price": 572.0 + }, + { + "ampere": 30, + "price": 858.0 + }, + { + "ampere": 40, + "price": 1144.0 + }, + { + "ampere": 50, + "price": 1430.0 + }, + { + "ampere": 60, + "price": 1716.0 + } + ], + "pay_per_use_price": [ + { + "price_per_kwh": 19.88, + "min_kwh": 0 + }, + { + "price_per_kwh": 26.48, + "min_kwh": 120 + }, + { + "price_per_kwh": 30.57, + "min_kwh": 300 + } + ] + }, + { + "name": "おうちプラン", + "provider_name": "Looopでんき", + "basic_price": [ + { + "ampere": 10, + "price": 0 + }, + { + "ampere": 15, + "price": 0 + }, + { + "ampere": 20, + "price": 0 + }, + { + "ampere": 30, + "price": 0 + }, + { + "ampere": 40, + "price": 0 + }, + { + "ampere": 50, + "price": 0 + }, + { + "ampere": 60, + "price": 0 + } + ], + "pay_per_use_price": [ + { + "price_per_kwh": 26.40, + "min_kwh": 0 + } + ] + }, + { + "name": "ずっとも電気1", + "provider_name": "東京ガス", + "basic_price": [ + { + "ampere": 30, + "price": 858.0 + }, + { + "ampere": 40, + "price": 1144.0 + }, + { + "ampere": 50, + "price": 1430.0 + }, + { + "ampere": 60, + "price": 1716.0 + } + ], + "pay_per_use_price": [ + { + "price_per_kwh": 23.67, + "min_kwh": 0 + }, + { + "price_per_kwh": 23.88, + "min_kwh": 140 + }, + { + "price_per_kwh": 26.41, + "min_kwh": 350 + } + ] + }, + { + "name": "従量電灯Bたっぷりプラン", + "provider_name": "JXTGでんき", + "basic_price": [ + { + "ampere": 30, + "price": 858.0 + }, + { + "ampere": 40, + "price": 1144.0 + }, + { + "ampere": 50, + "price": 1430.0 + }, + { + "ampere": 60, + "price": 1716.8 + } + ], + "pay_per_use_price": [ + { + "price_per_kwh": 19.88, + "min_kwh": 0 + }, + { + "price_per_kwh": 26.48, + "min_kwh": 120 + }, + { + "price_per_kwh": 25.08, + "min_kwh": 300 + }, + { + "price_per_kwh": 26.15, + "min_kwh": 600 + } + ] + } +] diff --git a/challengeA/okamoto/lib/simulator.rb b/challengeA/okamoto/lib/simulator.rb index 141371f2d..3372b4422 100644 --- a/challengeA/okamoto/lib/simulator.rb +++ b/challengeA/okamoto/lib/simulator.rb @@ -1,3 +1,6 @@ +require 'json' +JSON_FILE_PATH = '../data/plans.json' + class Simulator attr_reader :contract_amp, :power_usage, :plans @@ -16,7 +19,7 @@ class Plan attr_reader :contract_amp, :power_usage, :plans def initialize(contract_amp, power_usage) - @plans = plans + @plans = json_load @contract_amp = contract_amp @power_usage = power_usage end @@ -27,14 +30,19 @@ def show_plans private + def json_load + json_file_path = File.expand_path(JSON_FILE_PATH, __dir__) + JSON.load(File.open(json_file_path)) + end + def available?(plan) - plan[:basic_price].find { |price| price[:ampere] == contract_amp } + plan['basic_price'].find { |price| price['ampere'] == contract_amp } end def plan_with_price(plan) { - provider_name: plan[:provider_name], - plan_name: plan[:name], + provider_name: plan['provider_name'], + plan_name: plan['name'], price: sum_price(plan) } end @@ -44,196 +52,27 @@ def sum_price(plan) end def basic_price(plan) - plan[:basic_price].find { |price| price[:ampere] == contract_amp }[:price] + plan['basic_price'].find { |price| price['ampere'] == contract_amp }['price'] end def pay_per_use_price(plan) sum = 0 power_usage_before_stage = 0 sorted_pay_per_use_price_lists(plan).each do |price_list| - power_usage_current_stage = power_usage - price_list[:min_kwh] - power_usage_before_stage + power_usage_current_stage = power_usage - price_list['min_kwh'] - power_usage_before_stage #丸め誤差が生じるため小数点第四位を四捨五入とする - sum += (price_list[:price_per_kwh] * power_usage_current_stage).round(3) + sum += (price_list['price_per_kwh'] * power_usage_current_stage).round(3) power_usage_before_stage += power_usage_current_stage end sum end def sorted_pay_per_use_price_lists(plan) - pay_per_use_price_lists(plan).sort_by {|list| list[:min_kwh]}.reverse + pay_per_use_price_lists(plan).sort_by {|list| list['min_kwh']}.reverse end def pay_per_use_price_lists(plan) - plan[:pay_per_use_price].select { |price| price[:min_kwh] <= power_usage } - end - - def plans - [ - { - name: '従量電灯B', - provider_name: '東京電力エナジーパートナー', - basic_price: [ - { - "ampere": 10, - "price": 286.0 - }, - { - "ampere": 15, - "price": 429.0 - }, - { - "ampere": 20, - "price": 572.0 - }, - { - "ampere": 30, - "price": 858.0 - }, - { - "ampere": 40, - "price": 1144.0 - }, - { - "ampere": 50, - "price": 1430.0 - }, - { - "ampere": 60, - "price": 1716.0 - } - ], - pay_per_use_price: [ - { - "price_per_kwh": 19.88, - "min_kwh": 0 - }, - { - "price_per_kwh": 26.48, - "min_kwh": 120 - }, - { - "price_per_kwh": 30.57, - "min_kwh": 300 - } - ] - }, - { - name: 'おうちプラン', - provider_name: 'Looopでんき', - basic_price: [ - { - "ampere": 10, - "price": 0 - }, - { - "ampere": 15, - "price": 0 - }, - { - "ampere": 20, - "price": 0 - }, - { - "ampere": 30, - "price": 0 - }, - { - "ampere": 40, - "price": 0 - }, - { - "ampere": 50, - "price": 0 - }, - { - "ampere": 60, - "price": 0 - } - ], - pay_per_use_price: [ - { - "price_per_kwh": 26.40, - "min_kwh": 0 - } - ] - }, - { - name: 'ずっとも電気1', - provider_name: '東京ガス', - basic_price: [ - { - "ampere": 30, - "price": 858.0 - }, - { - "ampere": 40, - "price": 1144.0 - }, - { - "ampere": 50, - "price": 1430.0 - }, - { - "ampere": 60, - "price": 1716.0 - } - ], - pay_per_use_price: [ - { - "price_per_kwh": 23.67, - "min_kwh": 0 - }, - { - "price_per_kwh": 23.88, - "min_kwh": 140 - }, - { - "price_per_kwh": 26.41, - "min_kwh": 350 - } - ] - }, - { - name: '従量電灯Bたっぷりプラン', - provider_name: 'JXTGでんき', - basic_price: [ - { - "ampere": 30, - "price": 858.0 - }, - { - "ampere": 40, - "price": 1144.0 - }, - { - "ampere": 50, - "price": 1430.0 - }, - { - "ampere": 60, - "price": 1716.8 - } - ], - pay_per_use_price: [ - { - "price_per_kwh": 19.88, - "min_kwh": 0 - }, - { - "price_per_kwh": 26.48, - "min_kwh": 120 - }, - { - "price_per_kwh": 25.08, - "min_kwh": 300 - }, - { - "price_per_kwh": 26.15, - "min_kwh": 600 - } - ] - } - ] + plan['pay_per_use_price'].select { |price| price['min_kwh'] <= power_usage } end end From 85f883844215c1c15b940bbb8d644cb254f8e4fd Mon Sep 17 00:00:00 2001 From: masaki okamoto Date: Sun, 20 Jun 2021 13:45:31 +0900 Subject: [PATCH 05/12] =?UTF-8?q?=E5=85=A5=E5=8A=9B=E5=80=A4=E3=82=92?= =?UTF-8?q?=E6=A8=99=E6=BA=96=E5=85=A5=E5=8A=9B=E3=81=8B=E3=82=89=E5=8F=97?= =?UTF-8?q?=E3=81=91=E5=8F=96=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- challengeA/okamoto/lib/simulator.rb | 3 --- challengeA/okamoto/main.rb | 35 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 challengeA/okamoto/main.rb diff --git a/challengeA/okamoto/lib/simulator.rb b/challengeA/okamoto/lib/simulator.rb index 3372b4422..2b79e8236 100644 --- a/challengeA/okamoto/lib/simulator.rb +++ b/challengeA/okamoto/lib/simulator.rb @@ -75,6 +75,3 @@ def pay_per_use_price_lists(plan) plan['pay_per_use_price'].select { |price| price['min_kwh'] <= power_usage } end end - -simulator = Simulator.new(30,600) -puts simulator.simulate diff --git a/challengeA/okamoto/main.rb b/challengeA/okamoto/main.rb new file mode 100644 index 000000000..4aede8bba --- /dev/null +++ b/challengeA/okamoto/main.rb @@ -0,0 +1,35 @@ +require './lib/simulator' + +AVAILABLE_AMP = [10, 15, 20, 30, 40, 50, 60] + +puts '契約アンペア数を数字のみで入力してください。' +puts "#{AVAILABLE_AMP}の中から選択してください。" +contract_amp = gets.to_i + +unless AVAILABLE_AMP.include?(contract_amp) + puts '契約アンペア数の入力が不正です。' + exit +end + +puts '電力使用量(kWh)を整数のみで入力してください' +power_usage = gets.to_i + +if power_usage.negative? + puts '電力使用量(kWh)は0以上を入力してください。' + exit +end + +simulator = Simulator.new(contract_amp, power_usage) +plan_lists = simulator.simulate + +return puts '条件に一致するプランはありません。' if plan_lists.empty? + +puts 'ご入力いただいた条件での見積もり結果は以下の通りです。' +puts "契約アンペア:#{contract_amp}(A), 電力使用量:#{power_usage}(kwh)" +puts '================================================' +plan_lists.each do |plan| + puts "プロバイダー名:#{plan[:provider_name]}" + puts "プラン名:#{plan[:plan_name]}" + puts "月額料金:#{plan[:price]}円" + puts '================================================' +end From 7b78da76028833751549c65e4c94998a2605480e Mon Sep 17 00:00:00 2001 From: masaki okamoto Date: Sun, 20 Jun 2021 13:47:18 +0900 Subject: [PATCH 06/12] =?UTF-8?q?README=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- challengeA/okamoto/README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 challengeA/okamoto/README.md diff --git a/challengeA/okamoto/README.md b/challengeA/okamoto/README.md new file mode 100644 index 000000000..d125911d5 --- /dev/null +++ b/challengeA/okamoto/README.md @@ -0,0 +1,25 @@ +# CHALLENGE A + +## 概要 + +契約アンペア(A)と月の電力使用量(kWh)の入力に応じて、各プラン名と料金のシミュレーションを行うスクリプトです。 + +## シミュレーション実行方法 + +```sh +ruby main.rb +``` + +## データの編集 + +JSON形式で`/data`のディレクトリに格納しています。プラン追加や編集の際はJSONデータを修正することで対応できるように実装しています。 + +## テスト + +```sh +bundle exec rspec +``` + +## 補足事項 + +- 合計電気料金は小数点以下切り捨て From ebb77b12f00cf69007ea0a3decc05f80db308a0c Mon Sep 17 00:00:00 2001 From: masaki okamoto Date: Sun, 20 Jun 2021 13:55:50 +0900 Subject: [PATCH 07/12] =?UTF-8?q?plan=E3=82=AF=E3=83=A9=E3=82=B9=E3=82=92?= =?UTF-8?q?=E5=88=A5=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=81=B8=E5=88=86?= =?UTF-8?q?=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- challengeA/okamoto/lib/plan.rb | 63 ++++++++++++++++++ challengeA/okamoto/lib/simulator.rb | 64 +------------------ .../spec/{simulator_spec.rb => plan_spec.rb} | 0 3 files changed, 64 insertions(+), 63 deletions(-) create mode 100644 challengeA/okamoto/lib/plan.rb rename challengeA/okamoto/spec/{simulator_spec.rb => plan_spec.rb} (100%) diff --git a/challengeA/okamoto/lib/plan.rb b/challengeA/okamoto/lib/plan.rb new file mode 100644 index 000000000..d907451ae --- /dev/null +++ b/challengeA/okamoto/lib/plan.rb @@ -0,0 +1,63 @@ +require 'json' +JSON_FILE_PATH = '../data/plans.json' + +class Plan + attr_reader :contract_amp, :power_usage, :plans + + def initialize(contract_amp, power_usage) + @plans = json_load + @contract_amp = contract_amp + @power_usage = power_usage + end + + def show_plans + plans.map { |plan| available?(plan)? plan_with_price(plan) : nil }.compact + end + + private + + def json_load + json_file_path = File.expand_path(JSON_FILE_PATH, __dir__) + JSON.load(File.open(json_file_path)) + end + + def available?(plan) + plan['basic_price'].find { |price| price['ampere'] == contract_amp } + end + + def plan_with_price(plan) + { + provider_name: plan['provider_name'], + plan_name: plan['name'], + price: sum_price(plan) + } + end + + def sum_price(plan) + (basic_price(plan) + pay_per_use_price(plan)).floor + end + + def basic_price(plan) + plan['basic_price'].find { |price| price['ampere'] == contract_amp }['price'] + end + + def pay_per_use_price(plan) + sum = 0 + power_usage_before_stage = 0 + sorted_pay_per_use_price_lists(plan).each do |price_list| + power_usage_current_stage = power_usage - price_list['min_kwh'] - power_usage_before_stage + #丸め誤差が生じるため小数点第四位を四捨五入とする + sum += (price_list['price_per_kwh'] * power_usage_current_stage).round(3) + power_usage_before_stage += power_usage_current_stage + end + sum + end + + def sorted_pay_per_use_price_lists(plan) + pay_per_use_price_lists(plan).sort_by {|list| list['min_kwh']}.reverse + end + + def pay_per_use_price_lists(plan) + plan['pay_per_use_price'].select { |price| price['min_kwh'] <= power_usage } + end +end diff --git a/challengeA/okamoto/lib/simulator.rb b/challengeA/okamoto/lib/simulator.rb index 2b79e8236..e28cfb6d3 100644 --- a/challengeA/okamoto/lib/simulator.rb +++ b/challengeA/okamoto/lib/simulator.rb @@ -1,5 +1,4 @@ -require 'json' -JSON_FILE_PATH = '../data/plans.json' +require './lib/plan' class Simulator attr_reader :contract_amp, :power_usage, :plans @@ -14,64 +13,3 @@ def simulate plans.show_plans end end - -class Plan - attr_reader :contract_amp, :power_usage, :plans - - def initialize(contract_amp, power_usage) - @plans = json_load - @contract_amp = contract_amp - @power_usage = power_usage - end - - def show_plans - plans.map { |plan| available?(plan)? plan_with_price(plan) : nil }.compact - end - - private - - def json_load - json_file_path = File.expand_path(JSON_FILE_PATH, __dir__) - JSON.load(File.open(json_file_path)) - end - - def available?(plan) - plan['basic_price'].find { |price| price['ampere'] == contract_amp } - end - - def plan_with_price(plan) - { - provider_name: plan['provider_name'], - plan_name: plan['name'], - price: sum_price(plan) - } - end - - def sum_price(plan) - (basic_price(plan) + pay_per_use_price(plan)).floor - end - - def basic_price(plan) - plan['basic_price'].find { |price| price['ampere'] == contract_amp }['price'] - end - - def pay_per_use_price(plan) - sum = 0 - power_usage_before_stage = 0 - sorted_pay_per_use_price_lists(plan).each do |price_list| - power_usage_current_stage = power_usage - price_list['min_kwh'] - power_usage_before_stage - #丸め誤差が生じるため小数点第四位を四捨五入とする - sum += (price_list['price_per_kwh'] * power_usage_current_stage).round(3) - power_usage_before_stage += power_usage_current_stage - end - sum - end - - def sorted_pay_per_use_price_lists(plan) - pay_per_use_price_lists(plan).sort_by {|list| list['min_kwh']}.reverse - end - - def pay_per_use_price_lists(plan) - plan['pay_per_use_price'].select { |price| price['min_kwh'] <= power_usage } - end -end diff --git a/challengeA/okamoto/spec/simulator_spec.rb b/challengeA/okamoto/spec/plan_spec.rb similarity index 100% rename from challengeA/okamoto/spec/simulator_spec.rb rename to challengeA/okamoto/spec/plan_spec.rb From c94a9b9faadca7807d575fbf5788052d9cacd83f Mon Sep 17 00:00:00 2001 From: masaki okamoto Date: Sun, 20 Jun 2021 14:02:14 +0900 Subject: [PATCH 08/12] =?UTF-8?q?=E5=8F=82=E8=80=83=E6=96=87=E7=8C=AE?= =?UTF-8?q?=E3=82=92README=E3=81=AB=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- challengeA/okamoto/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/challengeA/okamoto/README.md b/challengeA/okamoto/README.md index d125911d5..88c25156d 100644 --- a/challengeA/okamoto/README.md +++ b/challengeA/okamoto/README.md @@ -23,3 +23,8 @@ bundle exec rspec ## 補足事項 - 合計電気料金は小数点以下切り捨て + +## 参考文献 + +- オブジェクト指向設計実践ガイド +- [使えるRSpec入門](https://qiita.com/jnchito/items/42193d066bd61c740612) From 1cafae68b9f1c26fb315408aacb2b9540c4a3865 Mon Sep 17 00:00:00 2001 From: masaki okamoto Date: Sun, 20 Jun 2021 14:11:00 +0900 Subject: [PATCH 09/12] =?UTF-8?q?=E5=A5=91=E7=B4=84=E3=82=A2=E3=83=B3?= =?UTF-8?q?=E3=83=9A=E3=82=A2=E5=AF=BE=E8=B1=A1=E3=81=8C=E3=81=AA=E3=81=84?= =?UTF-8?q?=E5=A0=B4=E5=90=88=E3=81=AE=E3=83=86=E3=82=B9=E3=83=88=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- challengeA/okamoto/spec/plan_spec.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/challengeA/okamoto/spec/plan_spec.rb b/challengeA/okamoto/spec/plan_spec.rb index 8db8aed2d..9f3a061e8 100644 --- a/challengeA/okamoto/spec/plan_spec.rb +++ b/challengeA/okamoto/spec/plan_spec.rb @@ -17,6 +17,10 @@ let(:tokyogas_plan1_price) { plans.show_plans.find {|plan| plan[:provider_name] == TOKYOGAS && plan[:plan_name] == TOKYOGAS_PLAN1 }[:price] } let(:jxtg_plan1_price) { plans.show_plans.find {|plan| plan[:provider_name] == JXTG && plan[:plan_name] == JXTG_PLAN1 }[:price] } + shared_examples 'planがヒットしないこと' do + it { expect(plans.show_plans.count).to eq 0 } + end + shared_examples 'planが2件ヒットすること' do it { expect(plans.show_plans.count).to eq 2 } end @@ -190,5 +194,16 @@ end end end + + context '契約アンペア対象がない場合のテスト' do + context '141kwhの場合' do + let(:power) { 141 } + context '70Aの場合' do + let(:amp) { 70 } + + it_behaves_like 'planがヒットしないこと' + end + end + end end end From e2f9b7f8471fa2786b2577c085c3c144b1da8a02 Mon Sep 17 00:00:00 2001 From: masaki okamoto Date: Mon, 21 Jun 2021 17:07:41 +0900 Subject: [PATCH 10/12] =?UTF-8?q?Plan=E3=82=AF=E3=83=A9=E3=82=B9=E3=82=92P?= =?UTF-8?q?lans=E3=81=A8Plan=E3=81=B8=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- challengeA/okamoto/lib/plan.rb | 59 +++++++++++----------------- challengeA/okamoto/lib/plans.rb | 33 ++++++++++++++++ challengeA/okamoto/lib/simulator.rb | 4 +- challengeA/okamoto/spec/plan_spec.rb | 4 +- 4 files changed, 61 insertions(+), 39 deletions(-) create mode 100644 challengeA/okamoto/lib/plans.rb diff --git a/challengeA/okamoto/lib/plan.rb b/challengeA/okamoto/lib/plan.rb index d907451ae..65a4f8cdc 100644 --- a/challengeA/okamoto/lib/plan.rb +++ b/challengeA/okamoto/lib/plan.rb @@ -1,50 +1,39 @@ -require 'json' -JSON_FILE_PATH = '../data/plans.json' - class Plan - attr_reader :contract_amp, :power_usage, :plans - - def initialize(contract_amp, power_usage) - @plans = json_load - @contract_amp = contract_amp - @power_usage = power_usage - end + attr_reader :name, :provider_name, :basic_prices, :pay_per_use_prices - def show_plans - plans.map { |plan| available?(plan)? plan_with_price(plan) : nil }.compact + def initialize(name:, provider_name:, basic_prices:, pay_per_use_prices:) + @name = name + @provider_name = provider_name + @basic_prices = basic_prices + @pay_per_use_prices = pay_per_use_prices end - private - - def json_load - json_file_path = File.expand_path(JSON_FILE_PATH, __dir__) - JSON.load(File.open(json_file_path)) + def available?(contract_amp) + basic_prices.find { |price| price['ampere'] == contract_amp } end - def available?(plan) - plan['basic_price'].find { |price| price['ampere'] == contract_amp } - end - - def plan_with_price(plan) + def plan_with_price(contract_amp, power_usage) { - provider_name: plan['provider_name'], - plan_name: plan['name'], - price: sum_price(plan) + provider_name: provider_name, + plan_name: name, + price: sum_price(contract_amp, power_usage) } end - def sum_price(plan) - (basic_price(plan) + pay_per_use_price(plan)).floor + private + + def sum_price(contract_amp, power_usage) + (basic_price(contract_amp) + pay_per_use_price(power_usage)).floor end - def basic_price(plan) - plan['basic_price'].find { |price| price['ampere'] == contract_amp }['price'] + def basic_price(contract_amp) + basic_prices.find { |price| price['ampere'] == contract_amp }['price'] end - def pay_per_use_price(plan) + def pay_per_use_price(power_usage) sum = 0 power_usage_before_stage = 0 - sorted_pay_per_use_price_lists(plan).each do |price_list| + sorted_pay_per_use_price_lists(power_usage).each do |price_list| power_usage_current_stage = power_usage - price_list['min_kwh'] - power_usage_before_stage #丸め誤差が生じるため小数点第四位を四捨五入とする sum += (price_list['price_per_kwh'] * power_usage_current_stage).round(3) @@ -53,11 +42,11 @@ def pay_per_use_price(plan) sum end - def sorted_pay_per_use_price_lists(plan) - pay_per_use_price_lists(plan).sort_by {|list| list['min_kwh']}.reverse + def sorted_pay_per_use_price_lists(power_usage) + pay_per_use_price_lists(power_usage).sort_by {|list| list['min_kwh']}.reverse end - def pay_per_use_price_lists(plan) - plan['pay_per_use_price'].select { |price| price['min_kwh'] <= power_usage } + def pay_per_use_price_lists(power_usage) + pay_per_use_prices.select { |price| price['min_kwh'] <= power_usage } end end diff --git a/challengeA/okamoto/lib/plans.rb b/challengeA/okamoto/lib/plans.rb new file mode 100644 index 000000000..702011a0f --- /dev/null +++ b/challengeA/okamoto/lib/plans.rb @@ -0,0 +1,33 @@ +require './lib/plan' +require 'json' +JSON_FILE_PATH = '../data/plans.json' + +class Plans + attr_reader :contract_amp, :power_usage, :plans + + def initialize(contract_amp, power_usage) + @plans = load_plans + @contract_amp = contract_amp + @power_usage = power_usage + end + + def show_plans + plans.map { |plan| plan.available?(contract_amp)? plan.plan_with_price(contract_amp, power_usage) : nil }.compact + end + + private + + def load_plans + load_json.map {|data| Plan.new( + name: data['name'], + provider_name: data['provider_name'], + basic_prices: data['basic_price'], + pay_per_use_prices: data['pay_per_use_price'] + )} + end + + def load_json + json_file_path = File.expand_path(JSON_FILE_PATH, __dir__) + JSON.load(File.open(json_file_path)) + end +end diff --git a/challengeA/okamoto/lib/simulator.rb b/challengeA/okamoto/lib/simulator.rb index e28cfb6d3..d48034eb3 100644 --- a/challengeA/okamoto/lib/simulator.rb +++ b/challengeA/okamoto/lib/simulator.rb @@ -1,4 +1,4 @@ -require './lib/plan' +require './lib/plans' class Simulator attr_reader :contract_amp, :power_usage, :plans @@ -6,7 +6,7 @@ class Simulator def initialize(contract_amp, power_usage) @contract_amp = contract_amp @power_usage = power_usage - @plans = Plan.new(contract_amp, power_usage) + @plans = Plans.new(contract_amp, power_usage) end def simulate diff --git a/challengeA/okamoto/spec/plan_spec.rb b/challengeA/okamoto/spec/plan_spec.rb index 9f3a061e8..2c05fad09 100644 --- a/challengeA/okamoto/spec/plan_spec.rb +++ b/challengeA/okamoto/spec/plan_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -RSpec.describe Plan do +RSpec.describe Plans do TEPCO = '東京電力エナジーパートナー' TEPCO_PLAN1 = '従量電灯B' LOOOP = 'Looopでんき' @@ -11,7 +11,7 @@ JXTG_PLAN1 = '従量電灯Bたっぷりプラン' describe '#show_plans' do - let(:plans) { Plan.new(amp, power) } + let(:plans) { Plans.new(amp, power) } let(:tepco_plan1_price) { plans.show_plans.find {|plan| plan[:provider_name] == TEPCO && plan[:plan_name] == TEPCO_PLAN1 }[:price] } let(:looop_plan1_price) { plans.show_plans.find {|plan| plan[:provider_name] == LOOOP && plan[:plan_name] == LOOOP_PLAN1 }[:price] } let(:tokyogas_plan1_price) { plans.show_plans.find {|plan| plan[:provider_name] == TOKYOGAS && plan[:plan_name] == TOKYOGAS_PLAN1 }[:price] } From 2efa0199f425ea57000230bf2a741f655e90fe1e Mon Sep 17 00:00:00 2001 From: masaki okamoto Date: Mon, 21 Jun 2021 17:09:02 +0900 Subject: [PATCH 11/12] =?UTF-8?q?spec=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E5=90=8D=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- challengeA/okamoto/spec/{plan_spec.rb => plans_spec.rb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename challengeA/okamoto/spec/{plan_spec.rb => plans_spec.rb} (100%) diff --git a/challengeA/okamoto/spec/plan_spec.rb b/challengeA/okamoto/spec/plans_spec.rb similarity index 100% rename from challengeA/okamoto/spec/plan_spec.rb rename to challengeA/okamoto/spec/plans_spec.rb From 3d2a545da64717756800ac05142741db76f6ea28 Mon Sep 17 00:00:00 2001 From: masaki okamoto Date: Mon, 21 Jun 2021 17:10:13 +0900 Subject: [PATCH 12/12] =?UTF-8?q?main=E3=81=AEtop=E3=83=AC=E3=83=99?= =?UTF-8?q?=E3=83=AB=E3=81=A7=E3=81=AEreturn=E3=81=AF=E3=82=84=E3=82=81?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- challengeA/okamoto/main.rb | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/challengeA/okamoto/main.rb b/challengeA/okamoto/main.rb index 4aede8bba..729a5e692 100644 --- a/challengeA/okamoto/main.rb +++ b/challengeA/okamoto/main.rb @@ -22,14 +22,16 @@ simulator = Simulator.new(contract_amp, power_usage) plan_lists = simulator.simulate -return puts '条件に一致するプランはありません。' if plan_lists.empty? - -puts 'ご入力いただいた条件での見積もり結果は以下の通りです。' -puts "契約アンペア:#{contract_amp}(A), 電力使用量:#{power_usage}(kwh)" -puts '================================================' -plan_lists.each do |plan| - puts "プロバイダー名:#{plan[:provider_name]}" - puts "プラン名:#{plan[:plan_name]}" - puts "月額料金:#{plan[:price]}円" +if plan_lists.empty? + puts '条件に一致するプランはありません。' +else + puts 'ご入力いただいた条件での見積もり結果は以下の通りです。' + puts "契約アンペア:#{contract_amp}(A), 電力使用量:#{power_usage}(kwh)" puts '================================================' + plan_lists.each do |plan| + puts "プロバイダー名:#{plan[:provider_name]}" + puts "プラン名:#{plan[:plan_name]}" + puts "月額料金:#{plan[:price]}円" + puts '================================================' + end end