Решение на Шеста задача от Светлана Величкова

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

Към профила на Светлана Величкова

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 42 успешни тест(а)
  • 5 неуспешни тест(а)

Код

require 'bigdecimal'
require 'bigdecimal/util'
class ExchangeRate
attr_accessor :rates
def initialize()
@rates = {}
end
def set(from_currency, to_currency, rate)
rates[[from_currency, to_currency]]=rate
rates[[to_currency, from_currency]]=1/rate
if from_currency == to_currency
rates[[to_currency, from_currency]]=1
end
end
def get(from_currency, to_currency)
rates[[from_currency, to_currency]]
end
def convert(from_currency, to_currency, amount)
rate = rates[[from_currency, to_currency]]
if !rate
raise Unknown
end
amount*rate
end
class Unknown < RuntimeError
def exception
end
end
end
class Money
include Comparable
attr_accessor :amount, :currency
def initialize(amount, currency)
@amount = amount.to_d
@currency = currency
end
def to_s
s = amount.ceil(2).to_s(' f')
if s.index('.')<s.length
s = s + '0'
end
s = s[1..s.index('.')+2] + ' ' + currency.to_s
end
def in(currency, exchange_rate)
new_amount = exchange_rate.convert(self.currency, currency, amount)
Money.new new_amount, currency
end
def *(number)
if ! number.kind_of?(Numeric)
raise ArgumentError
end
Money.new amount*number, currency
end
def /(number)
if ! number.kind_of?(Numeric)
raise ArgumentError
end
Money.new amount/number, currency
end
def +(money)
if !money.instance_of?(Money)
raise ArgumentError
end
if currency != money.currency
raise IncompatibleCurrencies
end
Money.new amount + money.amount, currency
end
def -(money)
if !money.instance_of?(Money)
raise ArgumentError
end
if currency != money.currency
raise IncompatibleCurrencies
end
Money.new amount - money.amount, currency
end
def <=> (other)
if !other.instance_of?(Money) then raise ArgumentError end
if other.currency != currency then raise IncompatibleCurrencies end
if amount == other.amount then return 0 end
if amount > other.amount then return 1 end
-1
end
class IncompatibleCurrencies < StandardError
def exception
end
end
end

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

.......F....F....F...................FF........

Failures:

  1) ExchangeRate#get always returns 1 as the exchange rate between two identical currencies
     Failure/Error: rate.get(:JPY, :JPY).should eq 1.to_d
       
       expected: #<BigDecimal:95ac338,'0.1E1',9(36)>
            got: nil
       
       (compared using ==)
     # /tmp/d20130203-23049-136firo/spec.rb:45:in `block (3 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) ExchangeRate#convert works for identical currencies without defining any rates
     Failure/Error: rate.convert(:JPY, :JPY, 123.to_d).should eq 123.to_d
     ExchangeRate::Unknown:
       ExchangeRate::Unknown
     # /tmp/d20130203-23049-136firo/solution.rb:26:in `convert'
     # /tmp/d20130203-23049-136firo/spec.rb:72:in `block (3 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)>'

  3) Money convertion does not change the amount if the same currency is passed
     Failure/Error: Money.new(5.to_d, :EUR).in(:EUR, ExchangeRate.new).amount.should eq 5.to_d
     ExchangeRate::Unknown:
       ExchangeRate::Unknown
     # /tmp/d20130203-23049-136firo/solution.rb:26:in `convert'
     # /tmp/d20130203-23049-136firo/solution.rb:58:in `in'
     # /tmp/d20130203-23049-136firo/spec.rb:107:in `block (3 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)>'

  4) Money comparison with == raises ArgumentError when comparing with other objects
     Failure/Error: expect do
       expected ArgumentError but nothing was raised
     # /tmp/d20130203-23049-136firo/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)>'

  5) Money comparison with == raises IncompatibleCurrencies when currencies differ
     Failure/Error: expect do
       expected Money::IncompatibleCurrencies but nothing was raised
     # /tmp/d20130203-23049-136firo/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.08625 seconds
47 examples, 5 failures

Failed examples:

rspec /tmp/d20130203-23049-136firo/spec.rb:44 # ExchangeRate#get always returns 1 as the exchange rate between two identical currencies
rspec /tmp/d20130203-23049-136firo/spec.rb:71 # ExchangeRate#convert works for identical currencies without defining any rates
rspec /tmp/d20130203-23049-136firo/spec.rb:106 # Money convertion does not change the amount if the same currency is passed
rspec /tmp/d20130203-23049-136firo/spec.rb:194 # Money comparison with == raises ArgumentError when comparing with other objects
rspec /tmp/d20130203-23049-136firo/spec.rb:200 # Money comparison with == raises IncompatibleCurrencies when currencies differ

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

Светлана обнови решението на 16.01.2013 16:40 (преди над 11 години)

+ require 'bigdecimal'
+ require 'bigdecimal/util'
+
+ class ExchangeRate
+ attr_accessor :rates
+
+ def initialize()
+ @rates = {}
+ end
+
+ def set(from_currency, to_currency, rate)
+ rates[[from_currency, to_currency]]=rate
+ rates[[to_currency, from_currency]]=1/rate
+ if from_currency == to_currency
+ rates[[to_currency, from_currency]]=1
+ end
+ end
+
+ def get(from_currency, to_currency)
+ rates[[from_currency, to_currency]]
+ end
+
+ def convert(from_currency, to_currency, amount)
+ rate = rates[[from_currency, to_currency]]
+ if !rate
+ raise Unknown
+ end
+ amount*rate
+ end
+
+ class Unknown < RuntimeError
+
+ def exception
+ end
+
+ end
+
+ end
+
+ class Money
+ include Comparable
+ attr_accessor :amount, :currency
+
+ def initialize(amount, currency)
+ @amount = amount.to_d
+ @currency = currency
+ end
+
+ def to_s
+ s = amount.ceil(2).to_s(' f')
+ if s.index('.')<s.length
+ s = s + '0'
+ end
+ s = s[1..s.index('.')+2] + ' ' + currency.to_s
+ end
+
+ def in(currency, exchange_rate)
+ new_amount = exchange_rate.convert(self.currency, currency, amount)
+ Money.new new_amount, currency
+ end
+
+ def *(number)
+ if ! number.kind_of?(Numeric)
+ raise ArgumentError
+ end
+ Money.new amount*number, currency
+ end
+
+ def /(number)
+ if ! number.kind_of?(Numeric)
+ raise ArgumentError
+ end
+ Money.new amount/number, currency
+ end
+
+ def +(money)
+ if !money.instance_of?(Money)
+ raise ArgumentError
+ end
+ if currency != money.currency
+ raise IncompatibleCurrencies
+ end
+ Money.new amount + money.amount, currency
+ end
+
+ def -(money)
+ if !money.instance_of?(Money)
+ raise ArgumentError
+ end
+ if currency != money.currency
+ raise IncompatibleCurrencies
+ end
+ Money.new amount - money.amount, currency
+ end
+
+ def <=> (other)
+ if !other.instance_of?(Money) then raise ArgumentError end
+ if other.currency != currency then raise IncompatibleCurrencies end
+ if amount == other.amount then return 0 end
+ if amount > other.amount then return 1 end
+ -1
+ end
+
+ class IncompatibleCurrencies < StandardError
+
+ def exception
+ end
+
+ end
+
+ end