Решение на Шеста задача от Елена Миронова

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

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

Резултати

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

Код

require 'bigdecimal'
require 'bigdecimal/util'
class ExchangeRate
attr_accessor :rates
def initialize
@rates = []
end
def set(from_currency, to_currency, rate)
@rates << RateUnit.new(from_currency, to_currency, rate)
@rates << RateUnit.new(to_currency, from_currency, 1/rate)
end
def get(from_currency, to_currency)
@rates.each do |rate_unit|
if rate_unit.from_currency == from_currency and rate_unit.to_currency == to_currency
return rate_unit.rate
end
end
return nil
end
def convert(from_currency, to_currency, amount)
rate_unit = get(from_currency, to_currency)
raise Unknown.new('ExchangeRate::Unknown') if rate_unit == nil
return amount*rate_unit
end
end
class RateUnit
attr_accessor :from_currency, :to_currency, :rate
def initialize(from_currency, to_currency, rate)
@from_currency = from_currency
@to_currency = to_currency
@rate = rate
end
end
class Money
attr_accessor :amount, :currency
def initialize(amount, currency)
@amount = amount
@currency = currency
end
def to_s
sprintf("%.2f %s", @amount.to_f, @currency)
end
def in(currency, exchange_rate)
to_currency_amount = exchange_rate.convert(@currency, currency, @amount)
Money.new(to_currency_amount, currency)
end
def *(numeric_value)
Money.new(@amount*numeric_value, @currency)
end
def /(numeric_value)
Money.new(@amount/numeric_value, @currency)
end
def +(other_money)
return Money.new(@amount + other_money.amount, @currency) if @currency == other_money.currency
raise IncompatibleCurrencies.new('Money::IncompatibleCurrencies')
end
def -(other_money)
return Money.new(@amount - other_money.amount, @currency) if @currency == other_money.currency
raise IncompatibleCurrencies.new('Money::IncompatibleCurrencies')
end
def <=>(other_money)
check_compatibility(other_money)
return @amount <=> other_money.amount
end
def ==(other_money)
check_compatibility(other_money)
return @amount == other_money.amount
end
def <=(other_money)
check_compatibility(other_money)
return @amount <= other_money.amount
end
def >=(other_money)
check_compatibility(other_money)
return @amount >= other_money.amount
end
def check_compatibility(other_money)
raise ArgumentError if !other_money.is_a? Money
raise IncompatibleCurrencies if @currency != other_money.currency
end
end
class Unknown < RuntimeError
end
class IncompatibleCurrencies < RuntimeError
end

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

/tmp/d201...F....F..F.FF..F..FFFFF.....FF..FF..

Failures:

  1) ExchangeRate#set allows rates to be updated if called multiple times
     Failure/Error: expect do
       result should have been changed to #<BigDecimal:9cda90c,'0.149E1',18(18)>, but is now #<BigDecimal:9ba0d5c,'0.15E1',18(18)>
     # /tmp/d20130203-23049-trkcqw/spec.rb:16: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#set sets the exchange rate in both directions
     Failure/Error: rate.get(:EUR, :BGN).should eq '1.25'.to_d
       
       expected: #<BigDecimal:9aa6064,'0.125E1',18(18)>
            got: #<BigDecimal:9cd9908,'0.2E1',9(36)>
       
       (compared using ==)
     # /tmp/d20130203-23049-trkcqw/spec.rb:25: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) 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:93ba19c,'0.1E1',9(36)>
            got: nil
       
       (compared using ==)
     # /tmp/d20130203-23049-trkcqw/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)>'

  4) ExchangeRate#get does not allow changing the exchange rate between two identical currencies
     Failure/Error: rate.get(:EUR, :EUR).should eq 1.to_d
       
       expected: #<BigDecimal:93c577c,'0.1E1',9(36)>
            got: #<BigDecimal:93c5e5c,'0.2E1',9(36)>
       
       (compared using ==)
     # /tmp/d20130203-23049-trkcqw/spec.rb:50: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)>'

  5) ExchangeRate#convert works for identical currencies without defining any rates
     Failure/Error: rate.convert(:JPY, :JPY, 123.to_d).should eq 123.to_d
     Unknown:
       ExchangeRate::Unknown
     # /tmp/d20130203-23049-trkcqw/solution.rb:27:in `convert'
     # /tmp/d20130203-23049-trkcqw/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)>'

  6) 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
     Unknown:
       ExchangeRate::Unknown
     # /tmp/d20130203-23049-trkcqw/solution.rb:27:in `convert'
     # /tmp/d20130203-23049-trkcqw/solution.rb:55:in `in'
     # /tmp/d20130203-23049-trkcqw/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)>'

  7) Money arithmetic * with money objects raises an ArgumentError
     Failure/Error: expect do
       expected ArgumentError, got #<TypeError: Money can't be coerced into BigDecimal>
     # /tmp/d20130203-23049-trkcqw/spec.rb:129: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)>'

  8) Money arithmetic / with money objects raises an ArgumentError
     Failure/Error: expect do
       expected ArgumentError, got #<TypeError: Money can't be coerced into BigDecimal>
     # /tmp/d20130203-23049-trkcqw/spec.rb:129: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)>'

  9) Money arithmetic + with numeric objects raises an ArgumentError
     Failure/Error: expect do
       expected ArgumentError, got #<NoMethodError: undefined method `currency' for 42:Fixnum>
     # /tmp/d20130203-23049-trkcqw/spec.rb:137: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)>'

  10) Money arithmetic - with numeric objects raises an ArgumentError
     Failure/Error: expect do
       expected ArgumentError, got #<NoMethodError: undefined method `currency' for 42:Fixnum>
     # /tmp/d20130203-23049-trkcqw/spec.rb:137: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)>'

  11) Money arithmetic + with other objects raises an ArgumentError
     Failure/Error: expect do
       expected ArgumentError, got #<NoMethodError: undefined method `currency' for "foobar":String>
     # /tmp/d20130203-23049-trkcqw/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)>'

  12) Money arithmetic - with other objects raises an ArgumentError
     Failure/Error: expect do
       expected ArgumentError, got #<NoMethodError: undefined method `currency' for "foobar":String>
     # /tmp/d20130203-23049-trkcqw/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)>'

  13) Money arithmetic * with other objects raises an ArgumentError
     Failure/Error: expect do
       expected ArgumentError, got #<TypeError: String can't be coerced into BigDecimal>
     # /tmp/d20130203-23049-trkcqw/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)>'

  14) Money arithmetic / with other objects raises an ArgumentError
     Failure/Error: expect do
       expected ArgumentError, got #<TypeError: String can't be coerced into BigDecimal>
     # /tmp/d20130203-23049-trkcqw/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)>'

  15) Money comparison works when currencies are the same
     Failure/Error: (a < b).should be_false
     NoMethodError:
       undefined method `<' for 12.45 USD:Money
     # /tmp/d20130203-23049-trkcqw/spec.rb:172: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)>'

  16) Money comparison with < raises ArgumentError when comparing with other objects
     Failure/Error: expect do
       expected ArgumentError, got #<NoMethodError: undefined method `<' for 12.00 USD:Money>
     # /tmp/d20130203-23049-trkcqw/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)>'

  17) Money comparison with < raises IncompatibleCurrencies when currencies differ
     Failure/Error: expect do
       expected IncompatibleCurrencies, got #<NoMethodError: undefined method `<' for 12.00 USD:Money>
     # /tmp/d20130203-23049-trkcqw/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)>'

  18) Money comparison with > raises ArgumentError when comparing with other objects
     Failure/Error: expect do
       expected ArgumentError, got #<NoMethodError: undefined method `>' for 12.00 USD:Money>
     # /tmp/d20130203-23049-trkcqw/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)>'

  19) Money comparison with > raises IncompatibleCurrencies when currencies differ
     Failure/Error: expect do
       expected IncompatibleCurrencies, got #<NoMethodError: undefined method `>' for 12.00 USD:Money>
     # /tmp/d20130203-23049-trkcqw/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.06101 seconds
47 examples, 19 failures

Failed examples:

rspec /tmp/d20130203-23049-trkcqw/spec.rb:13 # ExchangeRate#set allows rates to be updated if called multiple times
rspec /tmp/d20130203-23049-trkcqw/spec.rb:21 # ExchangeRate#set sets the exchange rate in both directions
rspec /tmp/d20130203-23049-trkcqw/spec.rb:44 # ExchangeRate#get always returns 1 as the exchange rate between two identical currencies
rspec /tmp/d20130203-23049-trkcqw/spec.rb:48 # ExchangeRate#get does not allow changing the exchange rate between two identical currencies
rspec /tmp/d20130203-23049-trkcqw/spec.rb:71 # ExchangeRate#convert works for identical currencies without defining any rates
rspec /tmp/d20130203-23049-trkcqw/spec.rb:106 # Money convertion does not change the amount if the same currency is passed
rspec /tmp/d20130203-23049-trkcqw/spec.rb:128 # Money arithmetic * with money objects raises an ArgumentError
rspec /tmp/d20130203-23049-trkcqw/spec.rb:128 # Money arithmetic / with money objects raises an ArgumentError
rspec /tmp/d20130203-23049-trkcqw/spec.rb:136 # Money arithmetic + with numeric objects raises an ArgumentError
rspec /tmp/d20130203-23049-trkcqw/spec.rb:136 # Money arithmetic - with numeric objects raises an ArgumentError
rspec /tmp/d20130203-23049-trkcqw/spec.rb:159 # Money arithmetic + with other objects raises an ArgumentError
rspec /tmp/d20130203-23049-trkcqw/spec.rb:159 # Money arithmetic - with other objects raises an ArgumentError
rspec /tmp/d20130203-23049-trkcqw/spec.rb:159 # Money arithmetic * with other objects raises an ArgumentError
rspec /tmp/d20130203-23049-trkcqw/spec.rb:159 # Money arithmetic / with other objects raises an ArgumentError
rspec /tmp/d20130203-23049-trkcqw/spec.rb:168 # Money comparison works when currencies are the same
rspec /tmp/d20130203-23049-trkcqw/spec.rb:194 # Money comparison with < raises ArgumentError when comparing with other objects
rspec /tmp/d20130203-23049-trkcqw/spec.rb:200 # Money comparison with < raises IncompatibleCurrencies when currencies differ
rspec /tmp/d20130203-23049-trkcqw/spec.rb:194 # Money comparison with > raises ArgumentError when comparing with other objects
rspec /tmp/d20130203-23049-trkcqw/spec.rb:200 # Money comparison with > raises IncompatibleCurrencies when currencies differ

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

Елена обнови решението на 16.01.2013 07:28 (преди над 11 години)

+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class ExchangeRate
+ attr_accessor :rates
+
+ def initialize
+ @rates = []
+ end
+
+ def set(from_currency, to_currency, rate)
+ @rates << RateUnit.new(from_currency, to_currency, rate)
+ @rates << RateUnit.new(to_currency, from_currency, 1/rate)
+ end
+
+ def get(from_currency, to_currency)
+ @rates.each do |rate_unit|
+ if rate_unit.from_currency == from_currency and rate_unit.to_currency == to_currency
+ return rate_unit.rate
+ end
+ end
+ return nil
+ end
+
+ def convert(from_currency, to_currency, amount)
+ rate_unit = get(from_currency, to_currency)
+ raise Unknown.new('ExchangeRate::Unknown') if rate_unit == nil
+ return amount*rate_unit
+ end
+end
+
+class RateUnit
+ attr_accessor :from_currency, :to_currency, :rate
+
+ def initialize(from_currency, to_currency, rate)
+ @from_currency = from_currency
+ @to_currency = to_currency
+ @rate = rate
+ end
+end
+
+class Money
+ attr_accessor :amount, :currency
+
+ def initialize(amount, currency)
+ @amount = amount
+ @currency = currency
+ end
+
+ def to_s
+ sprintf("%.2f %s", @amount.to_f, @currency)
+ end
+
+end
+
+class Unknown < RuntimeError
+end

Елена обнови решението на 16.01.2013 11:41 (преди над 11 години)

require 'bigdecimal'
require 'bigdecimal/util'
class ExchangeRate
attr_accessor :rates
def initialize
@rates = []
end
def set(from_currency, to_currency, rate)
@rates << RateUnit.new(from_currency, to_currency, rate)
@rates << RateUnit.new(to_currency, from_currency, 1/rate)
end
def get(from_currency, to_currency)
@rates.each do |rate_unit|
if rate_unit.from_currency == from_currency and rate_unit.to_currency == to_currency
return rate_unit.rate
end
end
return nil
end
def convert(from_currency, to_currency, amount)
rate_unit = get(from_currency, to_currency)
raise Unknown.new('ExchangeRate::Unknown') if rate_unit == nil
return amount*rate_unit
end
end
class RateUnit
attr_accessor :from_currency, :to_currency, :rate
def initialize(from_currency, to_currency, rate)
@from_currency = from_currency
@to_currency = to_currency
@rate = rate
end
end
class Money
attr_accessor :amount, :currency
def initialize(amount, currency)
@amount = amount
@currency = currency
end
def to_s
sprintf("%.2f %s", @amount.to_f, @currency)
end
+ def in(currency, exchange_rate)
+ to_currency_amount = exchange_rate.convert(@currency, currency, @amount)
+ Money.new(to_currency_amount, currency)
+ end
+
+ def *(numeric_value)
+ Money.new(@amount*numeric_value, @currency)
+ end
+
+ def /(numeric_value)
+ Money.new(@amount/numeric_value, @currency)
+ end
+
+ def +(other_money)
+ return Money.new(@amount + other_money.amount, @currency) if @currency == other_money.currency
+ raise IncompatibleCurrencies.new('Money::IncompatibleCurrencies')
+ end
+
+ def -(other_money)
+ return Money.new(@amount - other_money.amount, @currency) if @currency == other_money.currency
+ raise IncompatibleCurrencies.new('Money::IncompatibleCurrencies')
+ end
+
+ def <=>(other_money)
+ check_compatibility(other_money)
+ return @amount <=> other_money.amount
+ end
+
+ def ==(other_money)
+ check_compatibility(other_money)
+ return @amount == other_money.amount
+ end
+
+ def <=(other_money)
+ check_compatibility(other_money)
+ return @amount <= other_money.amount
+ end
+
+ def >=(other_money)
+ check_compatibility(other_money)
+ return @amount >= other_money.amount
+ end
+
+ def check_compatibility(other_money)
+ raise ArgumentError if !other_money.is_a? Money
+ raise IncompatibleCurrencies if @currency != other_money.currency
+ end
end
class Unknown < RuntimeError
+end
+
+class IncompatibleCurrencies < RuntimeError
end