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

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

Към профила на Свилен Андонов

Резултати

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

Код

require 'bigdecimal'
require 'bigdecimal/util'
class HashString
def self.value value
hash_number = 228451
hash_value = 0
value.each_byte {|i| hash_value = (hash_value*23+i) % hash_number}
hash_value
end
end
class Money
include Comparable
attr_accessor :amount, :currency
def initialize amount ,currency
@amount = amount
@currency = currency
end
def <=>(other)
return self.amount <=> other.amount if other.class.to_s == "Money" &&
self.currency == other.currency
raise ArgumentError if other.class != Money
raise Money:IncompatibleCurrencies if self.currency != other.currency
end
def correctly? other
other.class == Money and self.currency == other.currency
end
def to_s
"%.2f" % @amount + " " + @currency.to_s
end
def in value , rate
sum = rate.get value.to_s, self.currency
raise ExchangeRate::Unknown if sum.nil?
Money.new (10 * (1/sum)).to_d, value
end
def * amount
return Money.new (@amount*amount).to_d ,@currency if amount.class == Fixnum ||
amount.class == Fixnum
raise ArgumentError
end
def / amount
return Money.new (@amount/amount).to_d ,@currency if amount.class == Numeric ||
amount.class == Fixnum
raise ArgumentError
end
def + amount
raise ArgumentError if amount.amount != amount.amount
raise Money:IncompatibleCurrencies if self.currency != amount.currency
Money.new (@amount+amount).to_d ,@currency if amount.class == Fixnum
Money.new (@amount+amount.amount).to_d ,@currency if correctly? amount
end
def - amount
raise ArgumentError if amount.amount != amount.amount
raise Money::IncompatibleCurrencies if self.currency != amount.currency
Money.new (@amount-amount).to_d ,@currency if amount.class == Fixnum
Money.new (@amount-amount.amount).to_d ,@currency if correctly? amount
end
end
class ExchangeRate
attr_writer :amounts
def initialize
@amounts = {}
end
def set from_currency, to_currency, rate
@amounts[HashString.value (from_currency.to_s+to_currency.to_s)] = rate
@amounts[HashString.value (to_currency.to_s+from_currency.to_s)] = (1/rate).to_d
end
def get from_currency, to_currency
return 1 if from_currency == to_currency
@amounts[HashString.value (from_currency.to_s+to_currency.to_s)].to_d
end
def convert from_currency, to_currency, amount
return nil if @amounts[HashString.value (from_currency.to_s+to_currency.to_s)] == nil
(amount * @amounts[HashString.value (from_currency.to_s+to_currency.to_s)]).to_d
end
end

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

....F....F..F...FFF....F.FF.FFF.....FFF.F.F.F.F

