knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE )
You can use check_for()
, check_while()
and check_if_else()
chains to check whether a student has properly coded control constructs.
Consider the following solution:
# Print out the integers 1 to 10 for (i in 1:10) { print(i) }
A suitable SCT for this exercise can be the following:
ex() %>% check_for() %>% { check_cond(.) %>% check_code("in\\s*1:10", missing_msg = "You can use `i in 1:10` to define your for loop.") check_body(.) %>% check_function("print") %>% check_arg("x") %>% check_equal(eval = FALSE) }
check_for()
checks whether students have specified a for
loop in their code. If this is the case, it produces a substate, referring to the condition of the for loop and its body.for
loop, using check_cond()
and check_body()
respectively. After this zooming in, you can continue the chain of SCT functions to check these 'parts' of the code. The check_code()
call, for example, only looks to match the regular expression in the iteration part of the for
loop.Consider the following solution:
# Predefined value of x x <- TRUE # Code the if else construct if (x) { print("x is TRUE!") } else { print("x is not TRUE!") }
The following SCT checks its correctness:
ex() %>% check_object("x") ex() %>% check_if_else() %>% { check_cond(.) %>% check_code("x") check_if(.) %>% check_function("print") %>% check_arg("x") %>% check_equal() check_else(.) %>% check_function("print") %>% check_arg("x") %>% check_equal() }
check_if_else()
parses the student code and checks if there is an if-else statement in there.check_cond
, check_if
, and check_else()
all 'zoom in' on a particular part of the if-else statement: the condition, the body of the if
statement and the body of the else
statement. After this zooming in, you can continue the chain of SCT functions to check these 'parts' of the code. The first check_function("print")
chain for example, only looks for the function call inside the if
body.It is also possible to use else if
in R. How to test this? Well, behind the scenes, R parses the following structure:
if (condition1) { expression } else if (condition2) { expression } else { expression }
as if it follows this structure:
if (condition1) { expression } else { if (condition2) { } else { } }
If you want to test such a piece of code, you therefore need the following construct:
ex() %>% check_if_else() %>% { check_cond(.) %>% ... check_if(.) %>% ... check_else(.) %>% check_if_else() %>% { check_cond(.) %>% ... check_if(.) %>% ... check_else(.) %>% ... } }
Not all of the SCT chains that you specify after a 'zooming in' step might work as you'd expect. Remember that functions like check_object()
and check_function()
often depend on both the student and solution environment. It is possible that during execution of control flow these values change. The testwhat
functions will always compare the 'end environment' of student and solution, it is not possible to do matching on intermediate values of objects that are changed further in the script.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.