Ejemplo n.º 1
0
def _compute_diagnostic_text(
        scoring_project: scoring.ScoringProject, unused_overall_score: float) \
        -> Tuple[str, List[int]]:
    """Create the left-side text of the diagnostic for a given project.

    Returns:
        A tuple containing the text,
        and a list of the orders of missing sentences (if text is empty).
    """

    sentences = []
    missing_sentences_orders = []
    templates_per_order = itertools.groupby(
        _SENTENCE_TEMPLATES.get_collection(scoring_project.database),
        key=lambda template: template.order)
    for order, templates_iterator in templates_per_order:
        templates = list(templates_iterator)
        template = next(
            scoring.filter_using_score(templates,
                                       lambda template: template.filters,
                                       scoring_project), None)
        if not template:
            if any(template.optional for template in templates):
                continue
            # TODO(pascal): Set to warning when we have theoretical complete coverage.
            logging.debug('Could not find a sentence %d for user.', order)
            missing_sentences_orders.append(order)
            continue
        translated_template = scoring_project.translate_string(
            template.sentence_template)
        sentences.append(
            scoring_project.populate_template(translated_template))
    return '\n\n'.join(
        sentences
    ) if not missing_sentences_orders else '', missing_sentences_orders
Ejemplo n.º 2
0
def _compute_diagnostic_overall(
    project: scoring.ScoringProject, diagnostic: diagnostic_pb2.Diagnostic,
    category: Optional[diagnostic_pb2.DiagnosticCategory]
) -> diagnostic_pb2.Diagnostic:
    all_overalls = _DIAGNOSTIC_OVERALL.get_collection(project.database)
    restricted_overalls: Iterable[diagnostic_pb2.DiagnosticTemplate] = []
    if category and (not category.are_strategies_for_alpha_only
                     or project.features_enabled.alpha):
        restricted_overalls = \
            [o for o in all_overalls if o.category_id == category.category_id]
    if not restricted_overalls:
        restricted_overalls = [o for o in all_overalls if not o.category_id]
    overall_template = next((scoring.filter_using_score(
        restricted_overalls, lambda t: t.filters, project)), None)
    if not overall_template:
        # TODO(cyrille): Put a warning here once enough cases are covered with overall templates.
        return diagnostic
    diagnostic.overall_sentence = project.populate_template(
        project.translate_string(overall_template.sentence_template))
    diagnostic.text = project.populate_template(
        project.translate_string(overall_template.text_template))
    diagnostic.strategies_introduction = project.populate_template(
        project.translate_string(overall_template.strategies_introduction))
    diagnostic.overall_score = overall_template.score
    return diagnostic
Ejemplo n.º 3
0
    def test_multiple_filters(self):
        """Filter an item with multiple filters."""

        get_scoring_func = mock.MagicMock()
        get_scoring_func.return_value = ['test-two', 'test-zero']
        filtered = scoring.filter_using_score([42], get_scoring_func, None)
        self.assertEqual([], list(filtered))
Ejemplo n.º 4
0
    def test_unknown_filter(self):
        """Filter an item with an unknown filter."""

        get_scoring_func = mock.MagicMock()
        get_scoring_func.return_value = ['unknown-filter']
        filtered = scoring.filter_using_score([42], get_scoring_func, None)
        self.assertEqual([42], list(filtered))
Ejemplo n.º 5
0
    def test_filter_list_constant_scorer(self):
        """Filter a list returning constant scorer."""

        get_scoring_func = mock.MagicMock()
        get_scoring_func.side_effect = [['test-zero'], ['test-two'],
                                        ['test-zero']]
        filtered = scoring.filter_using_score(range(3), get_scoring_func, None)
        self.assertEqual([1], list(filtered))