Failures:

  1) ExchangeRate#get returns nil for non-existing rates
     Failure/Error: rate.get(:EUR, :BGN).should be_nil
     NoMethodError:
       undefined method `to_d' for nil:NilClass
     # /tmp/d20130203-23049-jd2y1p/solution.rb:83:in `get'
     # /tmp/d20130203-23049-jd2y1p/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#convert raises an ExchangeRate::Unknown exception when the rate is not defined
     Failure/Error: end.to raise_error(ExchangeRate::Unknown)
     NameError:
       uninitialized constant ExchangeRate::Unknown
     # /tmp/d20130203-23049-jd2y1p/spec.rb:58: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#convert works for identical currencies without defining any rates
     Failure/Error: rate.convert(:JPY, :JPY, 123.to_d).should eq 123.to_d
       
       expected: #<BigDecimal:a87be14,'0.123E3',9(36)>
            got: nil
       
       (compared using ==)
     # /tmp/d20130203-23049-jd2y1p/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)>'

  4) Money convertion allows convertion to other currencies
     Failure/Error: levas.amount.should eq '39.2'.to_d
       
       expected: #<BigDecimal:a89ebe4,'0.392E2',18(18)>
            got: #<BigDecimal:a89ec34,'0.196E2',18(45)>
       
       (compared using ==)
     # /tmp/d20130203-23049-jd2y1p/spec.rb:102: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) 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
     NoMethodError:
       undefined method `to_d' for nil:NilClass
     # /tmp/d20130203-23049-jd2y1p/solution.rb:83:in `get'
     # /tmp/d20130203-23049-jd2y1p/solution.rb:37:in `in'
     # /tmp/d20130203-23049-jd2y1p/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)>'

  6) Money convertion raises an ExchangeRate::Unknown exception for unknown rates
     Failure/Error: end.to raise_error(ExchangeRate::Unknown)
     NameError:
       uninitialized constant ExchangeRate::Unknown
     # /tmp/d20130203-23049-jd2y1p/spec.rb:113: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 numeric objects raises an ArgumentError
     Failure/Error: expect do
       expected ArgumentError, got #<NoMethodError: undefined method `amount' for 42:Fixnum>
     # /tmp/d20130203-23049-jd2y1p/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)>'

  8) Money arithmetic raises Money::IncompatibleCurrencies for + with money with different currencies
     Failure/Error: end.to raise_error(Money::IncompatibleCurrencies)
     NameError:
       uninitialized constant Money::IncompatibleCurrencies
     # /tmp/d20130203-23049-jd2y1p/spec.rb:154: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 `amount' for 42:Fixnum>
     # /tmp/d20130203-23049-jd2y1p/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 raises Money::IncompatibleCurrencies for - with money with different currencies
     Failure/Error: end.to raise_error(Money::IncompatibleCurrencies)
     NameError:
       uninitialized constant Money::IncompatibleCurrencies
     # /tmp/d20130203-23049-jd2y1p/spec.rb:154: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 `amount' for "foobar":String>
     # /tmp/d20130203-23049-jd2y1p/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 `amount' for "foobar":String>
     # /tmp/d20130203-23049-jd2y1p/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 comparison with <=> raises IncompatibleCurrencies when currencies differ
     Failure/Error: end.to raise_error(Money::IncompatibleCurrencies)
     NameError:
       uninitialized constant Money::IncompatibleCurrencies
     # /tmp/d20130203-23049-jd2y1p/spec.rb:203: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 comparison with == raises ArgumentError when comparing with other objects
     Failure/Error: expect do
       expected ArgumentError but nothing was raised
     # /tmp/d20130203-23049-jd2y1p/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)>'

  15) Money comparison with == raises IncompatibleCurrencies when currencies differ
     Failure/Error: end.to raise_error(Money::IncompatibleCurrencies)
     NameError:
       uninitialized constant Money::IncompatibleCurrencies
     # /tmp/d20130203-23049-jd2y1p/spec.rb:203: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)>'

  16) Money comparison with < raises IncompatibleCurrencies when currencies differ
     Failure/Error: end.to raise_error(Money::IncompatibleCurrencies)
     NameError:
       uninitialized constant Money::IncompatibleCurrencies
     # /tmp/d20130203-23049-jd2y1p/spec.rb:203: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: end.to raise_error(Money::IncompatibleCurrencies)
     NameError:
       uninitialized constant Money::IncompatibleCurrencies
     # /tmp/d20130203-23049-jd2y1p/spec.rb:203: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 IncompatibleCurrencies when currencies differ
     Failure/Error: end.to raise_error(Money::IncompatibleCurrencies)
     NameError:
       uninitialized constant Money::IncompatibleCurrencies
     # /tmp/d20130203-23049-jd2y1p/spec.rb:203: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: end.to raise_error(Money::IncompatibleCurrencies)
     NameError:
       uninitialized constant Money::IncompatibleCurrencies
     # /tmp/d20130203-23049-jd2y1p/spec.rb:203: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.07034 seconds
47 examples, 19 failures

Failed examples:

