<commit_before>from __future__ import absolute_import, print_function, unicode_literals
from builtins import dict, str
import logging
import indra.statements as ist

logger = logging.getLogger(__name__)


class EnglishAssembler(object):
    """This assembler generates English sentences from INDRA Statements.

    Parameters
    ----------
    stmts : Optional[list[indra.statements.Statement]]
        A list of INDRA Statements to be added to the assembler.

    Attributes
    ----------
    statements : list[indra.statements.Statement]
        A list of INDRA Statements to assemble.
    model : str
        The assembled sentences as a single string.
    stmt_agents : list[list[AgentWithCoordinates]]
        A list containing lists of AgentWithCoordinates objects for each of
        the assembled statements. Coordinates represent the location of
        agents in the model.
    """
    def __init__(self, stmts=None):
        if stmts is None:
            self.statements = []
        else:
            self.statements = stmts
        self.model = None
        self.stmt_agents = []

    def add_statements(self, stmts):
        """Add INDRA Statements to the assembler's list of statements.

        Parameters
        ----------
        stmts : list[indra.statements.Statement]
            A list of :py:class:`indra.statements.Statement`
            to be added to the statement list of the assembler.
        """
        self.statements += stmts

    def make_model(self):
        """Assemble text from the set of collected INDRA Statements.

        Returns
        -------
        stmt_strs : str
            Return the assembled text as unicode string. By default, the text
            is a single string consisting of one or more sentences with
            periods at the end.
        """
        stmt_strs = []
        # Keep track of current length of the model text.
        text_length = 0
        for stmt in self.statements:
            sb = None
            # Get a SentenceBuilder object per statement
            if isinstance(stmt, ist.Modification):
                sb = _assemble_modification(stmt)
            elif isinstance(stmt, ist.Autophosphorylation):
                sb = _assemble_autophosphorylation(stmt)
            elif isinstance(stmt, ist.Association):
                sb = _assemble_association(stmt)
            elif isinstance(stmt, ist.Complex):
                sb = _assemble_complex(stmt)
            elif isinstance(stmt, ist.Influence):
                sb = _assemble_influence(stmt)
            elif isinstance(stmt, ist.RegulateActivity):
                sb = _assemble_regulate_activity(stmt)
            elif isinstance(stmt, ist.RegulateAmount):
                sb = _assemble_regulate_amount(stmt)
            elif isinstance(stmt, ist.ActiveForm):
                sb = _assemble_activeform(stmt)
            elif isinstance(stmt, ist.Translocation):
                sb = _assemble_translocation(stmt)
            elif isinstance(stmt, ist.Gef):
                sb = _assemble_gef(stmt)
            elif isinstance(stmt, ist.Gap):
                sb = _assemble_gap(stmt)
            elif isinstance(stmt, ist.Conversion):
                sb = _assemble_conversion(stmt)
            else:
                logger.warning('Unhandled statement type: %s.' % type(stmt))
            if sb:
                stmt_strs.append(sb.sentence)
                # If this is not the first sentence, the agents coordinates
                # should be updated
                for ag in sb.agents:
                    ag.update_coords(text_length)
                self.stmt_agents.append(sb.agents)
                # Update the length of the text by adding the length of the new
                # sentence and a space.
                text_length += (len(sb.sentence) + 1)
            else:
                # If sentence wasn't built, add empty list of agents to keep
                # consistent structure with statements.
                self.stmt_agents.append([])
        if stmt_strs:
            return ' '.join(stmt_strs)
        else:
            return ''


class AgentWithCoordinates():
    """English representation of an agent.

    Parameters
    ----------
    agent_str : str
        Full English description of an agent.
    name : str
        Name of an agent.
    db_refs : dict
        Dictionary of database identifiers associated with this agent.
    coords : tuple(int)
        A tuple of integers representing coordinates of agent name in a text.
        If not provided, coords will be set to coordinates of name in
        agent_str. When AgentWithCoordinates is a part of SentenceBuilder or
        EnglishAssembler, the coords represent the location of agent name in
        the SentenceBuilder.sentence or EnglishAssembler.model.
    """
    def __init__(self, agent_str, name, db_refs, coords=None):
        self.agent_str = agent_str
        self.name = name
        self.db_refs = db_refs
        self.coords = coords if coords else (
            agent_str.find(name), agent_str.find(name) + len(name))

    def update_coords(self, shift_by):
        """Update coordinates by shifting them by a given number of characters.

        Parameters
        ----------
        shift_by : int
            How many characters to shift the parameters by.
        """
        current_coords = self.coords
        self.coords = (current_coords[0] + shift_by,
                       current_coords[1] + shift_by)


