From: "Wai-Ming S. Li" Date: 2005-04-18T15:22:47+09:00 Subject: [SOLUTION] Madlibs (#28) --=_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_=--