Skip to content

Commit

Permalink
Merge pull request #112 from vsoch/master
Browse files Browse the repository at this point in the history
adding validation of surveys to expfactory --validate to close #111
  • Loading branch information
vsoch committed Apr 11, 2016
2 parents 9a99147 + ff75e18 commit a9f801d
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 11 deletions.
16 changes: 13 additions & 3 deletions expfactory/scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
'''
from expfactory.views import preview_experiment, run_battery, run_single
from expfactory.battery import generate, generate_local
from expfactory.experiment import validate
from expfactory.experiment import validate, load_experiment
from expfactory.tests import validate_surveys
from glob import glob
import argparse
import sys
Expand Down Expand Up @@ -119,8 +120,17 @@ def main():

# Validate a config.json
elif args.validate == True:
validate(experiment_folder=args.folder)

if args.folder == None:
folder = os.getcwd()
validate(experiment_folder=folder)
# If a survey, and if validates, also validate survey.tsv
experiment = load_experiment(folder)[0]
if experiment["template"] == "survey":
print "Validating survey.tsv..."
survey_repo = os.path.dirname(folder)
validate_surveys(experiment["exp_id"],survey_repo)


# Run the experiment robot
elif args.test == True:
from expfactory.tests import test_experiment
Expand Down
28 changes: 22 additions & 6 deletions expfactory/survey.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
'''

from expfactory.experiment import get_experiments
from exceptions import ValueError
from glob import glob
import pandas
import json
Expand Down Expand Up @@ -72,14 +73,15 @@ def add_classes(classes,new_classes):
classes = "%s %s" %(classes,new_classes)
return classes

def create_radio(text,id_attribute,options,values,classes="",required=0):
def create_radio(text,id_attribute,options,values,classes="",required=0,validate=False):
'''create_radio generate a material lite radio button given a text field, and a set of options.
:param text: The text (content) of the question to ask
:param id_attribute: the unique id for the question
:param options: a list of text options for the user to select from (not the value of the field)
:param values: a list of values for corresponding options
:param classes: classes to add to the default, should be a string
:param required: is the question required? 0=False,1=True, default 0
:param validate: throw an error in the case that number of values != number of option (for testing)
'''
class_names = "mdl-radio mdl-js-radio mdl-js-ripple-effect"

Expand All @@ -89,15 +91,27 @@ def create_radio(text,id_attribute,options,values,classes="",required=0):

meta = parse_meta(text,options)

# If going through validation, tell the user the question, etc.
if validate == True:
print "Testing question %s with text %s" %(id_attribute,text)

# If options provided are equal to values, parse the question
if len(options) == len(values):
radio_html = '<p id="%s_options">%s</p>' %(id_attribute,text)
for n in range(len(options)):
option_id = "%s_%s" %(id_attribute,n)
radio_html = '%s\n<label class="%s" for="option-%s">\n<input type="radio" id="option-%s" class="mdl-radio__button %s %s" name="%s_options" value="%s" %s>\n<span class="mdl-radio__label">%s</span>\n</label>' %(radio_html,class_names,option_id,option_id,required,classes,id_attribute,values[n],meta,options[n])
return "%s<br><br><br><br>" %(radio_html)

print "ERROR: %s options provided, and only %s values. Must define one option per value." %(len(options),len(values))
return ""

# Otherwise, we cannot include it
else:
error_message = "ERROR: %s options provided, and only %s values. Must define one option per value." %(len(options),len(values))
if validate == True:
raise ValueError(error_message)
else:
print error_message

return ""

def create_checkbox(text,id_attribute,options,classes="",required=0):
'''create_checkbox generate a material lite checkbox field given a text field, and a set of options.
Expand Down Expand Up @@ -338,11 +352,12 @@ def read_survey_file(question_file,delim="\t"):
print "Question file is missing required columns %s" %(",".join(missing_columns))
return None

def parse_questions(question_file,exp_id,delim="\t",return_requiredcount=True):
def parse_questions(question_file,exp_id,delim="\t",return_requiredcount=True,validate=False):
'''parse_questions reads in a text file, separated by delim, into a pandas data frame, checking that all column names are provided.
:param question_file: a TAB separated file to be read with experiment questions. Will also be validated for columns names.
:param exp_id: the experiment unique id, to be used to generate question ids
:param return_requiredcount: if True, will return questions,page_count where page_count is a dictionary to look up the number of required questions on each page {1:10}
:param validate: throw an error in the case that number of values != number of option (for testing)
'''
df = read_survey_file(question_file,delim=delim)
acceptable_types = get_question_types()
Expand Down Expand Up @@ -386,7 +401,8 @@ def parse_questions(question_file,exp_id,delim="\t",return_requiredcount=True):
values = values.split(","),
required=required,
id_attribute=unique_id,
classes=page_class)
classes=page_class,
validate=validate)
else:
print "Radio question %s found null for options or values, skipping." %(question_text)

Expand Down
4 changes: 3 additions & 1 deletion expfactory/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ def validate_surveys(survey_tags,survey_repo,survey_file="survey.tsv",delim="\t"
df = read_survey_file(survey_questions,delim=delim)
assert_equal(isinstance(df,pandas.DataFrame),True)
print "Testing survey generation of %s" %(survey[0]["exp_id"])
questions,required_count = parse_questions(survey_questions,exp_id=survey[0]["exp_id"])
questions,required_count = parse_questions(survey_questions,
exp_id=survey[0]["exp_id"],
validate=True)
print "Testing validation generation of %s" %(survey[0]["exp_id"])
validation = parse_validation(required_count)

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
name="expfactory",

# Version number (initial):
version="2.5.21",
version="2.5.23",

# Application author details:
author="Vanessa Sochat",
Expand Down

0 comments on commit a9f801d

Please sign in to comment.