class SentenceBuilder():
    """Builds a sentence from agents and strings.

    Attributes
    ----------
    agents : list[AgentWithCoordinates]
        A list of AgentWithCoordinates objects that are part of a sentence.
        The coordinates of the agent name are being dynamically updated as the
        sentence is being constructed.
    sentence : str
        A sentence that is being built by the builder.
    """
    def __init__(self):
        self.agents = []
        self.sentence = ''

    def append(self, element):
        """Append an element to the end of the sentence.

        Parameters
        ----------<commit_msg>Add string representation to AgentWithCoordinates<commit_after>from __future__ import absolute_import, print_function, unicode_literals
from builtins import dict, str
import logging
import indra.statements as ist

logger = logging.getLogger(__name__)


class EnglishAssembler(object):
    """This assembler generates English sentences from INDRA Statements.

    Parameters
    ----------
    stmts : Optional[list[indra.statements.Statement]]
        A list of INDRA Statements to be added to the assembler.

    Attributes
    ----------
    statements : list[indra.statements.Statement]
        A list of INDRA Statements to assemble.
    model : str
        The assembled sentences as a single string.
    stmt_agents : list[list[AgentWithCoordinates]]
        A list containing lists of AgentWithCoordinates objects for each of
        the assembled statements. Coordinates represent the location of
        agents in the model.
    """
    def __init__(self, stmts=None):
        if stmts is None:
            self.statements = []
        else:
            self.statements = stmts
        self.model = None
        self.stmt_agents = []

    def add_statements(self, stmts):
        """Add INDRA Statements to the assembler's list of statements.

        Parameters
        ----------
        stmts : list[indra.statements.Statement]
            A list of :py:class:`indra.statements.Statement`
            to be added to the statement list of the assembler.
        """
        self.statements += stmts

    def make_model(self):
        """Assemble text from the set of collected INDRA Statements.

        Returns
        -------
        stmt_strs : str
            Return the assembled text as unicode string. By default, the text
            is a single string consisting of one or more sentences with
            periods at the end.
        """
        stmt_strs = []
        # Keep track of current length of the model text.
        text_length = 0
        for stmt in self.statements:
            sb = None
            # Get a SentenceBuilder object per statement
            if isinstance(stmt, ist.Modification):
                sb = _assemble_modification(stmt)
            elif isinstance(stmt, ist.Autophosphorylation):
                sb = _assemble_autophosphorylation(stmt)
            elif isinstance(stmt, ist.Association):
                sb = _assemble_association(stmt)
            elif isinstance(stmt, ist.Complex):
                sb = _assemble_complex(stmt)
            elif isinstance(stmt, ist.Influence):
                sb = _assemble_influence(stmt)
            elif isinstance(stmt, ist.RegulateActivity):
                sb = _assemble_regulate_activity(stmt)
            elif isinstance(stmt, ist.RegulateAmount):
                sb = _assemble_regulate_amount(stmt)
            elif isinstance(stmt, ist.ActiveForm):
                sb = _assemble_activeform(stmt)
            elif isinstance(stmt, ist.Translocation):
                sb = _assemble_translocation(stmt)
            elif isinstance(stmt, ist.Gef):
                sb = _assemble_gef(stmt)
            elif isinstance(stmt, ist.Gap):
                sb = _assemble_gap(stmt)
            elif isinstance(stmt, ist.Conversion):
                sb = _assemble_conversion(stmt)
            else:
                logger.warning('Unhandled statement type: %s.' % type(stmt))
            if sb:
                stmt_strs.append(sb.sentence)
                # If this is not the first sentence, the agents coordinates
                # should be updated
                for ag in sb.agents:
                    ag.update_coords(text_length)
                self.stmt_agents.append(sb.agents)
                # Update the length of the text by adding the length of the new
                # sentence and a space.
                text_length += (len(sb.sentence) + 1)
            else:
                # If sentence wasn't built, add empty list of agents to keep
                # consistent structure with statements.
                self.stmt_agents.append([])
        if stmt_strs:
            return ' '.join(stmt_strs)
        else:
            return ''


class AgentWithCoordinates():
    """English representation of an agent.

    Parameters
    ----------
    agent_str : str
        Full English description of an agent.
    name : str
        Name of an agent.
    db_refs : dict
        Dictionary of database identifiers associated with this agent.
    coords : tuple(int)
        A tuple of integers representing coordinates of agent name in a text.
        If not provided, coords will be set to coordinates of name in
        agent_str. When AgentWithCoordinates is a part of SentenceBuilder or
        EnglishAssembler, the coords represent the location of agent name in
        the SentenceBuilder.sentence or EnglishAssembler.model.
    """
    def __init__(self, agent_str, name, db_refs, coords=None):
        self.agent_str = agent_str
        self.name = name
        self.db_refs = db_refs
        self.coords = coords if coords else (
            agent_str.find(name), agent_str.find(name) + len(name))

    def update_coords(self, shift_by):
        """Update coordinates by shifting them by a given number of characters.

        Parameters
        ----------
        shift_by : int
            How many characters to shift the parameters by.
        """
        current_coords = self.coords
        self.coords = (current_coords[0] + shift_by,
                       current_coords[1] + shift_by)

    def __repr__(self):
        return str(self)

    def __str__(self):
        return 'AgentWithCoordinates(%s (%s), coords=%s)' % (
            self.agent_str, self.name, self.coords)


class SentenceBuilder():
    """Builds a sentence from agents and strings.

    Attributes
    ----------
    agents : list[AgentWithCoordinates]
        A list of AgentWithCoordinates objects that are part of a sentence.
        The coordinates of the agent name are being dynamically updated as the
        sentence is being constructed.
    sentence : str
        A sentence that is being built by the builder.
    """
    def __init__(self):
        self.agents = []
        self.sentence = ''

    def append(self, element):
        """Append an element to the end of the sentence.

        Parameters
        ----------
{'fraction_non_alphanumeric': 0.0770281124497992, 'fraction_numerical': 0.000642570281124498, 'mean_word_length': 1.912514619883041, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '5434178', 'n_tokens_mistral': 3295, 'n_tokens_neox': 3098, 'n_words': 1069}