Решение на Шеста задача от Кирчо Кирев

Обратно към всички решения

Към профила на Кирчо Кирев

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 45 успешни тест(а)
  • 2 неуспешни тест(а)

Код

require 'bigdecimal'
require 'bigdecimal/util'
class Course
attr_reader :from_currency, :to_currency
def initialize(from_currency, to_currency)
@from_currency = from_currency
@to_currency = to_currency
end
def ==(other)
@from_currency == other.from_currency and
@to_currency == other.to_currency
end
alias eql? ==
def hash
[@from_currency, @to_currency].hash
end
end
class ExchangeRate
def initialize
@exchange = {}
end
def set(from_currency, to_currency, rate)
@exchange[Course.new(from_currency, to_currency)] = rate
@exchange[Course.new(to_currency, from_currency)] = 1 / rate
end
def get(from_currency, to_currency)
return '1'.to_d if from_currency == to_currency
@exchange[Course.new(from_currency, to_currency)]
end
def convert(from_currency, to_currency, amount)
rate = get from_currency, to_currency
rate ? amount * rate : (raise Unknown.new)
end
private
class Unknown < RuntimeError
end
end
class Money
include Comparable
attr_reader :amount, :currency
def initialize(amount, currency)
@amount = amount
@currency = currency
end
def to_s
"%.2f #{currency}" % amount
end
def in(currency, exchange_rate)
Money.new exchange_rate.convert(@currency, currency, @amount), currency
end
def +(other)
compatible_money other
Money.new @amount + other.amount, @currency
end
def -@
Money.new -@amount, @currency
end
def -(other)
self + (-other)
end
def <=>(other)
compatible_money other
@amount <=> other.amount
end
def ==(other)
compatible_money other
@amount == other.amount
end
def *(other)
calculate_if_numeric :mult, other
end
def /(other)
calculate_if_numeric :div, other
end
private
def calculate_if_numeric(operation, other)
raise ArgumentError unless other.is_a? Numeric
Money.new @amount.send(operation, other, 10), @currency
end
def compatible_money(other)
raise ArgumentError unless other.is_a? Money
raise IncompatibleCurrencies.new unless @currency == other.currency
end
class IncompatibleCurrencies < ArgumentError
end
end

Лог от изпълнението

.....................F........F................

Failures:

  1) Money arithmetic allows / with a numeric
     Failure/Error: result.amount.should eq bucks.amount.public_send(operation, numeric)
       
       expected: #<BigDecimal:91caa80,'0.1190476190 47619048E0',18(36)>
            got: #<BigDecimal:91cb19c,'0.119047619E0',9(45)>
       
       (compared using ==)
     # /tmp/d20130203-23049-kg9uit/spec.rb:125:in `block (4 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) Money arithmetic - with other objects raises an ArgumentError
     Failure/Error: expect do
       expected ArgumentError, got #<NoMethodError: undefined method `-@' for "foobar":String>
     # /tmp/d20130203-23049-kg9uit/spec.rb:160:in `block (4 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/homework/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.0759 seconds
47 examples, 2 failures

Failed examples:

rspec /tmp/d20130203-23049-kg9uit/spec.rb:119 # Money arithmetic allows / with a numeric
rspec /tmp/d20130203-23049-kg9uit/spec.rb:159 # Money arithmetic - with other objects raises an ArgumentError

История (3 версии и 0 коментара)

Кирчо обнови решението на 12.01.2013 20:47 (преди почти 12 години)

+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class CurrencyRate
+ attr_accessor :currency, :rate
+
+ def initialize(currency, rate)
+ @currency = currency
+ @rate = rate
+ end
+
+ def ==(other)
+ self.currency == other.currency
+ end
+
+ alias eql? ==
+
+ def hash
+ @currency.hash
+ end
+end
+
+class ExchangeRate
+ def initialize
+ @exchange = Hash.new { |hash, key| hash[key] = [CurrencyRate.new(key, '1'.to_d)] }
+ end
+
+ def set(from_currency, to_currency, rate)
+ if from_currency != to_currency
+ set_exchange_rate from_currency, to_currency, rate
+ set_exchange_rate to_currency, from_currency, 1 / rate
+ end
+ end
+
+ def get(from_currency, to_currency)
+ currency_rate = @exchange[from_currency].detect do |single_rate|
+ single_rate.currency == to_currency
+ end
+ currency_rate ? currency_rate.rate : nil
+ end
+
+ def convert(from_currency, to_currency, amount)
+ rate = get from_currency, to_currency
+ rate ? amount * rate : (raise Unknown.new)
+ end
+
+ private
+
+ def set_exchange_rate(from_currency, to_currency, rate)
+ @exchange[from_currency] =
+ [CurrencyRate.new(to_currency, rate)] | @exchange[from_currency]
+ end
+
+ class Unknown < RuntimeError
+ end
+end
+
+class Money
+ include Comparable
+ attr_reader :amount, :currency
+
+ def initialize(amount, currency)
+ @amount = amount
+ @currency = currency
+ end
+
+ def to_s
+ "%.2f #{currency}" % amount
+ end
+
+ def in(currency, exchange_rate)
+ Money.new exchange_rate.convert(@currency, currency, @amount), currency
+ end
+
+ def +(other)
+ compatible_money other
+ Money.new self.amount + other.amount, @currency
+ end
+
+ def <=>(other)
+ compatible_money other
+ self.amount <=> other.amount
+ end
+
+ def -@
+ Money.new -@amount, @currency
+ end
+
+ def -(other)
+ self + (-other)
+ end
+
+ def *(other)
+ calculate_if_numeric :mult, other
+ end
+
+ def /(other)
+ calculate_if_numeric :div, other
+ end
+
+ private
+
+ def calculate_if_numeric(operation, other)
+ raise ArgumentError unless other.is_a? Numeric
+ Money.new @amount.send(operation, other, 10), @currency
+ end
+
+ def compatible_money(other)
+ raise ArgumentError unless other.is_a? Money
+ raise IncompatibleCurrencies.new unless self.currency == other.currency
+ end
+
+ class IncompatibleCurrencies < ArgumentError
+ end
+end

