The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
Moodle is a widespread open source learning platform. It is the official teaching support platform of the University of Granada (Spain), where we develop this package.
The goal of the moodef
package is to harness the power
of R to make defining Moodle elements easier. In particular,
this first version is focused on the definition of questions for
quizzes.
The process is as follows: we define the questions in R, from the definition, we generate an xml file that we can import directly into Moodle.
What does this package provide? On the one hand, we have simplified the process of manually defining the questions, considering only the essential parameters for each type. On the other hand, the package offers an infrastructure that allows the automatic or semi-automatic generation of questions from R: to define a question we simply need to include a row in a data frame, a csv file or an Excel file.
The rest of this document is structured as follows: First, the general process of defining questions is presented. Next, we show the types of questions considered and how to define them. Finally, the document ends with conclusions.
One of the main objectives considered in the package design has been to simplify the definition of the questions. To do this, we have considered for each question the default values that we use most frequently and we only have to define the specific components of the question:
We do not even have to define the type, only, in some cases, indicate some additional detail, such as the orientation of the presentation of the answers. The type is deduced from the definition.
Questions are defined within the framework of a category (Moodle concept). In its definition we have included the general configuration parameters for all questions.
Therefore, the definition process is as follows:
Define the category.
Define questions.
Generate the xml file with the result.
Import the xml file from Moodle.
As a result, the questions are added to the question bank within the category and can be used directly in the definition of quizzes. If we need to configure a specific aspect of a question, it can be done there.
In this section we are going to show the first three points of this process.
To define a category we use the function
question_category()
and we have to indicate its name: it
creates an object of class question_category
.
Below is a call to the function with the values of the parameters that we usually define.
library(moodef)
qc <- question_category(category = 'Initial test',
copyright = 'Copyright © 2024 Universidad de Granada',
license = 'License Creative Commons Attribution-ShareAlike 4.0',
adapt_images = TRUE)
In addition to the category name in the category
parameter, we define the copyright
and license
parameters that will appear between comments in the xml file associated
with each question, as can be seen below.
<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
<category> <text>$course$/top/Initial test</text> </category>
<info format="html"> <text></text> </info>
<idnumber></idnumber>
</question>
<question type="...">
...
<questiontext format="html">
<text><![CDATA[
<!-- Copyright © 2024 Universidad de Granada -->
<!-- License Creative Commons Attribution-ShareAlike 4.0 -->
... ]]></text>
...
</questiontext>
...
</question>
</quiz>
Below is the function call that is being made including the default values of the rest of the parameters.
qc <- question_category(category = 'Initial test',
first_question_number = 1,
copyright = 'Copyright © 2024 Universidad de Granada',
license = 'License Creative Commons Attribution-ShareAlike 4.0',
correct_feedback = 'Correct.',
partially_correct_feedback = 'Partially correct.',
incorrect_feedback = 'Incorrect.',
adapt_images = TRUE,
width = 800,
height = 600)
We are going to discuss the use of each parameter.
Questions have a name, which is displayed as a summary in the Moodle question bank. We compose the name from the number of the question, the type of question that we have deduced and the beginning of its statement. For example, below is a generated question name.
<?xml version="1.0" encoding="UTF-8"?>
<quiz>
...
<question type="multichoice">
<name> <text>q_001_multichoice_what_are_the_basic_arithmetic_operations</text> </name>
...
</question>
</quiz>
Using the parameter first_question_number
, the number
that will be assigned to the first question is defined, with a
three-digit format. This number will increase for each question.
For each question we can indicate feedback text for cases in which
the answer is correct, partially correct or incorrect: The corresponding
values are provided by the correct_feedback
,
partially_correct_feedback
and
incorrect_feedback
parameters.
Finally, each question stem can include an image. Sometimes the
images we use have very different sizes and require a prior
transformation to homogenize their presentation. This transformation can
be carried out automatically by indicating it using the parameter
adapt_images
(default is FALSE
). Using the
parameters width
and height
we indicate the
size of the resulting image. It is advisable to test this functionality
and adjust the size accordingly by viewing the result when defining a
questionnaire in Moodle. The original images are not
modified, only those that are embedded in the xml file.
Once we have a question_category
object created, we can
define questions that are added to it.
We can define the questions one by one using a definition function or in bulk using a data frame, a csv file or an Excel file. Below we show the possibilities offered.
The minimum we have to define about a question is its statement.
Here’s how to define a question using the define_question()
function.
Below is the definition of a question with all possible parameters, which we explain below.
qc <- qc |>
define_question(
type = 'x',
question = 'Place the name of the operations as they appear in the figure.',
image = system.file("extdata", "ops.png", package = "moodef"),
image_alt = 'Operations',
answer = 'Addition',
a_1 = 'Multiplication',
a_2 = 'Division',
a_3 = 'Subtraction'
)
The type of question is deduced from the statement and the answers.
The type
parameter is used to distinguish between two types
of questions and also to indicate the presentation of the answers. It
can have three values: empty, h
or any other value
different from those two. In the above example it is x
,
that is, the third case: As we will see in the next section, it
indicates that it is not a multichoice
question and that
the values are not displayed horizontally (h
value).
The question statement is defined by the parameter
question
.
An image can be shown after the statement. Using the parameter
image
we indicate the file that contains it: In the example
we obtain the name of a file included in this package. Each image must
have a description that is indicated by the image_alt
parameter.
Finally we define the answers to the question. Using the parameter
answer
we indicate the first one. If necessary, we can
indicate the rest in a variable way with the parameter names we want (or
without names, if we use all the defined parameters), as many as we need
to include.
We can create an empty csv file but with the necessary columns using
the create_question_csv()
function. In addition to the file
name, we can also indicate the separator to use (,
or
;
).
The content of the file is shown below.
"type","question","image","image_alt","answer","a_1","a_2","a_3"
We can add as many additional columns as we consider necessary. From that file, we can include rows using a text editor, R or some tool to edit csv files in spreadsheet format.
Below is the content of a csv file included in this package.
"type","question","image","image_alt","answer","a_1","a_2","a_3"
,"What are the basic arithmetic operations?",,,"Addition, subtraction, multiplication and division.","Addition and subtraction.","Addition, subtraction, multiplication, division and square root.",
,"Match each operation with its symbol.",,,"Addition<|>+","Subtraction<|>-","Multiplication<|>*",
,"The square root is a basic arithmetic operation.",,,"False",,,
,"What basic operation does it have as a ""+"" symbol?",,,"Addition",,,
,"The symbol for addition is [[1]], the symbol for subtraction is [[2]].",,,"+","-",,
"x","The symbol for addition is [[1]], the symbol for subtraction is [[2]].",,,"+","-",,
"h","Sort the result from smallest to largest.",,,"6/2","6-2","6+2","6*2"
"x","Sort the result from smallest to largest.",,,"6/2","6-2","6+2","6*2"
,"What is the result of SQRT(4)?",,,"2","-2",,
,"What is the result of 4/3?",,,"1.33<|>0.03",,,
,"Describe the addition operation.",,,,,,
Once available, we can generate all the questions using the
define_questions_from_csv()
function, as shown below.
file <- system.file("extdata", "questions.csv", package = "moodef")
qc <- qc |>
define_questions_from_csv(file)
There are types of questions in which two string values must be
indicated for each answer. The criterion we have adopted to include two
values in a cell is to use a separator and define them in a single
string, the separator is <|>
: It can be seen in the
definition of some of the previous questions, for example,
Addition<|>+
or 1.33<|>0.03
.
In this example, questions with images have not been included due to the difficulty of referencing the image files in the package from the csv file, but they can be included without any problem.
For Excel files the definition is carried out in the same
way. The corresponding functions are:
create_question_excel()
and
define_questions_from_excel()
.
We can also massively define the questions using a data frame. We can
create an empty one using the create_question_data_frame()
function or read one from a csv file using the
read_question_csv()
function. In this case we are going to
read one that contains images in the statements.
file <- system.file("extdata", "questions_image.csv", package = "moodef")
df <- read_question_csv(file = file)
The content of the data frame is shown below.
type | question | image | image_alt | answer | a_1 | a_2 | a_3 |
---|---|---|---|---|---|---|---|
What basic operation has the symbol shown in the figure as its symbol? | xxxxx/divide.png | Operation | Division | ||||
x | Place the name of the operations as they appear in the figure. | xxxxx/ops.png | Operations | Addition | Multiplication | Division | Subtraction |
In this case we are going to update the figure data with the files included in the package (in a local example, this is not necessary).
df[1, 'image'] <- system.file("extdata", "divide.png", package = "moodef")
df[2, 'image'] <- system.file("extdata", "ops.png", package = "moodef")
From R we can add new rows or modify existing ones. As we have
explained in the previous section, there are questions in which we need
to define two values in a cell using a separator:
<|>
. To facilitate the definition of these cells, we
have defined the function vector_to_string()
that, from a
vector, generates a string including that separator, as shown in the
following example.
Once the definition of the questions in the data frame is finished,
we can add it to the question_category
object using the
define_questions_from_data_frame()
function, as it’s shown
in the following.
Once the questions we need have been defined, the next step is to
generate the xml file. We use the generate_xml_file()
function, to which we have to indicate a file name.
The generated file is the one that we can import from Moodle in the Question Bank section.
If we have included images, the file size increases considerably because they are embedded in xml (not referenced).
The definition file for a single question is shown below.
<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
<category> <text>$course$/top/Initial test</text> </category>
<info format="html"> <text></text> </info>
<idnumber></idnumber>
</question>
<question type="multichoice">
<name> <text>q_001_multichoice_what_are_the_basic_arithmetic_operations</text> </name>
<questiontext format="html">
<text><![CDATA[
<!-- Copyright © 2024 Universidad de Granada -->
<!-- License Creative Commons Attribution-ShareAlike 4.0 -->
<p>What are the basic arithmetic operations?</p>]]></text>
</questiontext>
<generalfeedback format="html"> <text></text> </generalfeedback>
<defaultgrade>1.0000000</defaultgrade>
<penalty>0.5</penalty>
<hidden>0</hidden>
<idnumber></idnumber>
<single>true</single>
<shuffleanswers>true</shuffleanswers>
<answernumbering>abc</answernumbering>
<showstandardinstruction>0</showstandardinstruction>
<correctfeedback format="moodle_auto_format"> <text>Correct.</text> </correctfeedback>
<partiallycorrectfeedback format="moodle_auto_format"> <text></text> </partiallycorrectfeedback>
<incorrectfeedback format="moodle_auto_format"> <text>Incorrect.</text> </incorrectfeedback>
<answer fraction="100" format="html">
<text>Addition, subtraction, multiplication and division.</text>
<feedback format="html"> <text>Correct.</text> </feedback>
</answer>
<answer fraction="-50.000000000000000" format="html">
<text>Addition and subtraction.</text>
<feedback format="html"> <text>Incorrect.</text> </feedback>
</answer>
<answer fraction="-50.000000000000000" format="html">
<text>Addition, subtraction, multiplication, division and square root.</text>
<feedback format="html"> <text>Incorrect.</text> </feedback>
</answer>
</question>
</quiz>
We have simplified and generalized the definition process for 9 types
of questions, so that we do not even have to indicate the type to define
them, it is deduced from the definition: It depends on the value of the
answer
field. In some cases a character in the
type
field is used to distinguish between two types whose
definition is identical or to indicate the orientation of the answers
(horizontal or vertical), as we will see below. We dedicate a section to
each type with the names that are generated in the xml file.
essay
Only includes the question statement with or without an image (the
answer
field is empty). The answer to the question is made
through free text. Below is an example that we had shown before.
truefalse
The answer
field contains the correct answer. If this is
one of the literals corresponding to the boolean values
('True'
or 'False'
), nothing else needs to be
indicated. Here is an example.
numerical
If the value of field answer
is a number with or without
decimal places, or a vector of two numbers, it is a
numerical
question.
In this type of questions we only have to indicate correct values of the answer. If, instead of a value, we indicate a vector of two values, the second number represents the margin of error in which the answer is accepted as valid. Below are two examples.
shortanswer
If only field answer
is defined and it is not a boolean
or numeric value, it is of type shortanswer
, for
example:
multichoice
If field answer
and the rest of the answers are of type
string, it is of type multichoice
. The content of field
answer
is the correct answer. Here is an example.
ordering
Type ordering
is defined as type
multichoice
. To distinguish it, we assign the parameter
type
a value other than empty, which is its default value.
If we assign the value h
, the answers will be presented
horizontally, if it is different from h
, they will be
presented vertically.
In the example below, the two questions are the same, only the way the answers are presented changes.
ddwtos
and gapselect
In questions of these types the objective is to fill in the gaps with
the terms indicated. If the variable type
has the default
value (empty string), the values are filled by dragging and dropping. If
we define a value other than empty in the variable type
,
they are filled by selecting from a list.
Gaps in the statement are defined by numbers in double brackets, as shown in the following examples.
qc <- qc |>
define_question(
question = 'The symbol for addition is [[1]], the symbol for subtraction is [[2]].',
answer = '+',
a_1 = '-'
) |>
define_question(
type = 'x',
question = 'The symbol for addition is [[1]], the symbol for subtraction is [[2]].',
answer = '+',
a_1 = '-'
)
We have to indicate as many answers as gaps, in the correct order.
matching
If the answers are made up of vectors of pairs of strings, we are in
a type matching
question. Below we show an example.
The moodef
package makes it easy to define questions for
Moodle quizzes.
We can define the questions one by one by calling a function or in bulk using a csv file or a data frame. We have simplified and generalized the definition so that the types considered are defined with the same parameters.
The functionality offered by the package can be used to manually define the questions quickly or to define them automatically or semi-automatically from R.
The result of the definition process is an xml file that can be imported directly into the Moodle question bank.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.