<commit_before>#!/usr/bin/env python
from __future__ import division

# -----------------------------------------------------------------------------
# Copyright (c) 2014--, The American Gut Development Team.
#
# Distributed under the terms of the BSD 3-clause License.
#
# The full license is in the file LICENSE, distributed with this software.
# -----------------------------------------------------------------------------

from itertools import groupby
from operator import itemgetter

from wtforms import (SelectField, SelectMultipleField, widgets,
                     TextAreaField, TextField)

from amgut import AMGUT_CONFIG, db_conn


_LOCALE_TO_COLUMN = {'american_gut': 'american',
                     'british_gut': 'british'}


_LOCALE_COLUMN = _LOCALE_TO_COLUMN[AMGUT_CONFIG.locale]


class Question(object):
    _survey_question_table = 'survey_question'
    _question_response_table = 'survey_question_response'
    _response_table = 'survey_response'
    _response_type_table = 'survey_question_response_type'
    _supplemental_survey_table = 'survey_question_triggered_by'

    def __init__(self, ID, current_response=None):
        self.id = ID

        responses = db_conn.execute_fetchall('''
            select sr.{0}
            from {1} q join {2} qr
                on q.survey_question_id = qr.survey_question_id
            join {3} sr on qr.response = sr.{0}
            where q.survey_question_id = %s
            order by qr.display_index'''.format(
                _LOCALE_COLUMN,
                self._survey_question_table,
                self._question_response_table,
                self._response_table),
            [self.id])

        self.responses = [row[0] for row in responses]

        if not responses:
            self.responses = None

        self.response_type = db_conn.execute_fetchone('''
            select survey_response_type from {0}
            where survey_question_id = %s'''.format(
                self._response_type_table),
            [self.id])[0]

        self.question = db_conn.execute_fetchone('''
            select {0}
            from {1}
            where survey_question_id = %s'''.format(
                _LOCALE_COLUMN,
                self._survey_question_table),
                [self.id])[0]

    @property
    def triggered_by(self):
        """What other question-response combinations trigger this question

        Returns
        -------
        dict
            {other_question_id: [triggering responses to that question], ...}
        """
        trigger_list = db_conn.execute_fetchall('''
            select trigger_question, trigger_response
            from survey_question_triggered_by
            where survey_question_id = %s
            order by trigger_question'''.format(
                self._supplemental_survey_table),
            [self.id])

        return {key: list(group)
                for key, group in groupby(trigger_list, key=itemgetter(0))}

    @property
    def interface_elements(self):
        """Get WTForms interface elements for the question

        Returns
        -------
        list
            A list of the elements that represent the interface to the question
        """
        raise NotImplementedError("To be implemented by quesiton subtypes.")<commit_msg>triggered_by is done once and cached<commit_after>#!/usr/bin/env python
from __future__ import division

# -----------------------------------------------------------------------------
# Copyright (c) 2014--, The American Gut Development Team.
#
# Distributed under the terms of the BSD 3-clause License.
#
# The full license is in the file LICENSE, distributed with this software.
# -----------------------------------------------------------------------------

from itertools import groupby
from operator import itemgetter

from wtforms import (SelectField, SelectMultipleField, widgets,
                     TextAreaField, TextField)

from amgut import AMGUT_CONFIG, db_conn


_LOCALE_TO_COLUMN = {'american_gut': 'american',
                     'british_gut': 'british'}


_LOCALE_COLUMN = _LOCALE_TO_COLUMN[AMGUT_CONFIG.locale]


class Question(object):
    _survey_question_table = 'survey_question'
    _question_response_table = 'survey_question_response'
    _response_table = 'survey_response'
    _response_type_table = 'survey_question_response_type'
    _supplemental_survey_table = 'survey_question_triggered_by'

    def __init__(self, ID, current_response=None):
        self.id = ID

        responses = db_conn.execute_fetchall('''
            select sr.{0}
            from {1} q join {2} qr
                on q.survey_question_id = qr.survey_question_id
            join {3} sr on qr.response = sr.{0}
            where q.survey_question_id = %s
            order by qr.display_index'''.format(
                _LOCALE_COLUMN,
                self._survey_question_table,
                self._question_response_table,
                self._response_table),
            [self.id])

        self.responses = [row[0] for row in responses]

        if not responses:
            self.responses = None

        self.response_type = db_conn.execute_fetchone('''
            select survey_response_type from {0}
            where survey_question_id = %s'''.format(
                self._response_type_table),
            [self.id])[0]

        self.question = db_conn.execute_fetchone('''
            select {0}
            from {1}
            where survey_question_id = %s'''.format(
                _LOCALE_COLUMN,
                self._survey_question_table),
                [self.id])[0]

        self.triggered_by = self._triggered_by()

    def _triggered_by(self):
        """What other question-response combinations trigger this question

        Returns
        -------
        dict
            {other_question_id: [triggering responses to that question], ...}
        """
        trigger_list = db_conn.execute_fetchall('''
            select trigger_question, trigger_response
            from survey_question_triggered_by
            where survey_question_id = %s
            order by trigger_question'''.format(
                self._supplemental_survey_table),
            [self.id])

        return {key: list(group)
                for key, group in groupby(trigger_list, key=itemgetter(0))}

    @property
    def interface_elements(self):
        """Get WTForms interface elements for the question

        Returns
        -------
        list
            A list of the elements that represent the interface to the question
        """
        raise NotImplementedError("To be implemented by quesiton subtypes.")
{'fraction_non_alphanumeric': 0.12654413980114493, 'fraction_numerical': 0.005122024706236818, 'mean_word_length': 1.9054704595185996, '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': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5192818', 'n_tokens_mistral': 1838, 'n_tokens_neox': 1760, 'n_words': 441}