Skip to content

MR12a Report Lab Solution

Dave Strus edited this page Jan 31, 2016 · 2 revisions

SOLUTION: Generating a Report

Let's start with how we want each mutant to appear in the report:

Mutant 1 ================================
* Real name: Doreen
* Mutant name: Howldread
* Power: Communes with animals

We'll have to loop over the @mutants array, building a string like that each time through.

Let's initialize a string before the loop, and return it after the loop ends.

def report
  report_output = ''
  @mutants.each do |mutant|
    # do something
  end
  report_output
end

Since the output numbers each mutant, let's use each_with_index, so our block receives both the mutant and its index within the array. The first mutant will have an index of 0, so let's add 1 to the index in our output.

def report
  report_output = ''
  @mutants.each_with_index do |mutant, i|
    report_output += "\nMutant #{i + 1} ================================\n"
  end
  report_output
end

Notice that I've included a newline before and after this heading.

Now it's time to print the attributes. We could loop over mutant.attribute_names to get the names, and then use send to retrieve the values. But that's making it harder than it needs to be, now that we've added Mutant#attributes, which returns the attributes and their values as a hash. Let's loop over that instead.

def report
  report_output = ''
  @mutants.each_with_index do |mutant, i|
    report_output += "\nMutant #{i + 1} ================================\n"
    mutant.attributes.each do |attribute, value|
      report_output += "#{attribute}: #{value}"
    end
  end
  report_output
end

This gets us really close to desired output, but we still have uncapitalized attribute names with underscores. We can use the same trick we used in our prompts in collect_mutant_data to transform the attribute names.

def report
  report_output = ''
  @mutants.each_with_index do |mutant, i|
    report_output += "\nMutant #{i + 1} ================================\n"
    mutant.attributes.each do |attribute, value|
      report_output += attribute.to_s.gsub('_', ' ').capitalize + ': '
      report_output += "#{value}\n"
    end
  end
  report_output
end

We're repeating ourselves there, but we can live with that for now.

Now that we have RosterApplication updated with our new method, remember to update roster.rb to print the result of the new method.

app = RosterApplication.new
app.start

3.times do
  app.collect_mutant_data
end

puts app.report

Hot stuff!

I know I said we could live with our gsub/capitalize repetition for now, but now is over, folks. Let's find a better solution.