<commit_before># -*- coding: utf-8 -*-

import logging
import uuid

from django import forms
from django.core.urlresolvers import reverse
from django.forms import models
from django.utils.safestring import mark_safe

from survey.models import (AnswerBase, AnswerInteger, AnswerRadio,
                           AnswerSelect, AnswerSelectMultiple, AnswerText,
                           Question, Response)
from survey.models.answer import get_real_type_answer
from survey.signals import survey_completed
from survey.widgets import ImageSelectWidget

LOGGER = logging.getLogger(__name__)


class HorizontalRadioRenderer(forms.RadioSelect.renderer):
    # Blatantly stolen from http://stackoverflow.com/questions/5935546/
    def render(self):
        return mark_safe(u'\n'.join([u'%s\n' % w for w in self]))


class HorizontalCheckboxRenderer(forms.RadioSelect.renderer):
    # Obviously an horrible hack based on HorizontalRadioRenderer.
    def render(self):
        return mark_safe(
            u'\n'.join(
                [u'{}\n'.format(w).replace("radio", "checkbox") for w in self]
            )
        )


class SelectMultipleHorizontal(forms.CheckboxSelectMultiple):
    renderer = HorizontalCheckboxRenderer


class ResponseForm(models.ModelForm):

    class Meta(object):
        model = Response
        fields = ()

    def __init__(self, *args, **kwargs):
        """ Expects a survey object to be passed in initially """
        self.survey = kwargs.pop('survey')
        self.user = kwargs.pop('user')
        try:
            self.step = int(kwargs.pop('step'))
        except KeyError:
            self.step = None
        super(ResponseForm, self).__init__(*args, **kwargs)
        self.uuid = uuid.uuid4().hex
        self.steps_count = len(self.survey.questions())
        # add a field for each survey question, corresponding to the question
        # type as appropriate.
        data = kwargs.get('data')
        for i, question in enumerate(self.survey.questions()):
            if self.survey.display_by_question and i != self.step and self.step is not None:
                continue
            else:
                self.add_question(question, data)

    def _get_preexisting_response(self):
        """ Recover a pre-existing response in database.

        The user must be logged.
        :rtype: Response or None"""
        if not self.user.is_authenticated():
            return None
        try:
            return Response.objects.get(user=self.user, survey=self.survey)
        except Response.DoesNotExist:
            LOGGER.debug("No saved response for '%s' for user %s",
                         self.survey, self.user)
            return None

    def _get_preexisting_answer(self, question):
        """ Recover a pre-existing answer in database.

        The user must be logged. A Response containing the Answer must exists.

        :param Question question: The question we want to recover in the
        response.
        :rtype: Answer or None"""
        response = self._get_preexisting_response()
        if response is None:
            return None
        try:
            base_answer = AnswerBase.objects.get(question=question,
                                                 response=response)
            return get_real_type_answer(base_answer)
        except AnswerBase.DoesNotExist:
            return None

    def get_question_initial(self, question, data):
        """ Get the initial value that we should use in the Form

        :param Question question: The question
        :param dict data: Value from a POST request.
        :rtype: String or None  """
        initial = None
        answer = self._get_preexisting_answer(question)
        if answer:
            # Initialize the field with values from the database if any
            if answer is AnswerSelectMultiple:
                initial = list(answer.body)
            else:
                initial = answer.body
        if data:
            # Initialize the field field from a POST request, if any.
            # Replace values from the database
            initial = data.get('question_%d' % question.pk)
        return initial

    def get_question_widget(self, question):
        """ Return the widget we should use for a question.

        :param Question question: The question
        :rtype: django.forms.widget or None """
        widget = None
        if question.type == Question.TEXT:
            widget = forms.Textarea
        elif question.type == Question.SHORT_TEXT:
            widget = forms.TextInput
        elif question.type == Question.RADIO:
            widget = forms.RadioSelect(renderer=HorizontalRadioRenderer)
        elif question.type == Question.SELECT:
            widget = forms.Select
        elif question.type == Question.SELECT_IMAGE:
            widget = ImageSelectWidget
        elif question.type == Question.SELECT_MULTIPLE:
            widget = SelectMultipleHorizontal
        return widget

    def get_question_choices(self, question):
        """ Return the choices we should use for a question.

        :param Question question: The question
        :rtype: List of String or None """
        qchoices = None
        if question.type not in [Question.TEXT, Question.SHORT_TEXT,
                                 Question.INTEGER]:
            qchoices = question.get_choices()
            # add an empty option at the top so that the user has to explicitly
            # select one of the options
            if question.type in [Question.SELECT, Question.SELECT_IMAGE]:
                qchoices = tuple([('', '-------------')]) + qchoices
        return qchoices

    def get_question_field(self, question, **kwargs):
        """ Return the field we should use in our form.

        :param Question question: The question
        :param **kwargs: A dict of parameter properly initialized in
            add_question.
        :rtype: django.forms.fields """
        if question.type in [Question.TEXT, Question.SHORT_TEXT]:
            field = forms.CharField(**kwargs)
        elif question.type in [Question.SELECT_MULTIPLE]:
            field = forms.MultipleChoiceField(**kwargs)
        elif question.type in [Question.INTEGER]:
            field = forms.IntegerField(**kwargs)
        else:
            field = forms.ChoiceField(**kwargs)
        return field

    def add_question(self, question, data):
        """ Add a question to the form.

        :param Question question: The question to add.
        :param dict data: The pre-existing values from a post request. """
        kwargs = {"label": question.text,
                  "required": question.required, }
        initial = self.get_question_initial(question, data)
        if initial:
            kwargs["initial"] = initial
        choices = self.get_question_choices(question)
        if choices:
            kwargs["choices"] = choices<commit_msg>Refactor - Using dict instead of tons of elif<commit_after># -*- coding: utf-8 -*-

