James Gray
4/17/2005 11:47:00 PM
Begin forwarded message:
> From: "Wai-Ming S. Li" <WLi@thoughtworks.com>
> Date: April 17, 2005 6:51:43 PM CDT
> To: submission@rubyquiz.com
> Subject: Please Forward: Ruby Quiz Subumission
>
>
> This is 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