Source code for octopus_sensing.questionnaire.questionnaire

# This file is part of Octopus Sensing <https://octopus-sensing.nastaran-saffar.me/>
# Copyright © Nastaran Saffaryazdi 2020
#
# Octopus Sensing is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software Foundation,
#  either version 3 of the License, or (at your option) any later version.
#
# Octopus Sensing is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with Octopus Sensing.
# If not, see <https://www.gnu.org/licenses/>.

import os

from typing import List
import csv
import gi
gi.require_version('Gtk', '3.0')  # nopep8
from gi.repository import Gtk  # nopep8

from octopus_sensing.questionnaire.question import Question  # nopep8


[docs]class Questionnaire(Gtk.Window): ''' Creating a questionnaire using Gtk It has a Done button which by clicking on it, the answers will be saved and window will be destroyed Attributes ----------- Parameters ---------- name: str Questionnaire name experiment_id: str The unique ID of the experiment stimulus_id: str The unique ID of the stimulus title: str Questionnaire title width: int, default: 400 The width of questionnaire window in pixel height: int, default: 200 The height of questionnaire window in pixel output_path: str The output path for recording answers Examples -------- Creating an opinion question, a text question and adding it to the questionnaire >>> emotions = {"Happiness": 4, "Sadness": 6, "Neutral": 5, "Fear": 3, "Anger": 1} >>> question_1 = OpinionQuestion("q1", ... "1- What emotion did you feel the most?", ... options=emotions, ... default_answer=5) >>> question_2 = TextQuestion("q2", ... "1- Was your feelings positive or negative?", ... default_answer="Positive") >>> questionnaire = Questionnaire("after_stimuli", ... "study01_p10", ... "stimuli00", ... "After Stimulus Questionnaire") >>> questionnaire.add_questions([question_1, question_2]) See Also ----------- :class:`octopus_sensing.questionnaire.text_question` :class:`octopus_sensing.questionnaire.opinion_question` ''' def __init__(self, name: str, experiment_id: str, stimulus_id: str, title: str, width: int = 400, height: int = 200, output_path="output/self_report"): Gtk.Window.__init__(self, title=title) self.set_border_width(10) self.set_default_size(width, height) self._name = name self._questions: List[Question] = [] self._experiment_id = experiment_id self.stimulus_id = stimulus_id self._output_path = output_path if not os.path.exists(self._output_path): os.mkdir(self._output_path)
[docs] def add_question(self, question: Question) -> None: ''' Adds a question to the questionnaire Parameters ----------- question Question: a question ''' assert isinstance(question, Question) if question.id in self._questions: raise RuntimeError( "The question ID {0} already exists in the questionnaire".format(question.id)) self._questions.append(question)
[docs] def add_questions(self, questions: List[Question]) -> None: ''' Adds a list of questions to the questionnaire Parameters ---------- questions: List(Question) a list of questions ''' for question in questions: self.add_question(question)
[docs] def show(self) -> None: ''' Shows the questionnaire ''' grid = Gtk.Grid(column_homogeneous=False, column_spacing=10, row_spacing=10) self.add(grid) i = 0 for question in self._questions: row = question.render(grid, i) i += row done_button = Gtk.Button.new_with_label("Done") done_button.connect("clicked", self._on_click_done_button) done_button.get_child().set_markup("<span font_desc='Tahoma 14'>Done</span>") grid.attach(done_button, 0, i, 1, 1) self.connect("destroy", Gtk.main_quit) self.show_all() Gtk.main()
def _on_click_done_button(self, button: Gtk.Button) -> None: ''' Saves answers and close the questionnaire Parameters ---------- button: Gtk.Button by clicking this button, this method will call ''' self._save_answers() self.destroy() def _save_answers(self) -> None: ''' Saves answers ''' file_name = \ "{0}/{1}-{2}.csv".format(self._output_path, self._name, self._experiment_id) if not os.path.exists(file_name): csv_file = open(file_name, 'a') header = ["stimulus ID"] for question in self._questions: header.append(question.id) writer = csv.writer(csv_file) writer.writerow(header) csv_file.flush() csv_file.close() row = [self.stimulus_id] for question in self._questions: row.append(question.get_answer()) with open(file_name, 'a') as csv_file: writer = csv.writer(csv_file) writer.writerow(row)