def generate_report(data, report_template, report_filename, subunit_filename,
                    book_folder=None):
    LOG.debug('Generating report, template: %s, output: %s',
              report_template, report_filename or '<dummy>')

    calculate_stats(data['records'], data['tests'])

    sla_records = verify_sla(data['records'], data['tests'])
    data['sla'] = output_sla(sla_records)

    if subunit_filename:
        save_to_subunit(sla_records, subunit_filename)

    # add more filters to jinja
    jinja_env = jinja2.Environment(variable_start_string='[[[',
                                   variable_end_string=']]]',
                                   comment_start_string='[[#',
                                   comment_end_string='#]]')
    jinja_env.filters['json'] = json.dumps
    jinja_env.filters['yaml'] = functools.partial(yaml.safe_dump, indent=2,
                                                  default_flow_style=False)

    alias_mapper = lambda f: config.REPORT_TEMPLATES + f % '%s.html'
    template = utils.read_file(report_template, alias_mapper=alias_mapper)
    compiled_template = jinja_env.from_string(template)
    rendered_template = compiled_template.render(dict(report=data))

    if report_filename:
        LOG.debug('Writing report to: %s', report_filename)
        try:
            utils.write_file(rendered_template, report_filename)
            LOG.info('Report saved to: %s', report_filename)
        except IOError as e:
            LOG.error('Failed to write report file: %s', e)

    if book_folder:
        writer.write_book(book_folder, data)
dataset/ETHPy150Open openstack/shaker/shaker/engine/report.py/generate_report/swapped operands of `%`