rspec /tmp/d20130203-23049-jd2y1p/spec.rb:30 # ExchangeRate#get returns nil for non-existing rates
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:55 # ExchangeRate#convert raises an ExchangeRate::Unknown exception when the rate is not defined
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:71 # ExchangeRate#convert works for identical currencies without defining any rates
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:95 # Money convertion allows convertion to other currencies
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:106 # Money convertion does not change the amount if the same currency is passed
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:110 # Money convertion raises an ExchangeRate::Unknown exception for unknown rates
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:136 # Money arithmetic + with numeric objects raises an ArgumentError
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:151 # Money arithmetic raises Money::IncompatibleCurrencies for + with money with different currencies
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:136 # Money arithmetic - with numeric objects raises an ArgumentError
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:151 # Money arithmetic raises Money::IncompatibleCurrencies for - with money with different currencies
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:159 # Money arithmetic + with other objects raises an ArgumentError
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:159 # Money arithmetic - with other objects raises an ArgumentError
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:200 # Money comparison with <=> raises IncompatibleCurrencies when currencies differ
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:194 # Money comparison with == raises ArgumentError when comparing with other objects
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:200 # Money comparison with == raises IncompatibleCurrencies when currencies differ
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:200 # Money comparison with < raises IncompatibleCurrencies when currencies differ
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:200 # Money comparison with <= raises IncompatibleCurrencies when currencies differ
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:200 # Money comparison with > raises IncompatibleCurrencies when currencies differ
rspec /tmp/d20130203-23049-jd2y1p/spec.rb:200 # Money comparison with >= raises IncompatibleCurrencies when currencies differ

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

Свилен обнови решението на 12.01.2013 10:57 (преди над 11 години)

+require 'bigdecimal'
+require 'bigdecimal/util'
+
+class HashString
+ def self.value value
+ hash_number = 228451
+ a = 0
+ value.each_byte {|i| a = (a*23+i) % hash_number}
+ a
+ end
+end
+
+
+class Money
+ attr_accessor :amount, :currency
+ define_method (:>=){ |other| (self.> other) or (self.== other)}
+ define_method (:<=){ |other| (self.< other) or (self.== other)}
+ define_method (:correctly?){ |other| other.class == Money and self.currency == other.currency}
+ def initialize amount ,currency
+ @amount = amount
+ @currency = currency
+ end
+
+ def to_s #To repair
+ "%.2f" % @amount + " " + @currency.to_s
+ end
+
+ def in value , rate
+ sum = rate.get value.to_s, self.currency
+ raise ExchangeRate::Unknown if sum.nil?
+ Money.new (10 * (1/sum)).to_d, value
+ end
+
+ def * amount
+ return Money.new (@amount*amount).to_d ,@currency if amount.class == Fixnum
+ raise ArgumentError
+ end
+
+ def / amount
+ return Money.new (@amount/amount).to_d ,@currency if amount.class == Fixnum
+ raise ArgumentError
+ end
+
+ def +amount
+ raise ArgumentError if amount.amount != amount.amount
+ raise Money::IncompatibleCurrencies if self.currency != amount.currency
+ Money.new (@amount+amount).to_d ,@currency if amount.class == Fixnum
+ Money.new (@amount+amount.amount).to_d ,@currency if correctly? amount
+ end
+
+ def - amount
+ raise ArgumentError if amount.amount != amount.amount
+ raise Money::IncompatibleCurrencies if self.currency != amount.currency
+ Money.new (@amount-amount).to_d ,@currency if amount.class == Fixnum
+ Money.new (@amount-amount.amount).to_d ,@currency if correctly? amount
+ end
+
+ def == other
+ raise ArgumentError if other.class != Money
+ raise Money::IncompatibleCurrencies if self.currency != other.currency
+ correctly? other and self.amount == other.amount
+ end
+
+ def < other
+ raise ArgumentError if other.class != Money
+ raise Money::IncompatibleCurrencies if self.currency != other.currency
+ correctly? other and self.amount < other.amount
+ end
+
+ def > other
+ raise ArgumentError if other.class != Money
+ raise Money::IncompatibleCurrencies if self.currency != other.currency
+ correctly? other and self.amount > other.amount
+ end
+
+ def <=> other
+ 1 if self > other
+ -1 if self < other
+ 0 if self == other
+ end
+
+end
+
+
+class ExchangeRate
+ attr_writer :amounts
+ def initialize
+ @amounts = {}
+ end
+
+ def set from_currency, to_currency, rate
+ @amounts[HashString.value (from_currency.to_s+to_currency.to_s)] = rate
+ @amounts[HashString.value (to_currency.to_s+from_currency.to_s)] = (1/rate).to_d
+ end
+
+ def get from_currency, to_currency
+ return 1 if from_currency == to_currency
+ @amounts[HashString.value (from_currency.to_s+to_currency.to_s)].to_d
+ end
+
+ def convert from_currency, to_currency, amount
+ nil if @amounts[HashString.value (from_currency.to_s+to_currency.to_s)] == nil
+ (amount * @amounts[HashString.value (from_currency.to_s+to_currency.to_s)]).to_d
+ end
+end

