Date

In my teaching, I use both paper and online quizzes. Since these formats are very different, I want to minimize the effort and errors that come with moving content between them. The solution I settled on was to create a simple data structure that would capture the essential pieces of a quiz. Once I had this data structure, I'd be able to convert to LaTeX for paper PDF generation or to a format like GIFT which I can use in our Moodle LMS system.

Below are two quiz questions in this format. To generate a quiz, an outer loop iterates over quiz questions while an inner loop iterates over the possible options for each quiz. Based on the format of each output, I can construct the text that will create the quiz question.

Since this data is structured, it is easy to extend and to create a library of quiz questions for inclusion in other work or classes. These allow me to target which ever method for creating the quiz I like. This is very much in the spirit of Pandoc, but without parsers so that you directly edit the data structure.

In [1]:
# equivalent yaml
raw_yaml = '''
- id: simple_addition_1
  prompt: What is $2^2$?
  options:
    - text: 3
      correct: False
      feedback: too low
    - text: 4
      correct: True
      feedback: correct
    - text: 5
      correct: False
      feedback: too high
    - text: 6
      correct: False
      feedback: too high

- id: simple_addition_2
  prompt: What is 2 + 3?
  options:
    - text: 4
      correct: False
      feedback: too low
    - text: 5
      correct: True
      feedback: correct
    - text: 6
      correct: False
      feedback: too high
    - text: 7
      correct: False
      feedback: too high
'''
In [2]:
import yaml
import io
quiz = yaml.load(io.StringIO(raw_yaml))

Once loaded, the quiz structure is a list of two dictionaries with three key-value pairs for the quiz question name id, the list of options, and the question text prompt. The options have fields for whether the option is correct, for any feedback to provide when chosen, and the text of the option.

In [3]:
quiz
Out[3]:
[{'id': 'simple_addition_1',
  'options': [{'correct': False, 'feedback': 'too low', 'text': 3},
   {'correct': True, 'feedback': 'correct', 'text': 4},
   {'correct': False, 'feedback': 'too high', 'text': 5},
   {'correct': False, 'feedback': 'too high', 'text': 6}],
  'prompt': 'What is $2^2$?'},
 {'id': 'simple_addition_2',
  'options': [{'correct': False, 'feedback': 'too low', 'text': 4},
   {'correct': True, 'feedback': 'correct', 'text': 5},
   {'correct': False, 'feedback': 'too high', 'text': 6},
   {'correct': False, 'feedback': 'too high', 'text': 7}],
  'prompt': 'What is 2 + 3?'}]
In [4]:
def print_latex(quiz):
    for i, q in enumerate(quiz, start=1):
        print('Question {}:'.format(i))
        print(q['prompt'])
        print('\\begin{enumerate}')
        for i, o in enumerate(q['options']):
            print('\item {}'.format(o['text']))
            if o['correct']:
                print('\checkmark')
        print('\\end{enumerate}')
        print()

print_latex(quiz)
Question 1:
What is $2^2$?
\begin{enumerate}
\item 3
\item 4
\checkmark
\item 5
\item 6
\end{enumerate}

Question 2:
What is 2 + 3?
\begin{enumerate}
\item 4
\item 5
\checkmark
\item 6
\item 7
\end{enumerate}

The student is presented with the output from the LaTeX program.

Rendered Quiz

I have also written a simple exporter for the Moodle GIFT format so I can create online quizzes in our campus Learning Management System (LMS).

In [5]:
def print_gift(quiz):
    for i, q in enumerate(quiz, start=1):
        print('//question: {} name: {}'.format(i, q['id']))
        print('::Q{}::{} {{'.format(i, q['prompt']))
        for i, o in enumerate(q['options']):
            if o['correct']:
                print('={}'.format(o['text']))
            else:
                print('~{}'.format(o['text']))
            print('#{}'.format(o['feedback']))
        print('}')
        print()
In [6]:
print_gift(quiz)
//question: 1 name: simple_addition_1
::Q1::What is $2^2$? {
~3
#too low
=4
#correct
~5
#too high
~6
#too high
}

//question: 2 name: simple_addition_2
::Q2::What is 2 + 3? {
~4
#too low
=5
#correct
~6
#too high
~7
#too high
}

Once the quiz is uploaded to Moodle, the student will be presented with the usual Moodle quiz interface.

In [ ]: