A student’s introduction to markmyassignment

Mans Magnusson and Oscar Pettersson

2016-08-15

The markmyassignment package is a tool to get automatic feedback easily on your lab assignment before handing it in.

Installing the package

The easiest way to install the package in R is as follows:

install.packages("markmyassignment")

How to get help

All documentation of the package and the functionality can be found using:

help(package = "markmyassignment")

Usage

To use the package markmyassignment, you must first load it into your R sesssion:

library(markmyassignment)

Then, use set_assignment() with the path provided by the teacher. Below you will find an example assignment that is part of the markmyassignment package. The assignment path of this example assignment depends on the local R installation path.

assignment_path <- 
 paste0(system.file(package = "markmyassignment"), "/extdata/example_assignment01.yml")
set_assignment(assignment_path)

Let us look at the tasks included in our example assignment. To check which task that is included we use the function show_tasks().

show_tasks()
## [1] "task1" "task2"

In this example assignment there are two tasks and also a mandatory requirement.

Mandatory requirement:

Store your name in the variable my_name.

task1:

Create a vector containing the values of \(\pi\) and e. The name of the vector should be task1.

task2:

Create a function that takes a numeric vector as the argument and returns the sum of the first and last element. Name the function task2.

We start to solve this assignment by solving the first task. It seems to work as intended.

task1 <- c(pi, exp(1))
print(task1)
## [1] 3.141593 2.718282

We now try to correct our lab assignment using markmyassignment:

mark_my_assignment()
## Mandatory tests: 12
## task1: ...
## task2: 34
## task2: 5
## 
## Failed --------------------------------------------------------------------
## 1. Failure: Mandatory tests (@test-00mandatory-1.R#6) ---------------------
## exists("my_name") isn't true.
## Variable my_name is missing
## 
## 2. Error: Mandatory tests (@test-00mandatory-1.R#7) -----------------------
## could not find function "use_package"
## 1: .handleSimpleError(function (e) 
##    {
##        e$call <- sys.calls()[(frame + 11):(sys.nframe() - 2)]
##        register_expectation(e, frame + 11, sys.nframe() - 2)
##        signalCondition(e)
##    }, "could not find function \"use_package\"", quote(eval(expr, envir, enclos))) at /var/folders/nx/psn9dtzd1m19wvf5_cyq2pl40000gn/T//RtmpY8WrYl/markmyassignment/assignment1/tests/test-00mandatory-1.R:7
## 2: eval(expr, envir, enclos)
## 
## 3. Failure: Marking task2 (@test-task2-1.R#6) -----------------------------
## exists("task2") isn't true.
## task2() does not exist.
## 
## 4. Error: Marking task2 (@test-task2-1.R#7) -------------------------------
## object 'task2' not found
## 1: expect_is(task2, "function", info = "task2 is not a function.") at /var/folders/nx/psn9dtzd1m19wvf5_cyq2pl40000gn/T//RtmpY8WrYl/markmyassignment/assignment1/tests/test-task2-1.R:7
## 2: klass(object)
## 3: paste(class(x), collapse = "/")
## 
## 5. Error: Mark even more on task2 (@test-task2-2.R#6) ---------------------
## could not find function "task2"
## 1: expect_is(task2(5:10), "integer", info = "task2 don't return an integer.") at /var/folders/nx/psn9dtzd1m19wvf5_cyq2pl40000gn/T//RtmpY8WrYl/markmyassignment/assignment1/tests/test-task2-2.R:6
## 2: klass(object)
## 3: paste(class(x), collapse = "/")
## 
## DONE ======================================================================

That did not work very well. This is how it looks when something goes wrong when the markmyassignment package is used.

The first part of the message contains the names of the tests that are run. The names of each task should be followed by dots only. Each dot is symbolising a successful test (ie a correct part of the actual task). If you get any numbers or letters then there is some kind of problem with your proposed solution.

The easiest way to go through the error messages is to start in a chronological order. Start with the first error (error number 1) and correct this error and then run the mark_my_assignment() function again. Lets look at the first error message:

1. Failure: Mandatory tests -------------------------------------------------------------------
Variable my_name is missing

We forgot to include our name. The teacher has decided that this is mandatory in this lab assignment. Let us fix this problem.

