def response_rate_text(records):
    """
    The response rate of the user (between 0 and 1).

    Considers text-conversations which began with an incoming text. The response
    rate is the fraction of such conversations in which the user sent a text
    (a response).

    The following sequence of messages defines four conversations (``I`` for an
    incoming text, ``O`` for an outgoing text): ::

        I-O-I-O => Started with an incoming text and at least one outgoing text
        I-I-O-I => Started with an incoming text and at least one outgoing text
        I-I-I-I => Started with an incoming text but doesn't have outgoing texts
        O-O-I-O => Not starting with an incoming text

    Here, the ratio would be 2/3 as we have 3 conversations starting with an
    incoming text and 2 of them have at least one outgoing text.

    See :ref:`Using bandicoot <conversations-label>` for a definition of
    conversations.
    """
    if len(records) == 0:
        return None

    interactions = defaultdict(list)
    for r in records:
        interactions[r.correspondent_id].append(r)

    def _response_rate(grouped):
        received, responded = 0, 0
        conversations = _conversations(grouped)

        for conv in conversations:
            if len(conv) != 0:
                first = conv[0]
                if first.direction == 'in' and first.interaction == 'text':
                    received += 1
                    if any((i.direction == 'out' for i in conv)):
                        responded += 1

        return responded, received

    # Group all records by their correspondent, and compute the response rate
    # for each
    all_couples = map(_response_rate, list(interactions.values()))
    responded, received = map(sum, list(zip(*all_couples)))

    return responded / received if received != 0 else None