Решение на Шеста задача от Петко Борджуков

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

Към профила на Петко Борджуков

Резултати

  • 4 точки от тестове
  • 0 бонус точки
  • 4 точки общо
  • 34 успешни тест(а)
  • 13 неуспешни тест(а)

Код

require 'bigdecimal'
require 'bigdecimal/util'
class ExchangeRate
class ExchangeRateUnknown < RuntimeError
end
def initialize
@rates = {}
end
def set(from_currency, to_currency, rate)
@rates[from_currency] = {to_currency => rate.to_d, from_currency => 1.to_d}
@rates[to_currency] = {from_currency => 1/(rate.to_d), to_currency => 1.to_d}
end
def get(from_currency, to_currency)
raise ExchangeRateUnknown unless @rates.include? from_currency and @rates.include? to_currency
@rates[from_currency][to_currency]
end
def convert(from_currency, to_currency, amount)
amount.to_d * get(from_currency, to_currency)
end
end
class Money
attr_reader :amount, :currency
class IncompatibleCurrencies < StandardError
end
def initialize(amount, currency)
@amount, @currency = amount.to_d, currency
end
def to_s
"%.2f %s" % [@amount, @currency]
end
def in(other_currency, exchange_rate)
converted_amount = exchange_rate.convert @currency, other_currency, @amount
Money.new converted_amount, other_currency
end
undef_method :==, :equal?, :!=
def method_missing(method, *args, &block)
if %w(<=> == equal? < > <= >= !=).include? method.to_s
enforce_comparisson_conditions_for args.first
@amount.send method, args.first.amount
else super
end
end
def *(multiplier)
enforce_multiplication_conditions_for multiplier
Money.new @amount * multiplier.to_d, @currency
end
def /(denominator)
self * (1 / denominator.to_d)
end
def +(addend)
enforce_addition_conditions_for addend
case addend
when Numeric then Money.new @amount + addend.to_d, @currency
when Money then self + addend.amount
end
end
def -@
Money.new(-@amount, @currency)
end
def -(subtrahend)
self + (-subtrahend)
end
private
def enforce_multiplication_conditions_for(object)
raise ArgumentError unless object.is_a? Numeric
end
def enforce_addition_conditions_for(object)
raise ArgumentError unless object.is_a? Numeric or object.kind_of? Money
raise IncompatibleCurrencies if object.kind_of? Money and object.currency != @currency
end
def enforce_comparisson_conditions_for(object)
raise ArgumentError unless object.kind_of? Money
raise IncompatibleCurrencies unless object.currency == @currency
end
end

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

▸ Покажи лога

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

Петко обнови решението на 13.01.2013 14:27 (преди над 12 години)

▸ Покажи разликите
+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class ExchangeRate
+ class ExchangeRateUnknown < RuntimeError
+ end
+
+ def initialize
+ @rates = {}
+ end
+
+ def set(from_currency, to_currency, rate)
+ @rates[from_currency] = {to_currency => rate.to_d, from_currency => 1.to_d}
+ @rates[to_currency] = {to_currency => 1/(rate.to_d), to_currency => 1.to_d}
+ end
+
+ def get(from_currency, to_currency)
+ raise ExchangeRateUnknown unless @rates.include? from_currency and @rates.include? to_currency
+ @rates[from_currency][to_currency]
+ end
+
+ def convert(from_currency, to_currency, amount)
+ amount.to_d * get(from_currency, to_currency)
+ end
+end
+
+class Money
+ attr_reader :amount, :currency
+
+ class IncompatibleCurrencies < StandardError
+ end
+
+ def initialize(amount, currency)
+ @amount, @currency = amount.to_d, currency
+ end
+
+ def to_s
+ "%.2f %s" % [@amount, @currency]
+ end
+
+ def in(other_currency, exchange_rate)
+ converted_amount = exchange_rate.convert @currency, other_currency, @amount
+ Money.new converted_amount, other_currency
+ end
+
+ undef_method :==, :equal?, :!=
+ def method_missing(method, *args, &block)
+ if %w(<=> == equal? < > <= >= !=).include? method.to_s
+ raise ArgumentError unless args.first.kind_of? Money
+ raise IncompatibleCurrencies unless args.first.currency == @currency
+ @amount.send method, args.first.amount
+ end
+ end
+
+ def *(multiplier)
+ raise ArgumentError unless multiplier.is_a? Numeric
+ Money.new @amount * multiplier.to_d, @currency
+ end
+
+ def /(denominator)
+ self * (1 / denominator.to_d)
+ end
+
+ def +(addend)
+ if addend.is_a? Numeric then add_numeric addend
+ elsif addend.kind_of? Money then add_money addend
+ else raise ArgumentError
+ end
+ end
+
+ def -@
+ Money.new(-@amount, @currency)
+ end
+
+ def -(subtrahend)
+ self + (-subtrahend)
+ end
+
+ private
+ def add_numeric(addend)
+ Money.new @amount + addend.to_d, @currency
+ end
+
+ def add_money(addend)
+ raise IncompatibleCurrencies unless @currency == addend.currency
+ add_numeric addend.amount
+ end
+end

Петко обнови решението на 13.01.2013 14:53 (преди над 12 години)

▸ Покажи разликите
require 'bigdecimal'
require 'bigdecimal/util'
class ExchangeRate
class ExchangeRateUnknown < RuntimeError
end
def initialize
@rates = {}
end
def set(from_currency, to_currency, rate)
@rates[from_currency] = {to_currency => rate.to_d, from_currency => 1.to_d}
@rates[to_currency] = {to_currency => 1/(rate.to_d), to_currency => 1.to_d}
end
def get(from_currency, to_currency)
raise ExchangeRateUnknown unless @rates.include? from_currency and @rates.include? to_currency
@rates[from_currency][to_currency]
end
def convert(from_currency, to_currency, amount)
amount.to_d * get(from_currency, to_currency)
end
end
class Money
attr_reader :amount, :currency
class IncompatibleCurrencies < StandardError
end
def initialize(amount, currency)
@amount, @currency = amount.to_d, currency
end
def to_s
"%.2f %s" % [@amount, @currency]
end
def in(other_currency, exchange_rate)
converted_amount = exchange_rate.convert @currency, other_currency, @amount
Money.new converted_amount, other_currency
end
undef_method :==, :equal?, :!=
def method_missing(method, *args, &block)
if %w(<=> == equal? < > <= >= !=).include? method.to_s
- raise ArgumentError unless args.first.kind_of? Money
- raise IncompatibleCurrencies unless args.first.currency == @currency
+ enforce_comparisson_conditions_for args.first
@amount.send method, args.first.amount
+ else super
end
end
def *(multiplier)
- raise ArgumentError unless multiplier.is_a? Numeric
+ enforce_multiplication_conditions_for multiplier
Money.new @amount * multiplier.to_d, @currency
end
def /(denominator)
self * (1 / denominator.to_d)
end
def +(addend)
- if addend.is_a? Numeric then add_numeric addend
- elsif addend.kind_of? Money then add_money addend
- else raise ArgumentError
+ enforce_addition_conditions_for addend
+ case addend
+ when Numeric then Money.new @amount + addend.to_d, @currency
+ when Money then self + addend.amount
end
end
def -@
Money.new(-@amount, @currency)
end
def -(subtrahend)
self + (-subtrahend)
end
private
- def add_numeric(addend)
- Money.new @amount + addend.to_d, @currency
+
+ def enforce_multiplication_conditions_for(object)
+ raise ArgumentError unless object.is_a? Numeric
end
- def add_money(addend)
- raise IncompatibleCurrencies unless @currency == addend.currency
- add_numeric addend.amount
+ def enforce_addition_conditions_for(object)
+ raise ArgumentError unless object.is_a? Numeric or object.kind_of? Money
+ raise IncompatibleCurrencies if object.kind_of? Money and object.currency != @currency
+ end
+
+ def enforce_comparisson_conditions_for(object)
+ raise ArgumentError unless object.kind_of? Money
+ raise IncompatibleCurrencies unless object.currency == @currency
end
end

Петко обнови решението на 13.01.2013 15:51 (преди над 12 години)

▸ Покажи разликите
require 'bigdecimal'
require 'bigdecimal/util'
class ExchangeRate
class ExchangeRateUnknown < RuntimeError
end
def initialize
@rates = {}
end
def set(from_currency, to_currency, rate)
@rates[from_currency] = {to_currency => rate.to_d, from_currency => 1.to_d}
- @rates[to_currency] = {to_currency => 1/(rate.to_d), to_currency => 1.to_d}
+ @rates[to_currency] = {from_currency => 1/(rate.to_d), to_currency => 1.to_d}
end
def get(from_currency, to_currency)
raise ExchangeRateUnknown unless @rates.include? from_currency and @rates.include? to_currency
@rates[from_currency][to_currency]
end
def convert(from_currency, to_currency, amount)
amount.to_d * get(from_currency, to_currency)
end
end
class Money
attr_reader :amount, :currency
class IncompatibleCurrencies < StandardError
end
def initialize(amount, currency)
@amount, @currency = amount.to_d, currency
end
def to_s
"%.2f %s" % [@amount, @currency]
end
def in(other_currency, exchange_rate)
converted_amount = exchange_rate.convert @currency, other_currency, @amount
Money.new converted_amount, other_currency
end
undef_method :==, :equal?, :!=
def method_missing(method, *args, &block)
if %w(<=> == equal? < > <= >= !=).include? method.to_s
enforce_comparisson_conditions_for args.first
@amount.send method, args.first.amount
else super
end
end
def *(multiplier)
enforce_multiplication_conditions_for multiplier
Money.new @amount * multiplier.to_d, @currency
end
def /(denominator)
self * (1 / denominator.to_d)
end
def +(addend)
enforce_addition_conditions_for addend
case addend
when Numeric then Money.new @amount + addend.to_d, @currency
when Money then self + addend.amount
end
end
def -@
Money.new(-@amount, @currency)
end
def -(subtrahend)
self + (-subtrahend)
end
private
def enforce_multiplication_conditions_for(object)
raise ArgumentError unless object.is_a? Numeric
end
def enforce_addition_conditions_for(object)
raise ArgumentError unless object.is_a? Numeric or object.kind_of? Money
raise IncompatibleCurrencies if object.kind_of? Money and object.currency != @currency
end
def enforce_comparisson_conditions_for(object)
raise ArgumentError unless object.kind_of? Money
raise IncompatibleCurrencies unless object.currency == @currency
end
end