Download, extract, and interpret a CO-TRACER report or reports.

    Generate a URL for the given report, download the corresponding archive,
    extract the CSV report, and interpret it using TRACER-specific logic. If
    no report type is provided, this process is repeated for all available
    report types for the given year.

    @param year: The year to retrieve a report or reports for.
    @type year: int
    @keyword report_type: The type of report that should be downloaded. Should
        be one of the strings in constants.REPORT_TYPES. If None, all reports
        for the given year will be downloaded. Defaults to None.
    @type report_type: str or None
    @return: A collection of dict with the loaded data. Note that this data has
        been interpreted so data fields like floating point values, dates, and
        boolean values are no longer strings. If report_type was None, this
        will be a dictionary where the keys are the report types as listed in
        constants.REPORT_TYPES and the values are Iterable over dict. Each dict
        rendered by that iterable will have one report entry.
    @rtype: dict or Iterable over dict

def get_report(year, report_type=None):
    """Download, extract, and interpret a CO-TRACER report or reports.

    Generate a URL for the given report, download the corresponding archive,
    extract the CSV report, and interpret it using TRACER-specific logic. If
    no report type is provided, this process is repeated for all available
    report types for the given year.

    @param year: The year to retrieve a report or reports for.
    @type year: int
    @keyword report_type: The type of report that should be downloaded. Should
        be one of the strings in constants.REPORT_TYPES. If None, all reports
        for the given year will be downloaded. Defaults to None.
    @type report_type: str or None
    @return: A collection of dict with the loaded data. Note that this data has
        been interpreted so data fields like floating point values, dates, and
        boolean values are no longer strings. If report_type was None, this
        will be a dictionary where the keys are the report types as listed in
        constants.REPORT_TYPES and the values are Iterable over dict. Each dict
        rendered by that iterable will have one report entry.
    @rtype: dict or Iterable over dict
    """
    if report_type == None:
        report_types = constants.REPORT_TYPES
        report_sections = [
            get_report_interpreted(year, report) for report in report_types
        ]

        return dict(zip(constants.REPORT_TYPES, report_sections))
    
    else:
        return get_report_interpreted(year, report_type)