Свилен обнови решението на 12.01.2013 11:03 (преди над 11 години)

require 'bigdecimal'
require 'bigdecimal/util'
class HashString
def self.value value
hash_number = 228451
a = 0
value.each_byte {|i| a = (a*23+i) % hash_number}
a
end
end
class Money
attr_accessor :amount, :currency
define_method (:>=){ |other| (self.> other) or (self.== other)}
define_method (:<=){ |other| (self.< other) or (self.== other)}
define_method (:correctly?){ |other| other.class == Money and self.currency == other.currency}
def initialize amount ,currency
@amount = amount
@currency = currency
end
def to_s #To repair
"%.2f" % @amount + " " + @currency.to_s
end
def in value , rate
sum = rate.get value.to_s, self.currency
raise ExchangeRate::Unknown if sum.nil?
Money.new (10 * (1/sum)).to_d, value
end
def * amount
return Money.new (@amount*amount).to_d ,@currency if amount.class == Fixnum
raise ArgumentError
- end
+ end
def / amount
return Money.new (@amount/amount).to_d ,@currency if amount.class == Fixnum
raise ArgumentError
end
def +amount
raise ArgumentError if amount.amount != amount.amount
raise Money::IncompatibleCurrencies if self.currency != amount.currency
Money.new (@amount+amount).to_d ,@currency if amount.class == Fixnum
Money.new (@amount+amount.amount).to_d ,@currency if correctly? amount
end
def - amount
raise ArgumentError if amount.amount != amount.amount
raise Money::IncompatibleCurrencies if self.currency != amount.currency
Money.new (@amount-amount).to_d ,@currency if amount.class == Fixnum
Money.new (@amount-amount.amount).to_d ,@currency if correctly? amount
end
def == other
raise ArgumentError if other.class != Money
raise Money::IncompatibleCurrencies if self.currency != other.currency
correctly? other and self.amount == other.amount
end
def < other
raise ArgumentError if other.class != Money
raise Money::IncompatibleCurrencies if self.currency != other.currency
correctly? other and self.amount < other.amount
end
def > other
raise ArgumentError if other.class != Money
raise Money::IncompatibleCurrencies if self.currency != other.currency
correctly? other and self.amount > other.amount
end
def <=> other
1 if self > other
-1 if self < other
0 if self == other
end
end
class ExchangeRate
attr_writer :amounts
def initialize
@amounts = {}
end
def set from_currency, to_currency, rate
@amounts[HashString.value (from_currency.to_s+to_currency.to_s)] = rate
@amounts[HashString.value (to_currency.to_s+from_currency.to_s)] = (1/rate).to_d
end
def get from_currency, to_currency
return 1 if from_currency == to_currency
@amounts[HashString.value (from_currency.to_s+to_currency.to_s)].to_d
end
def convert from_currency, to_currency, amount
nil if @amounts[HashString.value (from_currency.to_s+to_currency.to_s)] == nil
(amount * @amounts[HashString.value (from_currency.to_s+to_currency.to_s)]).to_d
end
end

Свилен обнови решението на 13.01.2013 13:35 (преди над 11 години)

