Exemple #1
0
class MatrixTabularStatistic(BaseMatrixStatistic):
    """Table with the count and percent of answered and unanswered questions,
        diveded per choice. It should be used for matrix questions.
    """

    security = ClassSecurityInfo()

    _constructors = (lambda *args, **kw: manage_addStatistic(MatrixTabularStatistic, *args, **kw), )

    meta_type = "Naaya Survey - Matrix Tabular Statistic"
    meta_label = "Matrix Tabular Statistic"
    meta_sortorder = 300
    meta_description = """Table with the count and percent of answered and unanswered questions,
        diveded per choice. It should be used for matrix questions."""
    icon_filename = 'statistics/www/matrix_tabular_statistic.gif'

    security.declarePublic('render')
    def render(self, answers):
        """Render statistics as HTML code"""
        total, unanswered, per_row_and_choice = self.calculate(self.question, answers)
        return self.page(question=self.question,
                         total=total,
                         unanswered=unanswered,
                         per_row_and_choice=per_row_and_choice)

    page = PageTemplateFile("zpt/matrix_tabular_statistics.zpt", globals())

    security.declarePrivate('add_to_excel')
    def add_to_excel(self, state):
        """ adds content to the excel file based on the specific statistic type """
        import xlwt
        answers = state['answers']
        ws = state['ws']
        current_row = state['current_row']
        translator = self.getSite().getPortalTranslations()
        total, unanswered, per_row_and_choice = self.calculate(self.question, answers)

        #define Excel styles
        header_style = xlwt.easyxf('font: bold on; align: vert centre')
        normal_style = xlwt.easyxf('align: vert centre')

        #write cell elements similarly to the zpt-->html output
        ws.write(current_row, 1, self.question.title, header_style)
        current_row += 1
        current_col = 2
        for choice in self.question.choices:
            ws.write(current_row, current_col, choice, header_style)
            current_col += 1
        ws.write(current_row, current_col, translator('Not answered'), header_style)
        current_row += 1

        for row in self.question.rows:
            r = self.question.rows.index(row)
            ws.write(current_row, 1, row, header_style)
            current_col = 2
            for statistics in per_row_and_choice[r]:
                ws.write(current_row, current_col, '%u (%.2f%%)'
                    % (statistics[0], round(statistics[1], 2)), normal_style)
                current_col += 1
            ws.write(current_row, current_col, '%u (%.2f%%)'
                % (unanswered[r][0], round(unanswered[r][1], 2)), normal_style)
            current_row += 1
        state['current_row'] = current_row
Exemple #2
0
class TextAnswerListing(BaseStatistic):
    """Table with the count and percent of answered and unanswered questions.
    """

    security = ClassSecurityInfo()

    _constructors = (lambda *args, **kw: manage_addStatistic(TextAnswerListing, *args, **kw), )

    meta_type = "Naaya Survey - Text Answer Listing"
    meta_label = "Text Answer Listing"
    meta_description = """Listing with answers posted in 'Paragraph text' and 'Single line text'"""
    meta_sortorder = 100
    icon_filename = 'statistics/www/simple_tabular_statistic.gif'

    def __init__(self, id, question, lang=None, **kwargs):
        if not (isinstance(question, StringWidget) or isinstance(question, TextAreaWidget)):
            raise TypeError('Unsupported question type')
        BaseStatistic.__init__(self, id, question, lang=lang, **kwargs)

    def calculate(self, answers):
        """ """
        return self.utSortObjsListByAttr(answers, 'modification_time')

    security.declarePublic('render')
    def render(self, answers):
        """Render statistics as HTML code"""
        
        return self.page(data=self.calculate(answers), question=self.question)

    page = PageTemplateFile("zpt/text_answer_listing.zpt", globals())

    security.declarePrivate('add_to_excel')
    def add_to_excel(self, state):
        """ adds content to the excel file based on the specific statistic type """
        import xlwt
        answers = state['answers']
        ws = state['ws']
        current_row = state['current_row']
        translator = self.getSite().getPortalTranslations()
        data=self.calculate(answers)
        question=self.question

        #define Excel styles
        header_style = xlwt.easyxf('font: bold on; align: vert centre')
        normal_style = xlwt.easyxf('align: vert centre')
        hyper_style = xlwt.easyxf('align: vert centre; font: underline single, color-index blue')

        #write cell elements similarly to the zpt-->html output
        ws.write(current_row, 1, self.question.title, header_style)
        current_row += 1
        ws.write(current_row, 1, translator('User'), header_style)
        ws.write(current_row, 2, translator('Date'), header_style)
        ws.write(current_row, 3, translator('Answer'), header_style)
        current_row += 1

        for answer in data:
            if self.checkPermissionPublishObjects():
                answer_url = answer.absolute_url()
                respondent = answer.get_respondent_name()
                ws.write(current_row, 1, xlwt.Formula('HYPERLINK' + '("%s"; "%s")'
                    % (answer_url, respondent)), hyper_style)
            ws.write(current_row, 2,
                self.utShowDateTime(answer.modification_time), normal_style)

            response = answer.get(question.id, '', lang=self.gl_get_selected_language())
            # try to get any response if multilingual
            if not response:
                all_responses = answer.get(question.id, '')
                if isinstance(all_responses, dict):
                    all_responses = filter(None, all_responses.values())
                    if len(all_responses) > 0:
                        response = all_responses[0]

            ws.write(current_row, 3,
                self.utLinkifyURLs(response) or 'No response.', normal_style)
            current_row += 1

        state['current_row'] = current_row + 1
