Constructing surveys programmatically

In this tutorial we will see how we can build surveys from an external data source. The iterative survey construction method in CitrusBuilder makes it easy to accomplish this task.

Consider for example that you have a csv file for each survey where each row defines a question in the survey. The questions might be default questions or more complex custom question types as described in the tutorial Constructing custom question types.

A sample csv file might look like this,

using CSV, DataFrames

data ="sample.csv", DataFrame)

3 rows × 4 columns

11textfirst question1
22textsecond question0
331-5third question1

First, we need to match the type column of the data frame to a question type. In this example we define,

For convenience we can create a custom function that maps the string in the data frame to a CitrusBuilder.Question

using CitrusBuilder

function question(type, args...; kwargs...)
    if type == "text"
        return short_text_question(args...; kwargs...)
    elseif type == "1-5"
        return five_point_choice_question(args...; kwargs...)
        error("unknown question type")
question (generic function with 1 method)

This function will return the required question type. Now we can set up an empty survey,

survey_from_data = survey(123456, "A survey from data")
Survey with 0 groups and 0 questions.
A survey from data (id: 123456)

and append an empty question group as required by LimeSurvey.

g1 = append!(survey_from_data, question_group(1, ""))
CitrusBuilder.QuestionGroup(1, CitrusBuilder.LanguageSettings(CitrusBuilder.LanguageSetting[CitrusBuilder.LanguageSetting("en", "", nothing, nothing, nothing)], false), CitrusBuilder.Question[])

All that is left to do is to append questions by iterating over each row in the data frame.

for row in eachrow(data)
    q = question(row.type, "q" * string(row.position), string(row.title), mandatory=row.mandatory)
    append!(g1, q)

Survey with 1 group and 3 questions.
A survey from data (id: 123456)
└──  (id: 1)
    ├── first question (id: q1)
    ├── second question (id: q2)
    └── third question (id: q3)