require 'bigdecimal'
require 'bigdecimal/util'
class HashString
def self.value value
hash_number = 228451
a = 0
value.each_byte {|i| a = (a*23+i) % hash_number}
a
end
end
class Money
attr_accessor :amount, :currency
define_method (:>=){ |other| (self.> other) or (self.== other)}
define_method (:<=){ |other| (self.< other) or (self.== other)}
define_method (:correctly?){ |other| other.class == Money and self.currency == other.currency}
def initialize amount ,currency
@amount = amount
@currency = currency
end
- def to_s #To repair
+ def to_s
"%.2f" % @amount + " " + @currency.to_s
end
def in value , rate
sum = rate.get value.to_s, self.currency
raise ExchangeRate::Unknown if sum.nil?
Money.new (10 * (1/sum)).to_d, value
end
def * amount
- return Money.new (@amount*amount).to_d ,@currency if amount.class == Fixnum
+ return Money.new (@amount*amount).to_d ,@currency if amount.class == Fixnum ||
+ amount.class == Fixnum
raise ArgumentError
end
def / amount
- return Money.new (@amount/amount).to_d ,@currency if amount.class == Fixnum
+ return Money.new (@amount/amount).to_d ,@currency if amount.class == Numeric ||
+ amount.class == Fixnum
raise ArgumentError
end
def +amount
raise ArgumentError if amount.amount != amount.amount
raise Money::IncompatibleCurrencies if self.currency != amount.currency
Money.new (@amount+amount).to_d ,@currency if amount.class == Fixnum
Money.new (@amount+amount.amount).to_d ,@currency if correctly? amount
end
def - amount
raise ArgumentError if amount.amount != amount.amount
raise Money::IncompatibleCurrencies if self.currency != amount.currency
Money.new (@amount-amount).to_d ,@currency if amount.class == Fixnum
Money.new (@amount-amount.amount).to_d ,@currency if correctly? amount
end
def == other
raise ArgumentError if other.class != Money
raise Money::IncompatibleCurrencies if self.currency != other.currency
correctly? other and self.amount == other.amount
end
def < other
raise ArgumentError if other.class != Money
raise Money::IncompatibleCurrencies if self.currency != other.currency
correctly? other and self.amount < other.amount
end
def > other
raise ArgumentError if other.class != Money
raise Money::IncompatibleCurrencies if self.currency != other.currency
correctly? other and self.amount > other.amount
end
def <=> other
1 if self > other
-1 if self < other
0 if self == other
end
end
class ExchangeRate
attr_writer :amounts
def initialize
@amounts = {}
end
def set from_currency, to_currency, rate
@amounts[HashString.value (from_currency.to_s+to_currency.to_s)] = rate
@amounts[HashString.value (to_currency.to_s+from_currency.to_s)] = (1/rate).to_d
end
def get from_currency, to_currency
return 1 if from_currency == to_currency
@amounts[HashString.value (from_currency.to_s+to_currency.to_s)].to_d
end
def convert from_currency, to_currency, amount
- nil if @amounts[HashString.value (from_currency.to_s+to_currency.to_s)] == nil
+ return nil if @amounts[HashString.value (from_currency.to_s+to_currency.to_s)] == nil
(amount * @amounts[HashString.value (from_currency.to_s+to_currency.to_s)]).to_d
end
end

Свилен обнови решението на 13.01.2013 18:19 (преди над 11 години)

require 'bigdecimal'
require 'bigdecimal/util'
class HashString
def self.value value
hash_number = 228451
a = 0
value.each_byte {|i| a = (a*23+i) % hash_number}
a
end
end
-
class Money
+ include Comparable
attr_accessor :amount, :currency
- define_method (:>=){ |other| (self.> other) or (self.== other)}
- define_method (:<=){ |other| (self.< other) or (self.== other)}
- define_method (:correctly?){ |other| other.class == Money and self.currency == other.currency}
def initialize amount ,currency
@amount = amount
@currency = currency
end
+ def <=>(other)
+ return self.amount <=> other.amount if other.class.to_s == "Money" &&
+ self.currency == other.currency
+ raise ArgumentError if other.class != Money
+ raise Money:IncompatibleCurrencies if self.currency != other.currency
+ end
+
+ def correctly? other
+ other.class == Money and self.currency == other.currency
+ end
+
def to_s
"%.2f" % @amount + " " + @currency.to_s
end
def in value , rate
sum = rate.get value.to_s, self.currency
raise ExchangeRate::Unknown if sum.nil?
Money.new (10 * (1/sum)).to_d, value
end
def * amount
return Money.new (@amount*amount).to_d ,@currency if amount.class == Fixnum ||
- amount.class == Fixnum
+ amount.class == Fixnum
raise ArgumentError
end
def / amount
return Money.new (@amount/amount).to_d ,@currency if amount.class == Numeric ||
- amount.class == Fixnum
+ amount.class == Fixnum
raise ArgumentError
end
- def +amount
+ def + amount
raise ArgumentError if amount.amount != amount.amount
- raise Money::IncompatibleCurrencies if self.currency != amount.currency
+ raise Money:IncompatibleCurrencies if self.currency != amount.currency
Money.new (@amount+amount).to_d ,@currency if amount.class == Fixnum
Money.new (@amount+amount.amount).to_d ,@currency if correctly? amount
end
def - amount
raise ArgumentError if amount.amount != amount.amount
raise Money::IncompatibleCurrencies if self.currency != amount.currency
Money.new (@amount-amount).to_d ,@currency if amount.class == Fixnum
Money.new (@amount-amount.amount).to_d ,@currency if correctly? amount
end
-
- def == other
- raise ArgumentError if other.class != Money
- raise Money::IncompatibleCurrencies if self.currency != other.currency
- correctly? other and self.amount == other.amount
- end
-
- def < other
- raise ArgumentError if other.class != Money
- raise Money::IncompatibleCurrencies if self.currency != other.currency
- correctly? other and self.amount < other.amount
- end
-
- def > other
- raise ArgumentError if other.class != Money
- raise Money::IncompatibleCurrencies if self.currency != other.currency
- correctly? other and self.amount > other.amount
- end
-
- def <=> other
- 1 if self > other
- -1 if self < other
- 0 if self == other
- end
-
end
class ExchangeRate
attr_writer :amounts
def initialize
@amounts = {}
end
def set from_currency, to_currency, rate
@amounts[HashString.value (from_currency.to_s+to_currency.to_s)] = rate
@amounts[HashString.value (to_currency.to_s+from_currency.to_s)] = (1/rate).to_d
end
def get from_currency, to_currency
return 1 if from_currency == to_currency
@amounts[HashString.value (from_currency.to_s+to_currency.to_s)].to_d
end
def convert from_currency, to_currency, amount
return nil if @amounts[HashString.value (from_currency.to_s+to_currency.to_s)] == nil
(amount * @amounts[HashString.value (from_currency.to_s+to_currency.to_s)]).to_d
end
-end
+end

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

