Generates questions about concrete constructs and patterns in a given JavaScript program. These questions (including answering options) can be posed to a learner to practice introductory programming. These questions include elements to develop program comprehension and program tracing.
Automatic generation enables systems to pose the generated questions to leaners about their own programs that they previously programmed. Such Questions About Learners' Code (QLCs) may have self-reflection and self-explanation effects that are of interest in computing education research.
The implementation was inspired by the work of Evan Cole on study-lenses.
Analysis and transformations of the input programs depend on Shift tools by Shape Security, Inc. These libraries are available under the Apache License, Version 2.0.
The concept of Questions About Learners' Code (QLCs) is first introduced by Lehtinen et al. in Let's Ask Students About Their Programs, Automatically.
function power(a, b) {
let n = 1;
for (let i = 0; i < b; i++) {
n *= a;
}
return n;
}
Which is the name of the function? [FunctionName]
- a [parameter_name] This is a parameter name for a value passed as an argument when calling the function
- b [parameter_name] This is a parameter name for a value passed as an argument when calling the function
- function [keyword] The keyword/command "function" is used when the program is about to declare a function
- let [keyword] This is a program keyword/command used inside the function body
- power [function_name] Correct, this is the name
Which are the parameter names of the function? [ParameterName]
- a [parameter_name] Correct, this is one of the 2 parameter names for this function
- b [parameter_name] Correct, this is one of the 2 parameter names for this function
- function [keyword] The keyword/command "function" is used when the program is about to declare a function
- power [function_name] This is the name of the function that is used to call the function
- return [keyword] This is a program keyword/command used inside the function body
Which value does a have when execution of power(2, 2) starts? [ParameterValue]
- 1 [literal] This is a literal value that is used inside the function body
- 2 [parameter_value] Correct, this is the value passed as an argument for the given parameter
- a [parameter_name] This is a parameter name for a value passed as an argument when calling the function
A program loop starts on line 3. Which is the last line inside it? [LoopEnd]
- 2 [line_before_block] The loop starts after this line
- 3 [line_inside_block] This line is inside the loop BUT it is not the last one
- 4 [last_line_inside_block] Correct, this is the last line inside the loop (closing curly bracket may appear later)
- 6 [line_after_block] The loop ends before this line
A value is assigned to variable n on line 4. On which line is n declared? [VariableDeclaration]
- 0 [random_line] This is a random line that does not handle the given variable
- 2 [declaration_line] Correct, this is the line where the variable is declared using the keyword let
- 4 [reference_line] This line references (reads or writes) the given variable BUT it is declared before
- 5 [random_line] This is a random line that does not handle the given variable
- 6 [reference_line] This line references (reads or writes) the given variable BUT it is declared before
Which is the ordered sequence of values that are assigned to variable i while executing power(2, 2)? [VariableTrace]
- 0, 1 [trace_miss_last] No, this sequence is missing a value that gets assigned
- 0, 1, 2 [trace] Correct, step by step these values are assigned to the variable
- 0, 1, 2, 3 [trace_extra_last] No, this sequence has an extra value that is not assigned
- 1, 2 [trace_miss_first] No, this sequence is missing a value that gets assigned
- 1, 2, 0 [trace_shuffled] No, this is an incorrect random sequence
The library is implemented in TypeScript and the types can describe a great deal of the API.
npm install git+https://github.com/teemulehtinen/qlcjs
import { generate, QLCRequest, ProgramInput, QLC } from '@teemulehtinen/qlcjs';
const req: QLCRequest[] = [
{
count: 1, // Number of questions to generate if possible
types: ['FunctionName', 'ParameterName'], // Accepted question types
},
{
count: 3,
fill: true, // Fill in missing number of questions for the count
uniqueTypes: true, // Only accept one question for each question type
},
];
const input: ProgramInput = {
functionName: 'task', // Try to evaluate this function to collect dynamic data
arguments: [[0, 'a'], [1, 'b'], [2, 'c']], // Use one set from these arguments
};
const questions: QLC[] = generate(sourceCode, req, input);
Example of using the build unpkg-module:
npm install && npm run build && ls dist/qlcjs.min.js
<script src="qlcjs.min.js"></script>
<script>
const qlcs = qlcjs.generate(sourceCode, [
{ count: 1, types: ['FunctionName', 'ParameterName'] },
{ count: 3, fill: true, uniqueTypes: true }
]);
qlcs.forEach(qlc => {
console.log(qlc.type, qlc.question, qlc.options);
});
</script>