Ejemplo n.º 6
0
def _compute_diagnostic_overall(
    project: scoring.ScoringProject, diagnostic: diagnostic_pb2.Diagnostic,
    main_challenge: diagnostic_pb2.DiagnosticMainChallenge
) -> diagnostic_pb2.Diagnostic:
    all_overalls = _DIAGNOSTIC_OVERALL.get_collection(project.database)
    restricted_overalls = [
        o for o in all_overalls if o.category_id == main_challenge.category_id
    ]
    try:
        overall_template = next(
            (scoring.filter_using_score(restricted_overalls,
                                        lambda t: t.filters, project)))
    except StopIteration:
        logging.warning('No overall template for project: %s',
                        main_challenge.category_id)
        return diagnostic
    diagnostic.overall_sentence = project.populate_template(
        project.translate_airtable_string(
            'diagnosticOverall',
            overall_template.id,
            'sentence_template',
            is_genderized=True,
            hint=overall_template.sentence_template))
    diagnostic.text = project.populate_template(
        project.translate_airtable_string('diagnosticOverall',
                                          overall_template.id,
                                          'text_template',
                                          is_genderized=True,
                                          hint=overall_template.text_template))
    diagnostic.strategies_introduction = project.populate_template(
        project.translate_airtable_string(
            'diagnosticOverall',
            overall_template.id,
            'strategies_introduction',
            is_genderized=True,
            hint=overall_template.strategies_introduction))
    diagnostic.overall_score = overall_template.score
    diagnostic.bob_explanation = main_challenge.bob_explanation

    all_responses = _DIAGNOSTIC_RESPONSES.get_collection(project.database)
    self_diagnostic_category_id = project.details.original_self_diagnostic.category_id
    response_id = f'{self_diagnostic_category_id}:{main_challenge.category_id}'
    response_text = next(
        (response.text
         for response in all_responses if response.response_id == response_id),
        '')
    diagnostic.response = project.translate_airtable_string(
        'diagnosticResponses',
        response_id,
        'text',
        is_genderized=True,
        hint=response_text)

    return diagnostic
Ejemplo n.º 7
0
def compute_sub_diagnostic_observations(
        scoring_project: scoring.ScoringProject, topic: diagnostic_pb2.DiagnosticTopic) \
        -> Iterator[diagnostic_pb2.SubDiagnosticObservation]:
    """Find all relevant observations for a given sub-diagnostic topic."""

    templates = scoring.filter_using_score(
        (template
         for template in _SUBTOPIC_OBSERVATION_TEMPLATES.get_collection(
             scoring_project.database) if template.topic == topic),
        lambda template: template.filters, scoring_project)
    for template in templates:
        yield diagnostic_pb2.SubDiagnosticObservation(
            text=scoring_project.populate_template(
                scoring_project.translate_string(template.sentence_template)),
            is_attention_needed=template.is_attention_needed)
Ejemplo n.º 8
0
def list_all_tips(
        user: user_pb2.User, project: project_pb2.Project,
        piece_of_advice: project_pb2.Advice,
        database: pymongo_database.Database
) -> List[action_pb2.ActionTemplate]:
    """List all available tips for a piece of advice.

    Args:
        user: the full user info.
        project: the project to give tips for.
        piece_of_advice: the piece of advice to give tips for.
        database: access to the database to get modules and tips.
    Returns:
        An iterable of tips for this module.
    """

    try:
        module = next(m for m in _advice_modules(database)
                      if m.advice_id == piece_of_advice.advice_id)
    except StopIteration:
        logging.warning('Advice module %s does not exist anymore',
                        piece_of_advice.advice_id)
        return []

    # Get tip templates.
    all_tip_templates = _tip_templates(database)
    tip_templates = filter(None, (all_tip_templates.get(t)
                                  for t in module.tip_template_ids))

    # Filter tips.
    scoring_project = scoring.ScoringProject(project,
                                             user,
                                             database,
                                             now=now.get())
    filtered_tips = scoring.filter_using_score(tip_templates,
                                               lambda t: t.filters,
                                               scoring_project)

    return [_translate_tip(tip, scoring_project) for tip in filtered_tips]
Ejemplo n.º 9
0
def _compute_sub_diagnostic_text(
        scoring_project: scoring.ScoringProject, sub_diagnostic: diagnostic_pb2.SubDiagnostic) \
        -> str:
    """Create the sentence of the diagnostic for a given project on a given topic.

    Returns:
        The text for the diagnostic submetric.
    """

    template = next(
        scoring.filter_using_score(
            (template
             for template in _SUBTOPIC_SENTENCE_TEMPLATES.get_collection(
                 scoring_project.database)
             if template.topic == sub_diagnostic.topic),
            lambda template: template.filters, scoring_project), None)
    if not template:
        # TODO(cyrille): Change to warning once we have theoretical complete coverage.
        logging.debug('Could not find a sentence for topic %s for user.',
                      sub_diagnostic.topic)
        return ''
    translated_template = scoring_project.translate_string(
        template.sentence_template)
    return scoring_project.populate_template(translated_template)
Ejemplo n.º 10
0
    def test_filter_list_with_no_filters(self) -> None:
        """Filter a list with no filters to apply."""

        filtered = scoring.filter_using_score(range(5), lambda a: [],
                                              self.dummy_project)
        self.assertEqual([0, 1, 2, 3, 4], list(filtered))