class SimpleTabularStatistic(BaseStatistic):
    """Table with the count and percent of answered and unanswered questions.
    """

    security = ClassSecurityInfo()

    _constructors = (lambda *args, **kw: manage_addStatistic(SimpleTabularStatistic, *args, **kw), )

    meta_type = "Naaya Survey - Simple Tabular Statistic"
    meta_label = "Simple Tabular Statistic"
    meta_description = """Table with the count and percent of answered and unanswered questions."""
    meta_sortorder = 100
    icon_filename = 'statistics/www/simple_tabular_statistic.gif'

    def __init__(self, id, question, lang=None, **kwargs):
        if isinstance(question, LabelWidget):
            raise TypeError('Unsupported question type')
        BaseStatistic.__init__(self, id, question, lang=lang, **kwargs)

    def calculate(self, question, answers):
        """ -> (total, answered, unanswered)"""
        w_id = question.getWidgetId()
        total = answered_count = 0
        for answer in answers:
            val = answer.get(w_id)
            if val:
                answered_count += 1
            total += 1

        unanswered_count = total - answered_count
        if total:
            answered_percent = 100.0 * answered_count / total
            unanswered_percent = 100.0 * unanswered_count / total
        else:
            answered_percent = unanswered_percent = 0
        return (total,
                (answered_count, answered_percent),
                (unanswered_count, unanswered_percent))

    security.declarePublic('render')
    def render(self, answers):
        """Render statistics as HTML code"""
        total, answered, unanswered = self.calculate(self.question, answers)
        return self.page(question=self.question,
                         total=total,
                         answered=answered,
                         unanswered=unanswered)

    page = PageTemplateFile("zpt/simple_tabular_statistics.zpt", globals())

    security.declarePrivate('add_to_excel')
    def add_to_excel(self, state):
        """ adds content to the excel file based on the specific statistic type """
        answers = state['answers']
        ws = state['ws']
        current_row = state['current_row']
        translator = self.getSite().getPortalTranslations()
        total, answered, unanswered = self.calculate(self.question, answers)

        #define Excel styles
        header_style = xlwt.easyxf('font: bold on; align: vert centre')
        normal_style = xlwt.easyxf('align: vert centre')

        #write cell elements similarly to the zpt-->html output
        ws.write(current_row, 1, self.question.title, header_style)
        current_row += 1
        ws.write(current_row, 2, translator('Count'), header_style)
        ws.write(current_row, 3, translator('Percent'), header_style)
        current_row += 1
        ws.write(current_row, 1, translator('Answered'), header_style)
        ws.write(current_row, 2, answered[0], normal_style)
        ws.write(current_row, 3, '%.2f%%'
            % (round(answered[1], 2), ), normal_style)
        current_row += 1
        ws.write(current_row, 1, translator('Not answered'), header_style)
        ws.write(current_row, 2, unanswered[0], normal_style)
        ws.write(current_row, 3, '%.2f%%'
            % (round(unanswered[1], 2), ), normal_style)
        current_row += 1
        ws.write(current_row, 1, translator('Total'), header_style)
        ws.write(current_row, 2, total, normal_style)
        ws.write(current_row, 3, '100%%', normal_style)
        current_row += 1

        state['current_row'] = current_row