require 'bigdecimal'
require 'bigdecimal/util'
class HashString
def self.value value
hash_number = 228451
- a = 0
- value.each_byte {|i| a = (a*23+i) % hash_number}
- a
+ hash_value = 0
+ value.each_byte {|i| hash_value = (hash_value*23+i) % hash_number}
+ hash_value
end
end
class Money
include Comparable
attr_accessor :amount, :currency
def initialize amount ,currency
@amount = amount
@currency = currency
end
def <=>(other)
return self.amount <=> other.amount if other.class.to_s == "Money" &&
self.currency == other.currency
raise ArgumentError if other.class != Money
raise Money:IncompatibleCurrencies if self.currency != other.currency
end
def correctly? other
other.class == Money and self.currency == other.currency
end
def to_s
"%.2f" % @amount + " " + @currency.to_s
end
def in value , rate
sum = rate.get value.to_s, self.currency
raise ExchangeRate::Unknown if sum.nil?
Money.new (10 * (1/sum)).to_d, value
end
def * amount
return Money.new (@amount*amount).to_d ,@currency if amount.class == Fixnum ||
amount.class == Fixnum
raise ArgumentError
end
def / amount
return Money.new (@amount/amount).to_d ,@currency if amount.class == Numeric ||
amount.class == Fixnum
raise ArgumentError
end
def + amount
raise ArgumentError if amount.amount != amount.amount
raise Money:IncompatibleCurrencies if self.currency != amount.currency
Money.new (@amount+amount).to_d ,@currency if amount.class == Fixnum
Money.new (@amount+amount.amount).to_d ,@currency if correctly? amount
end
def - amount
raise ArgumentError if amount.amount != amount.amount
raise Money::IncompatibleCurrencies if self.currency != amount.currency
Money.new (@amount-amount).to_d ,@currency if amount.class == Fixnum
Money.new (@amount-amount.amount).to_d ,@currency if correctly? amount
end
end
class ExchangeRate
attr_writer :amounts
def initialize
@amounts = {}
end
def set from_currency, to_currency, rate
@amounts[HashString.value (from_currency.to_s+to_currency.to_s)] = rate
@amounts[HashString.value (to_currency.to_s+from_currency.to_s)] = (1/rate).to_d
end
def get from_currency, to_currency
return 1 if from_currency == to_currency
@amounts[HashString.value (from_currency.to_s+to_currency.to_s)].to_d
end
def convert from_currency, to_currency, amount
return nil if @amounts[HashString.value (from_currency.to_s+to_currency.to_s)] == nil
(amount * @amounts[HashString.value (from_currency.to_s+to_currency.to_s)]).to_d
end
end