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

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

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

Резултати

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

Код

require 'bigdecimal'
require 'bigdecimal/util'
class Unknown < RuntimeError
end
class ExchangeRate
def initialize
@rate = {}
end
def set from_currency, to_currency, rate
@rate[from_currency] = {}
@rate[from_currency][to_currency] = rate
@rate[to_currency] = {}
@rate[to_currency][from_currency] = 1/rate
end
def get from_currency, to_currency
@rate[from_currency][to_currency]
end
def convert from_currency, to_currency, amount
rate = from_currency == to_currency ? 1 : @rate[from_currency]
raise Unknown, 'No rate available' if rate.nil?
rate = rate[to_currency] unless rate == 1
rate * amount
end
end
class IncompatibleCurrencies < RuntimeError
end
class Money
include Comparable
attr_reader :currency, :amount
def initialize amount, currency
@amount = amount
@currency = currency
end
def to_s
((@amount*100).fix().to_f / 100).to_s + " " + @currency.to_s
end
def in currency, exchange_rate
Money.new exchange_rate.convert(@currency, currency, @amount), currency
end
def * multiplier
raise "Invalid operation" unless multiplier.kind_of? Numeric
Money.new @amount*multiplier, @currency
end
def / divisor
raise "Invalid operation" unless divisor.kind_of? Numeric
raise ZeroDivisionError, "Devision of 0" if divisor == 0
Money.new @amount/divisor, currency
end
def + money
raise ArgumentError, "Invalid argument" unless money.class == Money
raise IncompatibleCurrencies, "Different currencies" unless money.currency == currency
Money.new (amount + money.amount), currency
end
def - money
raise ArgumentError, "Invalid argument" unless money.class == Money
raise IncompatibleCurrencies, "Different currencies" unless money.currency == currency
Money.new (amount - money.amount), currency
end
def <=> money
raise ArgumentError, "Invalid argument" unless money.class == Money
raise IncompatibleCurrencies, "Different currencies" unless money.currency == currency
@amount <=> money.amount
end
end

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

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

Failures:

  1) ExchangeRate#get returns nil for non-existing rates
     Failure/Error: rate.get(:EUR, :BGN).should be_nil
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20130203-23049-1ayl2i0/solution.rb:20:in `get'
     # /tmp/d20130203-23049-1ayl2i0/spec.rb:31: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#get always returns 1 as the exchange rate between two identical currencies
     Failure/Error: rate.get(:JPY, :JPY).should eq 1.to_d
     NoMethodError:
       undefined method `[]' for nil:NilClass
     # /tmp/d20130203-23049-1ayl2i0/solution.rb:20:in `get'
     # /tmp/d20130203-23049-1ayl2i0/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)>'

  3) 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:9f48dd8,'0.1E1',9(36)>
            got: #<BigDecimal:9f48e28,'0.5E0',9(36)>
       
       (compared using ==)
     # /tmp/d20130203-23049-1ayl2i0/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)>'

  4) Money has a custom to_s representation
     Failure/Error: Money.new('12.1'.to_d, :USD).to_s.should eq '12.10 USD'
       
       expected: "12.10 USD"
            got: "12.1 USD"
       
       (compared using ==)
     # /tmp/d20130203-23049-1ayl2i0/spec.rb:90:in `block (2 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 arithmetic * with money objects raises an ArgumentError
     Failure/Error: expect do
       expected ArgumentError, got #<RuntimeError: Invalid operation>
     # /tmp/d20130203-23049-1ayl2i0/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)>'

  6) Money arithmetic / with money objects raises an ArgumentError
     Failure/Error: expect do
       expected ArgumentError, got #<RuntimeError: Invalid operation>
     # /tmp/d20130203-23049-1ayl2i0/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)>'

  7) Money arithmetic * with other objects raises an ArgumentError
     Failure/Error: expect do
       expected ArgumentError, got #<RuntimeError: Invalid operation>
     # /tmp/d20130203-23049-1ayl2i0/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)>'

  8) Money arithmetic / with other objects raises an ArgumentError
     Failure/Error: expect do
       expected ArgumentError, got #<RuntimeError: Invalid operation>
     # /tmp/d20130203-23049-1ayl2i0/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)>'

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

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