my_name <- "Foo Bar"
mark_my_assignment()
## Mandatory tests: .1
## task1: ...
## task2: 23
## task2: 4
## 
## Failed --------------------------------------------------------------------
## 1. Error: Mandatory tests (@test-00mandatory-1.R#7) -----------------------
## could not find function "use_package"
## 1: .handleSimpleError(function (e) 
##    {
##        e$call <- sys.calls()[(frame + 11):(sys.nframe() - 2)]
##        register_expectation(e, frame + 11, sys.nframe() - 2)
##        signalCondition(e)
##    }, "could not find function \"use_package\"", quote(eval(expr, envir, enclos))) at /var/folders/nx/psn9dtzd1m19wvf5_cyq2pl40000gn/T//RtmpY8WrYl/markmyassignment/assignment1/tests/test-00mandatory-1.R:7
## 2: eval(expr, envir, enclos)
## 
## 2. Failure: Marking task2 (@test-task2-1.R#6) -----------------------------
## exists("task2") isn't true.
## task2() does not exist.
## 
## 3. Error: Marking task2 (@test-task2-1.R#7) -------------------------------
## object 'task2' not found
## 1: expect_is(task2, "function", info = "task2 is not a function.") at /var/folders/nx/psn9dtzd1m19wvf5_cyq2pl40000gn/T//RtmpY8WrYl/markmyassignment/assignment1/tests/test-task2-1.R:7
## 2: klass(object)
## 3: paste(class(x), collapse = "/")
## 
## 4. Error: Mark even more on task2 (@test-task2-2.R#6) ---------------------
## could not find function "task2"
## 1: expect_is(task2(5:10), "integer", info = "task2 don't return an integer.") at /var/folders/nx/psn9dtzd1m19wvf5_cyq2pl40000gn/T//RtmpY8WrYl/markmyassignment/assignment1/tests/test-task2-2.R:6
## 2: klass(object)
## 3: paste(class(x), collapse = "/")
## 
## DONE ======================================================================

Yay! The first problem has been solved! Now we can check the next problem of our assignment.

1. Failure: Marking task2 ---------------------------------------------------------------------
task2() does not exist.

The second problem is that we tried to mark the second task, but we have not yet tried to solve this task So let us correct only the first task, using the tasks argument in mark_my_assignment():

mark_my_assignment(tasks = "task1")
## Mandatory tests: .1
## task1: ...
## 
## Failed --------------------------------------------------------------------
## 1. Error: Mandatory tests (@test-00mandatory-1.R#7) -----------------------
## could not find function "use_package"
## 1: .handleSimpleError(function (e) 
##    {
##        e$call <- sys.calls()[(frame + 11):(sys.nframe() - 2)]
##        register_expectation(e, frame + 11, sys.nframe() - 2)
##        signalCondition(e)
##    }, "could not find function \"use_package\"", quote(eval(expr, envir, enclos))) at /var/folders/nx/psn9dtzd1m19wvf5_cyq2pl40000gn/T//RtmpY8WrYl/markmyassignment/assignment1/tests/test-00mandatory-1.R:7
## 2: eval(expr, envir, enclos)
## 
## DONE ======================================================================

That worked better - only dots! We have solved the first task. Let us try to solve the second problem.

task2 <- function(vector){
  vector[1] + vector[5]
}
task2(1:5)
## [1] 6

It seems to work well at a first glance. Let us see what markmyassignment says.

mark_my_assignment(tasks = "task2")
## Mandatory tests: .1
## task2: ...
## task2: ..2.
## 
## Failed --------------------------------------------------------------------
## 1. Error: Mandatory tests (@test-00mandatory-1.R#7) -----------------------
## could not find function "use_package"
## 1: .handleSimpleError(function (e) 
##    {
##        e$call <- sys.calls()[(frame + 11):(sys.nframe() - 2)]
##        register_expectation(e, frame + 11, sys.nframe() - 2)
##        signalCondition(e)
##    }, "could not find function \"use_package\"", quote(eval(expr, envir, enclos))) at /var/folders/nx/psn9dtzd1m19wvf5_cyq2pl40000gn/T//RtmpY8WrYl/markmyassignment/assignment1/tests/test-00mandatory-1.R:7
## 2: eval(expr, envir, enclos)
## 
## 2. Failure: Mark even more on task2 (@test-task2-2.R#8) -------------------
## task2(vector = 5:10) not equal to 15.
## 1/1 mismatches
## [1] 14 - 15 == -1
## task2(vector=5:10) don't return 15
## 
## DONE ======================================================================

Oh! There seems to be an error in our function. What if we run our function with the same example as markmyassignment does?

task2(5:10)
## [1] 14

Ah, the problem seems to be that we assumed a fixed length vector argument. Let us correct that and check our task again.

