5 releases (3 stable)
1.3.0 | Jan 15, 2024 |
---|---|
1.0.1 | Nov 7, 2021 |
0.1.4 | Jan 5, 2021 |
0.1.3 | Dec 15, 2020 |
#198 in Text processing
74KB
2K
SLoC
VMKS exam generator
A simple CLI program for pseudo-randomly generating different variants of an embedded programming exam. Designed for Technological school "Electronic Systems" in Sofia, Bulgaria.
When a new variant is generated an adjustable subset of questions is picked at random from a question bank.
Both questions and possible answers for multiple choice questions are shuffled.
Supports randomly picking parts of the question text from a predefined list of possible values.
This makes it possible to generate slightly different tasks such as
"Write a program that prints asterisks in the shape of a square"
and
"Write a program that prints hashtags in the shape of a triangle".
The generated exam variants are pdf forms by default or plain text files, if so specified.
A working latex distribution and latexmk
are required to generate pdf forms.
Installation
Currently, VMKS exam generator can only be installed by compiling from source. A working Rust toolchain is required for this. It can be obtained by installing rustup from your distribution's package manager or from rust-lang.org. Once you have rustup installed, the stable toolchain can be installed with the following command:
rustup toolchain install stable
Then, to install VMKS exam generator run:
cargo install vmks-exam-generator
Usage
Usage: vmks-exam-generator [OPTIONS]
Options:
-n, --variants <VARIANTS> Number of variants to generate
-q, --question-bank <FILENAME> XML file specifying the questions [default: questions.xml]
-s, --num-seed <SEED> Use the number SEED to seed the random number generator
-S, --text-seed <SEED> Use the hash-sum of the string SEED to seed the random number generator
-t, --plain-text Output plaintext instead of pdf forms
-e, --no-escape Don't escape special characters
-h, --help Print help information (use `--help` for more detail)
-V, --version Print version information
If no seed is provided for the random number generator then the number of seconds since the start of the UNIX epoch is used. The default number of variants to generate is 30 and the default name for the question bank file is "questions.xml". Special characters are escaped by default to avoid LaTeX errors and provide an easy way of indenting text in the questions.
Question bank file format
The set of questions used for generating different exam variants is described in XML format. An example is provided in example_questions.xml.
Header
Being an XML file, naturally the question bank file must start with a declaration of the XML version and encoding, for example:
<?xml version="1.0" encoding="UTF-8"?>
Question bank
The entire set of questions is enclosed in a pair of opening and closing question_bank
tags.
It can optionally have the title
attribute. If it is specified, its value will be present at the beginning of each
variant as a title.
question_bank
can optionally contain a description
tag pair. Any text enclosed in
it is displayed at the start of the variant but after the title (if specified).
<question_bank title="Very Difficult Exam">
<description>
This exam will test such and such skills. It requires that much time and the maximum points are X.
</description>
<question_group>...</question_group>
<question_group>...</question_group>
...
</question_bank>
Question group
Questions are separated into groups with the question_group
tags.
These can have the pick
attribute that selects how many questions from the given group are to be picked,
the shuffle
attribute that determines if the questions in the group are to be shuffled and the title
attribute which is similar to the question_bank
attribute of the same name but is displayed before the
corresponding section of the generated exam variant. All question group attributes are optional.
The shuffle
attribute can be either true
(default) or false
. It determines whether the order of the
questions in the group is to be shuffled. If the pick
attribute is not specified then all questions from the
group will be present in every variant generated. Each question can be either a multiple choice question or a
question with variable segments. Question groups also support the optional description
tag pair.
<question_group title="Questions about some topic" pick="5" shuffle="false">
<description>
Each correct answer in this section is worth Y points. There is only one correct answer per question.
</description>
<question_mc>...</question_mc>
<question_mc>...</question_mc>
<question_var>...</question_var>
...
<question_group>
Multiple choice question
Multiple choice questions are enclosed by a pair of question_mc
tags and can optionally have the shuffle
attribute that determines whether the possible answers are to be shuffled. It can be either true
(default) or
false
. question_mc
contain one question_text
tag pair followed by answer_mc
pairs.
The actual text of the question is placed between the question_text
tags. answer_mc
tag pairs are
used to specify the possible answer choices.
<question_mc shuffle="false">
<question_text>When?</question_text>
<answer_mc>Now</answer_mc>
<answer_mc>Later</answer_mc>
<answer_mc>Whenever</answer_mc>
<answer_mc>A long time ago</answer_mc>
<answer_mc>Tuesday</answer_mc>
</question_mc>
Question with variable segments
Questions with variable segments are enclosed in question_var
tags and consist of any number of
question_text
and var_text
tag pairs. Each var_text
tag pair contains any number of option
pairs which in turn contain the different values that can appear at this position in the question text.
var_text
can also contain question_var
to allow multiple levels of variability.
Parts of the question text that do not change between variants are placed inside question_text
tag pairs.
Questions with variable segments appear with text boxes below them in the generated variants. question_var
tags
can have one optional attribute - text_field_height
. Its value must be an integer between 0 and 65535
(default is 5). It determines how many lines of text can fit in the text box for the respective question without
scrolling. Set to 0 to remove the text box. Nesting question_var
in var_text
does not create an additional
text box and the text_field_height
attribute is ignored for the nested questions.
<question_var text_field_height="5">
<question_text>Build a </question_text>
<var_text>
<option>castle</option>
<option>garage</option>
<question_var>
<question_text>house with a </question_text>
<var_text>
<option>chimney</option>
<option>porch</option>
<option>terrace</option>
<option>fence</option>
</var_text>
</question_var>
</var_text>
<question_text> out of </question_text>
<var_text>
<option>hay</option>
<option>planks</option>
<option>bricks</option>
</var_text>
<question_text> in 5 minutes.</question_text>
</question_var>
Notes
If the same attribute is specified more than once, its last instance overrides the previous ones. The same applies to
multiple instances of the description
tag within the same question_bank
or question_group
.
The sequences \n
and \t
will be replaced with newlines and tabs respectively when encountered in the
question bank text. To avoid this, when it's undesired, slashes can be escaped like so: \\
. When generating PDF
files the characters #$%_{}
are also escaped with a slash because they have special meanings in LaTeX.
If you don't want the question text to be altered in any way, you can disable this functionality by running the program
with the -e
flag. This is useful for adding LaTeX commands to the question text that will be evaluated when
generating the variants.
The text in titles, descriptions and multiple choice questions and answers is trimmed of leading and trailing whitespace. The text that forms variable text questions is not trimmed.
Tag and attribute short forms
All tags and some attributes have short forms:
question_bank - qb
question_group - qg
question_mc - qmc
question_var - qv
question_text - qt
answer_mc - amc
var_text - vt
option - o
title - t
description - d
text_field_height - tfh
Dependencies
~1.5MB
~27K SLoC