Failed examples:

rspec /tmp/d20130203-23049-1ayl2i0/spec.rb:30 # ExchangeRate#get returns nil for non-existing rates
rspec /tmp/d20130203-23049-1ayl2i0/spec.rb:44 # ExchangeRate#get always returns 1 as the exchange rate between two identical currencies
rspec /tmp/d20130203-23049-1ayl2i0/spec.rb:48 # ExchangeRate#get does not allow changing the exchange rate between two identical currencies
rspec /tmp/d20130203-23049-1ayl2i0/spec.rb:88 # Money has a custom to_s representation
rspec /tmp/d20130203-23049-1ayl2i0/spec.rb:128 # Money arithmetic * with money objects raises an ArgumentError
rspec /tmp/d20130203-23049-1ayl2i0/spec.rb:128 # Money arithmetic / with money objects raises an ArgumentError
rspec /tmp/d20130203-23049-1ayl2i0/spec.rb:159 # Money arithmetic * with other objects raises an ArgumentError
rspec /tmp/d20130203-23049-1ayl2i0/spec.rb:159 # Money arithmetic / with other objects raises an ArgumentError
rspec /tmp/d20130203-23049-1ayl2i0/spec.rb:194 # Money comparison with == raises ArgumentError when comparing with other objects
rspec /tmp/d20130203-23049-1ayl2i0/spec.rb:200 # Money comparison with == raises IncompatibleCurrencies when currencies differ

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

Елена обнови решението на 11.01.2013 19:33 (преди почти 12 години)

+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class Unknown < RuntimeError
+end
+
+class ExchangeRate
+ def initialize
+ @rate = {}
+ end
+
+ def set from_currency, to_currency, rate
+ @rate[from_currency] = {}
+ @rate[from_currency][to_currency] = rate
+ @rate[to_currency] = {}
+ @rate[to_currency][from_currency] = 1/rate
+ end
+
+ def get from_currency, to_currency
+ @rate[from_currency][to_currency]
+ end
+
+ def convert from_currency, to_currency, amount
+ rate = from_currency == to_currency ? 1 : @rate[from_currency]
+ raise Unknown, 'No rate available' if rate.nil?
+ rate = rate[to_currency] unless rate == 1
+ rate * amount
+ end
+end
+
+class IncompatibleCurrencies < RuntimeError
+end
+
+class Money
+ include Comparable
+ attr_reader :currency, :amount
+
+ def initialize amount, currency
+ @amount = amount
+ @currency = currency
+ end
+
+ def to_s
+ ((@amount*100).fix().to_f / 100).to_s + " " + @currency.to_s
+ end
+
+ def in currency, exchange_rate
+ Money.new exchange_rate.convert(@currency, currency, @amount), currency
+ end
+
+ def * multiplier
+ raise "Invalid operation" unless multiplier.kind_of? Numeric
+ Money.new @amount*multiplier, @currency
+ end
+
+ def / divisor
+ raise "Invalid operation" unless divisor.kind_of? Numeric
+ raise ZeroDivisionError, "Devision of 0" if divisor == 0
+ Money.new @amount/divisor, currency
+ end
+
+ def + money
+ raise ArgumentError, "Invalid argument" unless money.class == Money
+ raise IncompatibleCurrencies, "Different currencies" unless money.currency == currency
+ Money.new (amount + money.amount), currency
+ end
+
+ def - money
+ raise ArgumentError, "Invalid argument" unless money.class == Money
+ raise IncompatibleCurrencies, "Different currencies" unless money.currency == currency
+ Money.new (amount - money.amount), currency
+ end
+
+ def <=> money
+ raise ArgumentError, "Invalid argument" unless money.class == Money
+ raise IncompatibleCurrencies, "Different currencies" unless money.currency == currency
+ @amount <=> money.amount
+ end
+end