Решение на Шеста задача от Камелия Пандаклиева

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

Към профила на Камелия Пандаклиева

Резултати

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

Код

require 'bigdecimal'
require 'bigdecimal/util'
class ExchangeRate
attr_accessor :rates
def initialize
@rates = {}
end
def add_rate(from_currency, to_currency, rate)
@rates[from_currency] ||= {}
@rates[from_currency].store to_currency, rate
end
def set(from_currency, to_currency, rate)
return if from_currency == to_currency
add_rate from_currency, to_currency, rate
rate = 1 / rate
add_rate to_currency, from_currency, rate
end
def get(from_currency, to_currency)
return 1 if from_currency == to_currency
if @rates.has_key? from_currency and @rates.has_key? to_currency
@rates[from_currency][to_currency]
else
nil
end
end
def convert(from_currency, to_currency, amount)
rate = get(from_currency, to_currency)
if rate
amount * rate
else
raise Unknown
end
end
def self.const_missing(error)
if error.to_s == "Unknown"
const_set error, Class.new(RuntimeError)
else
super
end
end
end
class Money
include Comparable
attr_reader :amount, :currency
def initialize(amount, currency)
@amount = amount
@currency = currency
end
def to_s
whole_part = amount.truncate.to_s
partial_part = (amount.frac.to_s.match /(?<=\.)(\d){,2}/).to_s
if partial_part.size == 0 then whole_part + ".00 " + @currency.to_s
elsif partial_part.size == 1 then whole_part + "." + partial_part + "0 " + @currency.to_s
else whole_part + "." + partial_part + " " + @currency.to_s
end
end
def in(currency, exchange_rate)
Money.new exchange_rate.convert(@currency, currency, @amount).to_d, currency
end
def +(other)
raise ArgumentError if not other.instance_of? Money
if @currency == other.currency
Money.new (@amount + other.amount), @currency
else
raise IncompatibleCurrencies
end
end
def -(other)
raise ArgumentError if not other.instance_of? Money
if @currency == other.currency
Money.new (@amount - other.amount), @currency
else
raise IncompatibleCurrencies
end
end
def *(number)
raise ArgumentError if not number.is_a? Numeric
Money.new (@amount * number), @currency
end
def /(number)
raise ArgumentError if not number.is_a? Numeric
Money.new (@amount / number), @currency
end
def <=>(other)
if other.instance_of? Money and @currency == other.currency then @amount <=> other.amount
elsif other.instance_of? Money then raise IncompatibleCurrencies
else raise ArgumentError
end
end
def self.const_missing(error)
if error.to_s == "IncompatibleCurrencies"
const_set error, Class.new(ArgumentError)
else
super
end
end
end

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

.....................................FF........

Failures:

  1) Money comparison with == raises ArgumentError when comparing with other objects
     Failure/Error: expect do
       expected ArgumentError but nothing was raised
     # /tmp/d20130203-23049-1f6dkqp/spec.rb:195: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 comparison with == raises IncompatibleCurrencies when currencies differ
     Failure/Error: expect do
       expected Money::IncompatibleCurrencies but nothing was raised
     # /tmp/d20130203-23049-1f6dkqp/spec.rb:201: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.05979 seconds
47 examples, 2 failures

Failed examples:

rspec /tmp/d20130203-23049-1f6dkqp/spec.rb:194 # Money comparison with == raises ArgumentError when comparing with other objects
rspec /tmp/d20130203-23049-1f6dkqp/spec.rb:200 # Money comparison with == raises IncompatibleCurrencies when currencies differ

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

Камелия обнови решението на 16.01.2013 07:16 (преди над 11 години)

+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class ExchangeRate
+ attr_accessor :rates
+
+ def initialize
+ @rates = {}
+ end
+
+ def add_rate(from_currency, to_currency, rate)
+ @rates[from_currency] ||= {}
+ @rates[from_currency].store to_currency, rate
+ end
+
+ def set(from_currency, to_currency, rate)
+ return if from_currency == to_currency
+ add_rate from_currency, to_currency, rate
+ rate = 1 / rate
+ add_rate to_currency, from_currency, rate
+ end
+
+ def get(from_currency, to_currency)
+ return 1 if from_currency == to_currency
+ if @rates.has_key? from_currency and @rates.has_key? to_currency
+ @rates[from_currency][to_currency]
+ else
+ nil
+ end
+ end
+
+ def convert(from_currency, to_currency, amount)
+ rate = get(from_currency, to_currency)
+ if rate
+ amount * rate
+ else
+ raise Unknown
+ end
+ end
+
+ def self.const_missing(error)
+ if error.to_s == "Unknown"
+ const_set error, Class.new(RuntimeError)
+ else
+ super
+ end
+ end
+end
+
+class Money
+ include Comparable
+
+ attr_reader :amount, :currency
+
+ def initialize(amount, currency)
+ @amount = amount
+ @currency = currency
+ end
+
+ def to_s
+ whole_part = amount.truncate.to_s
+ partial_part = (amount.frac.to_s.match /(?<=\.)(\d){,2}/).to_s
+ if partial_part.size == 0 then whole_part + ".00 " + @currency.to_s
+ elsif partial_part.size == 1 then whole_part + "." + partial_part + "0 " + @currency.to_s
+ else whole_part + "." + partial_part + " " + @currency.to_s
+ end
+ end
+
+ def in(currency, exchange_rate)
+ Money.new exchange_rate.convert(@currency, currency, @amount).to_d, currency
+ end
+
+ def +(other)
+ raise ArgumentError if not other.instance_of? Money
+ if @currency == other.currency
+ Money.new (@amount + other.amount), @currency
+ else
+ raise IncompatibleCurrencies
+ end
+ end
+
+ def -(other)
+ raise ArgumentError if not other.instance_of? Money
+ if @currency == other.currency
+ Money.new (@amount - other.amount), @currency
+ else
+ raise IncompatibleCurrencies
+ end
+ end
+
+ def *(number)
+ raise ArgumentError if not number.is_a? Numeric
+ Money.new (@amount * number), @currency
+ end
+
+ def /(number)
+ raise ArgumentError if not number.is_a? Numeric
+ Money.new (@amount / number), @currency
+ end
+
+ def <=>(other)
+ if other.instance_of? Money and @currency == other.currency then @amount <=> other.amount
+ elsif other.instance_of? Money then raise IncompatibleCurrencies
+ else raise ArgumentError
+ end
+ end
+
+ def self.const_missing(error)
+ if error.to_s == "IncompatibleCurrencies"
+ const_set error, Class.new(ArgumentError)
+ else
+ super
+ end
+ end
+end