Hi,
I’m running Ruby 1.8.2 over WinXP-Pro/SP2.
I’ve written a variant of Dave T.’ Decimal-to-Roman program from
PickAxe 2. I get a couple of minor differences in execution…
One difference is that my assert statements that test values need a
“to_s” to avoid failure. His do not, e.g.
assert_equal('i', Roman.new(1).to_s)
assert_equal('ii', Roman.new(2).to_s)
assert_equal('iv', Roman.new(4).to_s)
My statement
assert_raise(RuntimeError, Roman.new(0))
shows up in the “errors” count and a traceback is produced. Dave’s
example shows no errors nor a traceback.
I test under SciTE and in a Command Window; they yield identical
results.
Dave’s book says he’s covering the same Ruby version I’m using. Could
it be he’s developing on Uni* while I’m on Windows? The code’s below
if your interested.
Thanks in Advance,
Richard
TestC.rb
equire ‘roman3’ # No debugging code … just one puts statement
require ‘test/unit’
class TestRoman < Test::Unit::TestCase
def test_simple
assert_equal(‘i’, Roman.new(1).to_s)
assert_equal(‘ii’, Roman.new(2).to_s)
assert_equal(‘iv’, Roman.new(4).to_s)
assert_equal(‘v’, Roman.new(5).to_s)
assert_equal(‘vi’, Roman.new(6).to_s)
assert_equal(‘ixx’, Roman.new(19).to_s)
assert_equal(‘ic’, Roman.new(99).to_s)
assert_equal(‘ci’, Roman.new(101).to_s)
assert_equal(‘vmmmmm’, Roman.new(4995).to_s)
assert_equal(‘immmmm’, Roman.new(4999).to_s)
assert_raise(RuntimeError, Roman.new(0))
end
end
Results
Loaded suite TestC
Started
1=>i
2=>ii
4=>iv
5=>v
6=>vi
19=>ixx
99=>ic
101=>ci
4995=>vmmmmm
4999=>immmmm
E
Finished in 0.0 seconds.
- Error:
test_simple(TestRoman):
RuntimeError: Roman numerals must be between 1 & 4999
./roman3.rb:9:ininitialize' TestC.rb:15:in
new’
TestC.rb:15:in `test_simple’
1 tests, 10 assertions, 0 failures, 1 errors
Roman3.rb
class Roman
MAXROMAN = 4999
Symbols= [ [“m”, 1000], [“d”, 500], [“c”, 100], [“l”, 50],
[“x”, 10], [“v”, 5], [“i”, 1]
]
def initialize(value)
if value <= 0 || value > MAXROMAN
fail "Roman numerals must be between 1 & #{MAXROMAN}"
end
@value = value
end
def to_s
value = @value
roman = ""
# Check for exact match
for code, dec_equiv in Symbols
if dec_equiv == value then roman << code; value = 0; break; end
end
for code, dec_equiv in Symbols
break unless value > 0
orig_val =value
count, value = value.divmod(dec_equiv)
if (count < 0 || count * dec_equiv == orig_val)
else
for new_code, new_dec_equiv in Symbols
next unless new_dec_equiv < dec_equiv
if orig_val + new_dec_equiv == dec_equiv * (count+1)
roman << new_code
count += 1
value = orig_val + new_dec_equiv - (count * dec_equiv)
break
end
end
end
roman << (code * count)
break if value == 0
end
puts @value.to_s + '=>' + roman
roman
end
end