<commit_before>"""COUNTER journal and book reports and associated functions"""

from __future__ import absolute_import

import collections
import datetime
import logging
import re

import arrow
import six

from pycounter import csvhelper
from pycounter.constants import CODES, HEADER_FIELDS, METRICS
from pycounter.constants import REPORT_DESCRIPTIONS, TOTAL_TEXT
from pycounter.exceptions import PycounterException, UnknownReportTypeError
from pycounter.helpers import convert_covered, convert_date_column, \
    convert_date_run, format_stat, guess_type_from_content, last_day, \
    next_month


class CounterReport(object):
    """
    a COUNTER usage statistics report.

    Iterate over the report object to get its rows (each of which is a
    :class:`CounterBook <CounterBook>` or :class:`CounterJournal
    <CounterJournal>` instance.

    :param metric: metric being tracked by this report. For database
        reports (which have multiple metrics per report), this should be
        set to `None`.

    :param report_type: type of report (e.g., "JR1", "BR2")

    :param report_version: COUNTER version

    :param customer: name of customer on report

    :param institutional_identifier: unique ID assigned by vendor for
        customer

    :param period: tuple of datetime.date objects corresponding to the
        beginning and end of the covered range

    :param date_run: date the COUNTER report was generated

    """

    def __init__(self, report_type=None, report_version=4, metric=None,
                 customer=None, institutional_identifier=None,
                 period=(None, None), date_run=None):
        self.pubs = []
        self.report_type = report_type
        self.report_version = report_version
        self.metric = metric
        self.customer = customer
        self.institutional_identifier = institutional_identifier
        self.period = period
        if date_run is None:
            self.date_run = datetime.date.today()
        else:
            self.date_run = date_run
        self.year = None

    def __repr__(self):
        return (
            "<CounterReport %s version %s for date range %s to %s>" %
            (self.report_type,
             self.report_version,
             self.period[0], self.period[1])
        )

    def __iter__(self):
        return iter(self.pubs)

    def write_to_file(self, path, format):
        if format == 'tsv':
            self.write_tsv(path)
        else:
            raise PycounterException("unknown file type %s" % format)

    def write_tsv(self, path):
        """
        Output report to a COUNTER 4 TSV file.

        :param path: location to write file
        """<commit_msg>document write_to_file and don't redefine format() builtin accidentally...<commit_after>"""COUNTER journal and book reports and associated functions"""

from __future__ import absolute_import

import collections
import datetime
import logging
import re

import arrow
import six

from pycounter import csvhelper
from pycounter.constants import CODES, HEADER_FIELDS, METRICS
from pycounter.constants import REPORT_DESCRIPTIONS, TOTAL_TEXT
from pycounter.exceptions import PycounterException, UnknownReportTypeError
from pycounter.helpers import convert_covered, convert_date_column, \
    convert_date_run, format_stat, guess_type_from_content, last_day, \
    next_month


class CounterReport(object):
    """
    a COUNTER usage statistics report.

    Iterate over the report object to get its rows (each of which is a
    :class:`CounterBook <CounterBook>` or :class:`CounterJournal
    <CounterJournal>` instance.

    :param metric: metric being tracked by this report. For database
        reports (which have multiple metrics per report), this should be
        set to `None`.

    :param report_type: type of report (e.g., "JR1", "BR2")

    :param report_version: COUNTER version

    :param customer: name of customer on report

    :param institutional_identifier: unique ID assigned by vendor for
        customer

    :param period: tuple of datetime.date objects corresponding to the
        beginning and end of the covered range

    :param date_run: date the COUNTER report was generated

    """

    def __init__(self, report_type=None, report_version=4, metric=None,
                 customer=None, institutional_identifier=None,
                 period=(None, None), date_run=None):
        self.pubs = []
        self.report_type = report_type
        self.report_version = report_version
        self.metric = metric
        self.customer = customer
        self.institutional_identifier = institutional_identifier
        self.period = period
        if date_run is None:
            self.date_run = datetime.date.today()
        else:
            self.date_run = date_run
        self.year = None

    def __repr__(self):
        return (
            "<CounterReport %s version %s for date range %s to %s>" %
            (self.report_type,
             self.report_version,
             self.period[0], self.period[1])
        )

    def __iter__(self):
        return iter(self.pubs)

    def write_to_file(self, path, format_):
        """
        Output report to a file

        :param path: location to write file
        :param format_: file format. Currently supports 'tsv'
        :return:
        """
        if format_ == 'tsv':
            self.write_tsv(path)
        else:
            raise PycounterException("unknown file type %s" % format_)

    def write_tsv(self, path):
        """
        Output report to a COUNTER 4 TSV file.

        :param path: location to write file
        """
{'fraction_non_alphanumeric': 0.07323592302209551, 'fraction_numerical': 0.0021382751247327157, 'mean_word_length': 2.7221485411140582, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4767972', 'n_tokens_mistral': 1533, 'n_tokens_neox': 1479, 'n_words': 512}