Exemple #4
0
class ComboboxMatrixTabularStatistic(BaseStatistic):
    """Table with the count and percent of answered and unanswered questions,
        diveded per row and choice. It should be used for combobox matrix questions.
    """

    security = ClassSecurityInfo()

    _constructors = (lambda *args, **kw: manage_addStatistic(
        ComboboxMatrixTabularStatistic, *args, **kw), )

    meta_type = "Naaya Survey - Combobox Matrix Tabular Statistic"
    meta_label = "Combobox Matrix Tabular Statistic"
    meta_sortorder = 320
    meta_description = """Table with the count and percent of answered and
        unanswered questions, diveded per row and choice. It should be used
        for combobox matrix questions."""
    icon_filename = 'statistics/www/matrix_tabular_statistic.gif'

    def __init__(self, id, question, lang=None, **kwargs):
        if not isinstance(question, ComboboxMatrixWidget):
            raise TypeError('Unsupported question type')
        BaseStatistic.__init__(self, id, question, lang=lang, **kwargs)

    def calculate(self, question, answers):
        """ -> (total, answered, unanswered, per_choice)"""
        w_id = question.getWidgetId()
        total = answered_count = 0
        per_row_and_choice_count = [[[0
            for v in question.values]
            for c in question.choices]
            for r in question.rows]
        unanswered_count = [[0
            for c in question.choices]
            for r in question.rows]
        for answer in answers:
            total += 1
            answer = answer.get(w_id)
            if answer is None:
                for r in range(len(question.rows)):
                    for c in range(len(question.choices)):
                        unanswered_count[r][c] += 1
                continue
            for r, per_row_choices in enumerate(answer):
                for c, value in enumerate(per_row_choices):
                    if value:
                        per_row_and_choice_count[r][c][value] += 1
                    else:
                        unanswered_count[r][c] += 1

        if total:
            unanswered_stats = [[(x, 100.0 * x / total)
                for x in row]
                for row in unanswered_count]
            per_row_and_choice_stats = [[[(i, 100.0 * i / total)
                for i in per_value_count]
                for per_value_count in per_choice_count]
                for per_choice_count in per_row_and_choice_count]
        else:
            unanswered_stats = [[(0, 0.0)
                for x in row]
                for row in unanswered_count]
            per_row_and_choice_stats = [[[(0, 0.0)
                for i in per_value_count]
                for per_value_count in per_choice_count]
                for per_choice_count in per_row_and_choice_count]

        return (total, unanswered_stats, per_row_and_choice_stats)

    security.declarePublic('render')
    def render(self, answers):
        """Render statistics as HTML code"""
        total, unanswered, per_row_and_choice = self.calculate(self.question, answers)
        return self.page(question=self.question,
                         total=total,
                         unanswered=unanswered,
                         per_row_and_choice=per_row_and_choice)

    page = PageTemplateFile("zpt/combobox_matrix_tabular_statistics.zpt", globals())

    security.declarePrivate('add_to_excel')
    def add_to_excel(self, state):
        """ adds content to the excel file based on the specific statistic type """
        import xlwt
        answers = state['answers']
        ws = state['ws']
        current_row = state['current_row']
        translator = self.getSite().getPortalTranslations()
        total, unanswered, per_row_and_choice = self.calculate(self.question, answers)

        #define Excel styles
        header_style = xlwt.easyxf('font: bold on; align: vert centre')
        normal_style = xlwt.easyxf('align: vert centre')
        italic_style = xlwt.easyxf('align: vert centre; font: italic on')

        #write cell elements similarly to the zpt-->html output
        ws.write(current_row, 1, self.question.title, header_style)
        current_row += 1
        ws.write(current_row, 1, translator('row'), italic_style)
        ws.write(current_row, 2, translator('value'), italic_style)
        current_col = 3
        for choice in self.question.choices:
            ws.write(current_row, current_col, choice, header_style)
            current_col += 1
        current_row += 1
        for row in self.question.rows:
            r = self.question.rows.index(row)
            current_col = 1
            ws.write_merge(current_row,
                current_row+len(self.question.values), 1, 1, row, header_style)
            for value in self.question.values:
                v = self.question.values.index(value)
                current_col = 2
                ws.write(current_row, current_col, value, header_style)
                current_col += 1
                for statistic in per_row_and_choice[r]:
                    ws.write(current_row, current_col, '%u (%.2f%%)'
                        % (statistic[v][0], round(statistic[v][1], 2)), normal_style)
                    current_col += 1
                current_row += 1
            current_col = 2
            ws.write(current_row, current_col, translator('Not answered'), header_style)
            current_col += 1
            for statistic in unanswered[r]:
                ws.write(current_row, current_col, '%u (%.2f%%)'
                    % (statistic[0], round(statistic[1], 2)), normal_style)
                current_col += 1
            current_row += 1

        state['current_row'] = current_row + 1
Exemple #5
0
class MatrixCssBarChartStatistic(BaseMatrixStatistic):
    """Table with the count and percent of answered and unanswered questions,
        diveded per choice. It should be used for matrix questions.
    """

    security = ClassSecurityInfo()

    _constructors = (lambda *args, **kw: manage_addStatistic(
        MatrixCssBarChartStatistic, *args, **kw),
                     )

    meta_type = "Naaya Survey - Matrix CSS Bar Chart Statistic"
    meta_label = "Matrix CSS Bar Chart Statistic"
    meta_sortorder = 311
    meta_description = """Table with the count and percent of answered and unanswered questions,
        diveded per choice. It should be used for matrix questions."""
    icon_filename = "statistics/www/matrix_css_barchart_statistic.gif"

    security.declarePublic('getColors')

    def getPallete(self, numcolors):
        """Get a pallete of numcolors colors.

            The colors are a list of hexadecimal codes, e.g. '#f0b0d0'.
        """
        h, s, v = 0.01, 0.55, 0.95
        step = float(1 - h) / numcolors
        colors = []
        for i in range(numcolors):
            r, g, b = colorsys.hsv_to_rgb(h, s, v)
            color = "%02x%02x%02x" % tuple([int(x * 255) for x in h, s, v])
            colors.append(color)
            h += step
        return colors

    security.declarePublic('render')

    def render(self, answers):
        """Render statistics as HTML code"""
        total, unanswered, per_row_and_choice = self.calculate(
            self.question, answers)
        return self.page(
            question=self.question,
            total=total,
            unanswered=unanswered,
            per_row_and_choice=per_row_and_choice,
            colors=self.getPallete(len(self.question.choices) + 1))

    page = PageTemplateFile("zpt/matrix_css_barchart_statistics.zpt",
                            globals())

    security.declarePrivate('add_to_excel')

    def add_to_excel(self, state):
        """ adds content to the excel file based on the specific statistic type """
        import xlwt
        temp_folder = state['temp_folder']
        answers = state['answers']
        ws = state['ws']
        current_row = state['current_row']
        translator = self.getSite().getPortalTranslations()
        file_path = os.path.join(os.path.dirname(os.path.dirname(__file__)),
                                 'www', 'barchart.png')
        total, unanswered, per_row_and_choice = self.calculate(
            self.question, answers)
        colors = self.getPallete(len(self.question.choices) + 1)

        #define Excel styles
        header_style = xlwt.easyxf('font: bold on; align: vert centre')
        normal_style = xlwt.easyxf('align: vert centre')

        #write cell elements similarly to the zpt-->html output
        ws.write(current_row, 1, self.question.title, header_style)
        current_row += 1

        for row in self.question.rows:
            r = self.question.rows.index(row)
            ws.write_merge(current_row,
                           current_row + len(self.question.choices), 1, 1, row,
                           header_style)
            for choice in self.question.choices:
                c = self.question.choices.index(choice)
                ws.write(current_row, 2, choice, header_style)
                width = int(per_row_and_choice[r][c][1]) * 2
                height = 12
                if width * height:
                    path = self.set_bitmap_props(file_path, width, height,
                                                 temp_folder)
                    ws.insert_bitmap(path, current_row, 3, 0, 3)
                current_row += 1
            ws.write(current_row, 2, translator('Not answered'), header_style)
            width = int(unanswered[r][1]) * 2
            if width * height:
                path = self.set_bitmap_props(file_path, width, height,
                                             temp_folder)
                ws.insert_bitmap(path, current_row, 3, 0, 3)
            current_row += 2
        state['current_row'] = current_row