Кирчо обнови решението на 13.01.2013 14:37 (преди почти 12 години)

require 'bigdecimal'
require 'bigdecimal/util'
-class CurrencyRate
- attr_accessor :currency, :rate
+class Course
+ attr_reader :from_currency, :to_currency
- def initialize(currency, rate)
- @currency = currency
- @rate = rate
+ def initialize(from_currency, to_currency)
+ @from_currency = from_currency
+ @to_currency = to_currency
end
def ==(other)
- self.currency == other.currency
+ @from_currency == other.from_currency and
+ @to_currency == other.to_currency
end
alias eql? ==
def hash
- @currency.hash
+ [@from_currency, @to_currency].hash
end
end
class ExchangeRate
def initialize
- @exchange = Hash.new { |hash, key| hash[key] = [CurrencyRate.new(key, '1'.to_d)] }
+ @exchange = {}
end
def set(from_currency, to_currency, rate)
- if from_currency != to_currency
- set_exchange_rate from_currency, to_currency, rate
- set_exchange_rate to_currency, from_currency, 1 / rate
- end
+ @exchange[Course.new(from_currency, to_currency)] = rate
+ @exchange[Course.new(to_currency, from_currency)] = 1 / rate
end
def get(from_currency, to_currency)
- currency_rate = @exchange[from_currency].detect do |single_rate|
- single_rate.currency == to_currency
- end
- currency_rate ? currency_rate.rate : nil
+ return '1'.to_d if from_currency == to_currency
+ @exchange[Course.new(from_currency, to_currency)]
end
def convert(from_currency, to_currency, amount)
rate = get from_currency, to_currency
rate ? amount * rate : (raise Unknown.new)
end
private
- def set_exchange_rate(from_currency, to_currency, rate)
- @exchange[from_currency] =
- [CurrencyRate.new(to_currency, rate)] | @exchange[from_currency]
- end
-
class Unknown < RuntimeError
end
end
class Money
include Comparable
attr_reader :amount, :currency
def initialize(amount, currency)
@amount = amount
@currency = currency
end
def to_s
"%.2f #{currency}" % amount
end
def in(currency, exchange_rate)
Money.new exchange_rate.convert(@currency, currency, @amount), currency
end
def +(other)
compatible_money other
- Money.new self.amount + other.amount, @currency
+ Money.new @amount + other.amount, @currency
end
def <=>(other)
compatible_money other
- self.amount <=> other.amount
+ @amount <=> other.amount
end
def -@
Money.new -@amount, @currency
end
def -(other)
self + (-other)
end
def *(other)
calculate_if_numeric :mult, other
end
def /(other)
calculate_if_numeric :div, other
end
private
def calculate_if_numeric(operation, other)
raise ArgumentError unless other.is_a? Numeric
Money.new @amount.send(operation, other, 10), @currency
end
def compatible_money(other)
raise ArgumentError unless other.is_a? Money
- raise IncompatibleCurrencies.new unless self.currency == other.currency
+ raise IncompatibleCurrencies.new unless @currency == other.currency
end
class IncompatibleCurrencies < ArgumentError
end
end

Кирчо обнови решението на 16.01.2013 13:40 (преди почти 12 години)

require 'bigdecimal'
require 'bigdecimal/util'
class Course
attr_reader :from_currency, :to_currency
def initialize(from_currency, to_currency)
@from_currency = from_currency
@to_currency = to_currency
end
def ==(other)
@from_currency == other.from_currency and
@to_currency == other.to_currency
end
alias eql? ==
def hash
[@from_currency, @to_currency].hash
end
end
class ExchangeRate
def initialize
@exchange = {}
end
def set(from_currency, to_currency, rate)
@exchange[Course.new(from_currency, to_currency)] = rate
@exchange[Course.new(to_currency, from_currency)] = 1 / rate
end
def get(from_currency, to_currency)
return '1'.to_d if from_currency == to_currency
@exchange[Course.new(from_currency, to_currency)]
end
def convert(from_currency, to_currency, amount)
rate = get from_currency, to_currency
rate ? amount * rate : (raise Unknown.new)
end
private
class Unknown < RuntimeError
end
end
class Money
include Comparable
attr_reader :amount, :currency
def initialize(amount, currency)
- @amount = amount
+ @amount = amount
@currency = currency
end
def to_s
"%.2f #{currency}" % amount
end
def in(currency, exchange_rate)
Money.new exchange_rate.convert(@currency, currency, @amount), currency
end
def +(other)
compatible_money other
Money.new @amount + other.amount, @currency
end
- def <=>(other)
- compatible_money other
- @amount <=> other.amount
- end
-
def -@
Money.new -@amount, @currency
end
def -(other)
self + (-other)
+ end
+
+ def <=>(other)
+ compatible_money other
+ @amount <=> other.amount
+ end
+
+ def ==(other)
+ compatible_money other
+ @amount == other.amount
end
def *(other)
calculate_if_numeric :mult, other
end
def /(other)
calculate_if_numeric :div, other
end
private
def calculate_if_numeric(operation, other)
raise ArgumentError unless other.is_a? Numeric
Money.new @amount.send(operation, other, 10), @currency
end
def compatible_money(other)
raise ArgumentError unless other.is_a? Money
raise IncompatibleCurrencies.new unless @currency == other.currency
end
class IncompatibleCurrencies < ArgumentError
end
end