[SOLUTION] Madlibs (#28)

W

Wai-Ming S. Li

--=_alternative 0022FC3188256FE7_=
Content-Type: text/plain; charset="US-ASCII"

Resummit my solution to the Madlabs Quiz and the unit tests.

Best Regards,
Steve Li.

--------------------------------------------------------------------------------------------------------------------
Madlibs.rb
class Story
attr_accessor :placeholders

def initialize(base)
@placeholders = []

story_parts = []
match = Placeholder.getPattern().match(base)
reuseMap = {}
while(match != nil)
story_parts << match.pre_match
placeholderString = match[1]
placeholder = Placeholder.new(placeholderString, story_parts.size)

# if name is reused
if reuseMap[placeholder.name] == nil
@placeholders << placeholder

# if the name is reusable, add it to the reuse table
if placeholder.reusable()
reuseMap[placeholder.name] = placeholder
end

# replace the placeholder with the system generated position
string
story_parts << get_position_string(story_parts.size.to_s)
else
# for reuse placeholder,
# replace the placeholder with the system generated position
string for the referenced placeholder
story_parts <<
get_position_string(reuseMap[placeholder.name].position.to_s)
end

remaind = match.post_match
match = Placeholder.getPattern().match(match.post_match)
if (match == nil)
story_parts << remaind
end
end

@base = story_parts.join("")
end

def to_s
result = @base
@placeholders.each do |placeholder|
result.gsub!(Regexp.new(get_position_string(placeholder.position.to_s)),
placeholder.value)
end
return result
end

def get_position_string(position)
"%%" + position.to_s + "%%"
end
end

class Placeholder
attr_accessor :name, :display_name, :position, :value

def initialize(placeholderString, position)
@value = ""
@position = position

if placeholderString.include?(":")
@name = placeholderString.split(":")[0]
@display_name = placeholderString.split(":")[1]
else
@name = placeholderString
@display_name = placeholderString
end
end

def getTemplate()
Regexp.new(
"\\(\\(\\s*(#{name}|#{name}\\s*:\\s*#{display_name})\\s*\\)\\)")
end

def Placeholder.getPattern()
/\(\(([^)]*)\)\)/
end

def getValueQuestion()
"Give me #{display_name}: "
end

def reusable()
name != display_name
end
end

if $0 == __FILE__
# read story from standard input
story_string = ""
ARGF.each_line do |line|
story_string += line
end

# create story
story = Story.new(story_string)

# request uesr to enter the corresponding value for each placeholder
print "There are #{story.placeholders.size} placeholders.\n"
story.placeholders.each do |placeholder|
print placeholder.getValueQuestion()
placeholder.value = gets().chop()
end

# display the story
print story.to_s, "\n"
end

--------------------------------------------------------------------------------------------------------------------
UnitTest;
MadlibsTest.rb
require 'runit/testcase'
require 'Madlibs'

class TestMadlibs < RUNIT::TestCase
def testStoryTemplate()
# parse simple story
# e.g. "Our favorite language is ((a gemstone))."
template = "Our favorite language is ((a gemstone))."
story = Story.new(template)

# should return a Story with a symbol name='a gemstome' and alias=nil
assert_equals(1, story.placeholders.size)
assert_not_nil(story.placeholders[0])
assert_equals("a gemstone", story.placeholders[0].display_name)
end

def testStoryTemplateWithAlias()
# parse story with name alias
# e.g. "Our favorite language is ((gem:a gemstone)). We think ((gem))
is
# better than ((a gemstone))."
template = "Our favorite language is ((gem:a gemstone)). "
template += "We think ((gem)) is better then ((a gemstone))."
story = Story.new(template)

# should return a Story with 2 symbole
# Symbol 1: name = 'gem' alias='a gemstome'
# Symbol 2: name = 'a gemstome'
assert_equals(2, story.placeholders.size)
assert_not_nil(story.placeholders[0])
assert_equals("gem", story.placeholders[0].name)
assert_equals("a gemstone", story.placeholders[0].display_name)
assert_not_nil(story.placeholders[1])
assert_equals("a gemstone", story.placeholders[1].name)
assert_equals("a gemstone", story.placeholders[1].display_name)
end

def testStoryGeneration()
# give: "Our favorite language is ((a gemstone))."
# input: gemstone = Ruby
# result: Our favorite language is Ruby."
String template = "Our favorite language is ((a gemstone))."
story = Story.new(template)
story.placeholders[0].value = "Ruby"
assert_equals("Our favorite language is Ruby.", story.to_s())
end

def testStoryGenerationWithAlias()
# given: "Our favorite language is ((gem:a gemstone)).
# We think ((gem)) is better than ((a gemstone))."

# input: a gemstone = Ruby, a genstone = Emerald
# given: "Our favorite language is Ruby.
# We think Ruby is better than Emerald."
template = "Our favorite language is ((gem:a gemstone)). "
template += "We think ((gem)) is better then ((a gemstone))."
story = Story.new(template)
story.placeholders[0].value = "Ruby"
story.placeholders[1].value = "Emerald"
assert_equals("Our favorite language is Ruby. We think Ruby is better
then Emerald.", story.to_s())
end
end

if $0 == __FILE__
require 'runit/cui/testrunner'
RUNIT::CUI::TestRunner.run(TestMadlibs.suite)
end
--=_alternative 0022FC3188256FE7_=--
 
J

James Edward Gray II

UnitTest;
MadlibsTest.rb
require 'runit/testcase'

You might want to take a look at the standard "test/unit" library. I
believe "runit" might be the old system of Ruby unit testing.
Obviously, it works fine, but you might find "test/unit" a little more
refined. Just FYI.

James Edward Gray II
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top