# HG changeset patch # User Paul Boddie # Date 1227568027 -3600 # Node ID c48af72fbd716f2af1a70cdb80d84d7de423df25 # Parent f7237bce02602e9dd0130bf609d2a25c89207e4d Added a script for collecting responses, although it needs some work to be generally usable. Additional work on the schema is also required in order to make writing such scripts easier. diff -r f7237bce0260 -r c48af72fbd71 examples/Common/QuestionPlayer/collect_responses.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/Common/QuestionPlayer/collect_responses.py Tue Nov 25 00:07:07 2008 +0100 @@ -0,0 +1,105 @@ +#!/usr/bin/env python + +""" +Collect responses from multiple answer files. +""" + +from XSLForms.Resources.WebResources import resources +from glob import glob +import os +import libxml2dom + +question_path = "/questionnaire/question" + +def collect(questions, responses_dir): + answers = {} + for filename in glob(os.path.join(responses_dir, "distilled-*")): + responses = libxml2dom.parse(filename) + collect_answers(answers, questions, responses) + return answers + +def collect_answers(answers, questions, responses): + + # Get a mapping from questions to responses. + + for n, (question, response_question) in enumerate(map(None, questions.xpath(question_path), responses.xpath(question_path))): + + # Each response container can contain a number of responses. + + for response in response_question.xpath("response"): + + # Get the question number (starting from 1) and the selected response, + # if any. + + qn = n + 1 + selected = response.getAttribute("selected") + if selected is None: + continue + + # Determine the selected response and whether a textual answer is + # expected. + + selected = int(selected) + textual_answer = bool(question.xpath("choice[position() = %d]/response-type[@value != 'choice']" % selected)) + + # Collect the answer. + + if not answers.has_key(qn): + answers[qn] = {} + if not answers[qn].has_key(selected): + if textual_answer: + answers[qn][selected] = [] + else: + answers[qn][selected] = 0 + + # Either record counts or specific answers. + + if textual_answer: + text = response.getAttribute("response-text") + if text: + answers[qn][selected].append(text) + else: + answers[qn][selected] += 1 + +if __name__ == "__main__": + resource_dir = resources(__file__) + responses_dir = os.path.join(os.getcwd(), "Responses") + questions = libxml2dom.parse(os.path.join(resource_dir, "questions.xml")) + answers = collect(questions, responses_dir) + + # Get the collected answers in order. + + items = answers.items() + items.sort() + + # Visit each answer record... + + for qn, answers_for_question in items: + question = questions.xpath(question_path + ("[position() = %d]" % qn))[0] + print "Question %d: %s" % (qn, question.getAttribute("question-text").strip()) + + # Get the response details in order. + + items_for_question = answers_for_question.items() + items_for_question.sort() + + # Visit each distinct kind of response. + + for selected, results in items_for_question: + choice = question.xpath("choice[position() = %d]" % selected)[0] + choice_text = choice.getAttribute("response-choice").strip() + if choice_text: + print " ", ("%s:" % choice_text), + + if isinstance(results, int): + print results + else: + print + sorted_results = results[:] + sorted_results.sort() + for result in sorted_results: + print " ", result + + print + +# vim: tabstop=4 expandtab shiftwidth=4