task2 <- function(vector){
  vector[1] + vector[length(vector)]
}
mark_my_assignment(tasks = "task2")
## Mandatory tests: .1
## task2: ...
## task2: ....
## 
## Failed --------------------------------------------------------------------
## 1. Error: Mandatory tests (@test-00mandatory-1.R#7) -----------------------
## could not find function "use_package"
## 1: .handleSimpleError(function (e) 
##    {
##        e$call <- sys.calls()[(frame + 11):(sys.nframe() - 2)]
##        register_expectation(e, frame + 11, sys.nframe() - 2)
##        signalCondition(e)
##    }, "could not find function \"use_package\"", quote(eval(expr, envir, enclos))) at /var/folders/nx/psn9dtzd1m19wvf5_cyq2pl40000gn/T//RtmpY8WrYl/markmyassignment/assignment1/tests/test-00mandatory-1.R:7
## 2: eval(expr, envir, enclos)
## 
## DONE ======================================================================

We succeeded this time! Now all tasks are completed and we can now use mark_my_assignment() to correct the whole lab assignment. Note that my_name, task1 and task2 need to exist in the global environment. To check this, we can use ls().

ls()
## [1] "assignment_path" "my_name"         "task1"           "task2"
mark_my_assignment()
## Mandatory tests: .1
## task1: ...
## task2: ...
## task2: ....
## 
## Failed --------------------------------------------------------------------
## 1. Error: Mandatory tests (@test-00mandatory-1.R#7) -----------------------
## could not find function "use_package"
## 1: .handleSimpleError(function (e) 
##    {
##        e$call <- sys.calls()[(frame + 11):(sys.nframe() - 2)]
##        register_expectation(e, frame + 11, sys.nframe() - 2)
##        signalCondition(e)
##    }, "could not find function \"use_package\"", quote(eval(expr, envir, enclos))) at /var/folders/nx/psn9dtzd1m19wvf5_cyq2pl40000gn/T//RtmpY8WrYl/markmyassignment/assignment1/tests/test-00mandatory-1.R:7
## 2: eval(expr, envir, enclos)
## 
## DONE ======================================================================

Yay! We have completed the whole lab assignment!

If we save our file now, we could even clean the global environment and run the tests on the assignment file we will turn in. This is also what the teacher will do when correcting the labs (but probably with some extra tests). We need both the file path to our file and the assignment path that we used to set_assignment():

mark_file <- paste0(system.file(package = "markmyassignment"), "/extdata/example_lab_file.R")
mark_my_file(mark_file = mark_file, assignment_path = assignment_path)
## Mandatory tests: .1
## task1: ...
## task2: ...
## task2: ....
## 
## Failed --------------------------------------------------------------------
## 1. Error: Mandatory tests (@test-00mandatory-1.R#7) -----------------------
## could not find function "use_package"
## 1: .handleSimpleError(function (e) 
##    {
##        e$call <- sys.calls()[(frame + 11):(sys.nframe() - 2)]
##        register_expectation(e, frame + 11, sys.nframe() - 2)
##        signalCondition(e)
##    }, "could not find function \"use_package\"", quote(eval(expr, envir, enclos))) at /var/folders/nx/psn9dtzd1m19wvf5_cyq2pl40000gn/T//RtmpY8WrYl/markmyassignment/assignment1/tests/test-00mandatory-1.R:7
## 2: eval(expr, envir, enclos)
## 
## DONE ======================================================================

It is also possible to just specify the assignment path and then choose the assignment file as follows:

mark_my_file(assignment_path = assignment_path)

We could also check individual tasks in our file, similar to before:

mark_my_file(tasks = "task1", mark_file = mark_file, assignment_path = assignment_path)
## Mandatory tests: .1
## task1: ...
## 
## Failed --------------------------------------------------------------------
## 1. Error: Mandatory tests (@test-00mandatory-1.R#7) -----------------------
## could not find function "use_package"
## 1: .handleSimpleError(function (e) 
##    {
##        e$call <- sys.calls()[(frame + 11):(sys.nframe() - 2)]
##        register_expectation(e, frame + 11, sys.nframe() - 2)
##        signalCondition(e)
##    }, "could not find function \"use_package\"", quote(eval(expr, envir, enclos))) at /var/folders/nx/psn9dtzd1m19wvf5_cyq2pl40000gn/T//RtmpY8WrYl/markmyassignment/assignment1/tests/test-00mandatory-1.R:7
## 2: eval(expr, envir, enclos)
## 
## DONE ======================================================================

Good luck! If you have any suggestions, comments or ideas feel free to add an issue at the package webpage!