import logging
import uuid

from django import forms
from django.core.urlresolvers import reverse
from django.forms import models
from django.utils.safestring import mark_safe

from survey.models import (AnswerBase, AnswerInteger, AnswerRadio,
                           AnswerSelect, AnswerSelectMultiple, AnswerText,
                           Question, Response)
from survey.models.answer import get_real_type_answer
from survey.signals import survey_completed
from survey.widgets import ImageSelectWidget

LOGGER = logging.getLogger(__name__)


class HorizontalRadioRenderer(forms.RadioSelect.renderer):
    # Blatantly stolen from http://stackoverflow.com/questions/5935546/
    def render(self):
        return mark_safe(u'\n'.join([u'%s\n' % w for w in self]))


class HorizontalCheckboxRenderer(forms.RadioSelect.renderer):
    # Obviously an horrible hack based on HorizontalRadioRenderer.
    def render(self):
        return mark_safe(
            u'\n'.join(
                [u'{}\n'.format(w).replace("radio", "checkbox") for w in self]
            )
        )


class SelectMultipleHorizontal(forms.CheckboxSelectMultiple):
    renderer = HorizontalCheckboxRenderer


class ResponseForm(models.ModelForm):

    WIDGETS = {
        Question.TEXT: forms.Textarea,
        Question.SHORT_TEXT: forms.TextInput,
        Question.RADIO: forms.RadioSelect(renderer=HorizontalRadioRenderer),
        Question.SELECT: forms.Select,
        Question.SELECT_IMAGE: ImageSelectWidget,
        Question.SELECT_MULTIPLE: SelectMultipleHorizontal,
    }

    class Meta(object):
        model = Response
        fields = ()

    def __init__(self, *args, **kwargs):
        """ Expects a survey object to be passed in initially """
        self.survey = kwargs.pop('survey')
        self.user = kwargs.pop('user')
        try:
            self.step = int(kwargs.pop('step'))
        except KeyError:
            self.step = None
        super(ResponseForm, self).__init__(*args, **kwargs)
        self.uuid = uuid.uuid4().hex
        self.steps_count = len(self.survey.questions())
        # add a field for each survey question, corresponding to the question
        # type as appropriate.
        data = kwargs.get('data')
        for i, question in enumerate(self.survey.questions()):
            if self.survey.display_by_question and i != self.step and self.step is not None:
                continue
            else:
                self.add_question(question, data)

    def _get_preexisting_response(self):
        """ Recover a pre-existing response in database.

        The user must be logged.
        :rtype: Response or None"""
        if not self.user.is_authenticated():
            return None
        try:
            return Response.objects.get(user=self.user, survey=self.survey)
        except Response.DoesNotExist:
            LOGGER.debug("No saved response for '%s' for user %s",
                         self.survey, self.user)
            return None

    def _get_preexisting_answer(self, question):
        """ Recover a pre-existing answer in database.

        The user must be logged. A Response containing the Answer must exists.

        :param Question question: The question we want to recover in the
        response.
        :rtype: Answer or None"""
        response = self._get_preexisting_response()
        if response is None:
            return None
        try:
            base_answer = AnswerBase.objects.get(question=question,
                                                 response=response)
            return get_real_type_answer(base_answer)
        except AnswerBase.DoesNotExist:
            return None

    def get_question_initial(self, question, data):
        """ Get the initial value that we should use in the Form

        :param Question question: The question
        :param dict data: Value from a POST request.
        :rtype: String or None  """
        initial = None
        answer = self._get_preexisting_answer(question)
        if answer:
            # Initialize the field with values from the database if any
            if answer is AnswerSelectMultiple:
                initial = list(answer.body)
            else:
                initial = answer.body
        if data:
            # Initialize the field field from a POST request, if any.
            # Replace values from the database
            initial = data.get('question_%d' % question.pk)
        return initial

    def get_question_widget(self, question):
        """ Return the widget we should use for a question.

        :param Question question: The question
        :rtype: django.forms.widget or None """
        try:
            return self.WIDGETS[question.type]
        except KeyError:
            return None

    def get_question_choices(self, question):
        """ Return the choices we should use for a question.

        :param Question question: The question
        :rtype: List of String or None """
        qchoices = None
        if question.type not in [Question.TEXT, Question.SHORT_TEXT,
                                 Question.INTEGER]:
            qchoices = question.get_choices()
            # add an empty option at the top so that the user has to explicitly
            # select one of the options
            if question.type in [Question.SELECT, Question.SELECT_IMAGE]:
                qchoices = tuple([('', '-------------')]) + qchoices
        return qchoices

    def get_question_field(self, question, **kwargs):
        """ Return the field we should use in our form.

        :param Question question: The question
        :param **kwargs: A dict of parameter properly initialized in
            add_question.
        :rtype: django.forms.fields """
        FIELDS = {
            Question.TEXT: forms.CharField,
            Question.SHORT_TEXT: forms.CharField,
            Question.SELECT_MULTIPLE: forms.MultipleChoiceField,
            Question.INTEGER: forms.IntegerField
        }
        try:
            return FIELDS[question.type](**kwargs)
        except KeyError:
            return forms.ChoiceField(**kwargs)

    def add_question(self, question, data):
        """ Add a question to the form.

        :param Question question: The question to add.
        :param dict data: The pre-existing values from a post request. """
        kwargs = {"label": question.text,
                  "required": question.required, }
        initial = self.get_question_initial(question, data)
        if initial:
            kwargs["initial"] = initial
        choices = self.get_question_choices(question)
        if choices:
            kwargs["choices"] = choices
{'fraction_non_alphanumeric': 0.08461143318411976, 'fraction_numerical': 0.001320907022822338, 'mean_word_length': 2.1553600370456123, 'pattern_counts': {'":': 4, '<': 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': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '457278', 'n_tokens_mistral': 3485, 'n_tokens_neox': 3389, 'n_words': 1086}