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

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

Към профила на Красимир Георгиев

Резултати

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

Код

require 'bigdecimal'
require 'bigdecimal/util'
class ExchangeRate
class Unknown < RuntimeError
end
def initialize
@rates = {}
end
def set(from_currency, to_currency, rate)
@rates[[from_currency, to_currency]] = rate
@rates[[to_currency, from_currency]] = 1 / rate
end
def get(from_currency, to_currency)
if (from_currency == to_currency)
1
else
@rates[[from_currency, to_currency]]
end
end
def convert(from_currency, to_currency, amount)
rate = get(from_currency, to_currency)
if rate.nil?
raise Unknown, "Unknown exchange rate requested"
end
amount * rate
end
end
class Money
include Comparable
class IncompatibleCurrencies < RuntimeError
end
attr_reader :amount, :currency
def initialize(amount, currency)
@amount = amount.round(2)
@currency = currency
end
def to_s
"#{"%.2f" % @amount} #@currency"
end
def in(currency, exchange_rate)
converted_amount = exchange_rate.convert(@currency, currency, @amount)
Money.new(converted_amount, currency)
end
def *(other)
if other.is_a?(Numeric)
Money.new(@amount * other, @currency)
else
raise ArgumentError, "Money can be multiplied only by numbers."
end
end
def /(other)
if other.is_a?(Numeric)
Money.new(@amount / other, @currency)
else
raise ArgumentError, "Money can be divided only by numbers."
end
end
def +(other)
if other.is_a?(Money)
if compatible?(other)
Money.new(amount + other.amount, currency)
else
raise IncompatibleCurrencies, "Money can be added only if the currencies match"
end
else
raise ArgumentError, "Money can only be added to another money"
end
end
def -(other)
if other.is_a?(Money)
if compatible?(other)
Money.new(amount - other.amount, currency)
else
raise IncompatibleCurrencies, "Money can be subtracted only if the currencies match"
end
else
raise ArgumentError, "Money can only be subtracted from another money"
end
end
def compatible?(other)
other.is_a?(Money) and currency == other.currency
end
def <=>(other)
if other.is_a?(Money)
if compatible?(other)
amount <=> other.amount
else
raise IncompatibleCurrencies, "For money comparision the currencies should match"
end
else
raise ArgumentError, "Money can only be compared with other money"
end
end
end

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

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

Failures:

  1) Money arithmetic allows / with a numeric
     Failure/Error: result.amount.should eq bucks.amount.public_send(operation, numeric)
       
       expected: #<BigDecimal:9aa5664,'0.1190476190 47619048E0',18(36)>
            got: #<BigDecimal:9aa5790,'0.12E0',9(36)>
       
       (compared using ==)
     # /tmp/d20130203-23049-ovlgg4/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 comparison works when currencies are the same
     Failure/Error: (a < b).should be_true
       expected: true value
            got: false
     # /tmp/d20130203-23049-ovlgg4/spec.rb:181: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 comparison works for equality when currencies are the same
     Failure/Error: (Money.new('12.45'.to_d, :BGN) == Money.new('12.451'.to_d, :BGN)).should be_false
       expected: false value
            got: true
     # /tmp/d20130203-23049-ovlgg4/spec.rb:190: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-ovlgg4/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-ovlgg4/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.05838 seconds
47 examples, 5 failures

Failed examples:

rspec /tmp/d20130203-23049-ovlgg4/spec.rb:119 # Money arithmetic allows / with a numeric
rspec /tmp/d20130203-23049-ovlgg4/spec.rb:168 # Money comparison works when currencies are the same
rspec /tmp/d20130203-23049-ovlgg4/spec.rb:188 # Money comparison works for equality when currencies are the same
rspec /tmp/d20130203-23049-ovlgg4/spec.rb:194 # Money comparison with == raises ArgumentError when comparing with other objects
rspec /tmp/d20130203-23049-ovlgg4/spec.rb:200 # Money comparison with == raises IncompatibleCurrencies when currencies differ

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

Красимир обнови решението на 12.01.2013 19:53 (преди около 12 години)

+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class ExchangeRate
+ class Unknown < RuntimeError
+ end
+
+ def initialize
+ @rates = {}
+ end
+
+ def set(from_currency, to_currency, rate)
+ @rates[[from_currency, to_currency]] = rate
+ @rates[[to_currency, from_currency]] = 1 / rate
+ end
+
+ def get(from_currency, to_currency)
+ if (from_currency == to_currency)
+ 1
+ else
+ @rates[[from_currency, to_currency]]
+ end
+ end
+
+ def convert(from_currency, to_currency, amount)
+ rate = get(from_currency, to_currency)
+ if rate.nil?
+ raise Unknown, "Unknown exchange rate requested"
+ end
+ amount * rate
+ end
+end
+
+class Money
+ include Comparable
+
+ class IncompatibleCurrencies < RuntimeError
+ end
+
+ attr_reader :amount, :currency
+
+ def initialize(amount, currency)
+ @amount = amount.round(2)
+ @currency = currency
+ end
+
+ def to_s
+ "#{"%.2f" % @amount} #@currency"
+ end
+
+ def in(currency, exchange_rate)
+ converted_amount = exchange_rate.convert(@currency, currency, @amount)
+ Money.new(converted_amount, currency)
+ end
+
+ def *(other)
+ if other.is_a?(Numeric)
+ Money.new(@amount * other, @currency)
+ else
+ raise ArgumentError, "Money can be multiplied only by numbers."
+ end
+ end
+
+ def /(other)
+ if other.is_a?(Numeric)
+ Money.new(@amount / other, @currency)
+ else
+ raise ArgumentError, "Money can be divided only by numbers."
+ end
+ end
+
+ def +(other)
+ if other.is_a?(Money)
+ if compatible?(other)
+ Money.new(amount + other.amount, currency)
+ else
+ raise IncompatibleCurrencies, "Money can be added only if the currencies match"
+ end
+ else
+ raise ArgumentError, "Money can only be added to another money"
+ end
+ end
+
+ def -(other)
+ if other.is_a?(Money)
+ if compatible?(other)
+ Money.new(amount - other.amount, currency)
+ else
+ raise IncompatibleCurrencies, "Money can be subtracted only if the currencies match"
+ end
+ else
+ raise ArgumentError, "Money can only be subtracted from another money"
+ end
+ end
+
+ def compatible?(other)
+ other.is_a?(Money) and currency == other.currency
+ end
+
+ def <=>(other)
+ if other.is_a?(Money)
+ if compatible?(other)
+ amount <=> other.amount
+ else
+ raise IncompatibleCurrencies, "For money comparision the currencies should match"
+ end
+ else
+ raise ArgumentError, "Money can only be compared with other money"
+ end
+ end
+end