Evaluate NOPS Exams

Evaluate NOPS exams produced with exams2nops, and scanned by nops_scan.

nops_eval(register = dir(pattern = "\\.csv$"), solutions = dir(pattern = "\\.rds$"), scans = dir(pattern = "^nops_scan_[[:digit:]]*\\.zip$"), points = NULL, eval = exams_eval(partial = TRUE, negative = FALSE, rule = "false2"), mark = c(0.5, 0.6, 0.75, 0.85), dir = ".", results = "nops_eval", html = NULL, col = hcl(c(0, 0, 60, 120), c(70, 0, 70, 70), 90), encoding = "UTF-8", language = "en", interactive = TRUE, string_scans = dir(pattern = "^nops_string_scan_[[:digit:]]*\\.zip$"), string_points = seq(0, 1, 0.25))
character. File name of a CSV file (semicolon-separated) of the registered students. Must contain columns "registration" (registration number), "name" (student name), "id" (some user name or other string unique for each student). The file name should not contain spaces, umlaut or other special characters (e.g., something like "exam-2015-07-01.csv" is recommended).
character. File name of the RDS exam file produced by exams2nops.
character. File name of the ZIP file with scanning results (containing Daten.txt and PNG files) as produced by nops_scan.
numeric. Vector of points per exercise. By default read from solutions.
list specification of evaluation policy as computed by exams_eval.
logical or numeric. If mark = FALSE, no marks are computed. Otherwise mark needs to be a numeric vector with threshold values to compute marks. The thresholds can either be relative (all lower than 1) or absolute. In case results exactly matching a threshold, the better mark is used.
character. File path to the output directory (the default being the current working directory).
character. Prefix for output files.
character. File name for individual HTML report files, by default the same as register with suffix .html.
character. Hex color codes used for exercises with negative, neutral, positive, full solution.
character. Encoding of register, e.g., "latin1" or "UTF-8" (default).
character. Path to a DCF file with a language specification. Currently, the package ships: English ("en"), Dutch ("nl"), French ("fr"), German ("de"), Italian ("it"), Romanian ("ro"), Portuguese ("pt"), Spanish ("es").
logical. Should possible errors in the Daten.txt file by corrected interactively? Requires the png package for full interactivity.
character. Optional file name of the ZIP file with scanning results of string exercise sheets (if any) containing Daten2.txt and PNG files as produced by nops_scan.
numeric. Vector of length 5 with points assigned to string results.

nops_eval is a companion function for exams2nops and nops_scan. It evaluates the scanned exams by computing the sums of the points achived and (if desired) maps them to marks. Furthermore a HTML report for each individual student is generated (e.g., for upload into a learning management system).


A data.frame with the detailed exam results is returned invisibly. It is also written to a CSV file in the current directory, along with a ZIP file containing the HTML reports.

See Also

exams2nops, nops_scan

  • nops_eval
## --- Preliminaries ---

## load package and enforce par(ask = FALSE)
options(device.ask.default = FALSE)

## set up a temporary working directory in which all files are managed
odir <- getwd()
dir.create(mydir <- tempfile())

## --- Step 1 ---
## exam generation

## define an exam (= list of exercises)
myexam <- list(
  c("boxplots.Rnw", "scatterplot.Rnw"),

## create multiple exams on the disk with different numbers of points
## per exercise (see ?exams2nops for more examples)
ex1 <- exams2nops(myexam, n = 2, dir = ".", date = "2015-07-29",
  points = c(1, 1, 1, 2, 2, 3), showpoints = TRUE)

## assume the PDF exams were already printed (and possibly backed up
## in a different directory) so that they are not needed anymore
file.remove(dir(pattern = "pdf$"))

## --- Step 2 ---
## scan results

## assume two participants filled out the printed exam sheets
## and the corresponding scans are in two PNG files,
img <- dir(system.file("nops", package = "exams"), pattern = "nops_scan",
  full.names = TRUE)

## copy the PNG files to the working directory
file.copy(img, to = ".")

## read the scanned images (all locally available .png files) and collect
## results in a ZIP archive (see ?nops_scan for more details)

## the ZIP archive contains copies of the PNG images so that these are
## can be deleted here (possibly after backup in a different directory)
file.remove(dir(pattern = "png$"))

## -- Step 3 ---
## evaluate results

## three files are required: (a) an RDS file with the exam meta-information
## (see Step 1), (b) a ZIP file with the scanned sheets (see Step 2), (c) a
## CSV file with the student infomation (registration number, name, and some
## for of ID/username)

## here we create the CSV file on the fly but in practice this will typically
## be processed from some registration service or learning management system etc
  registration = c("1501090", "9901071"),
  name = c("Jane Doe", "Ambi Dexter"),
  id = c("jane_doe", "ambi_dexter")
), file = "Exam-2015-07-29.csv", sep = ";", quote = FALSE, row.names = FALSE)
## now the exam can be evaluated creating an output data frame (also stored
## as CSV file) and individual HTML reports (stored in a ZIP file),

## as there is only exactly on CSV/RDS/ZIP file in the current directory,
## these are found automatically - furthermore an evaluation scheme without
## partial points and differing points per exercise are used
ev1 <- nops_eval(eval = exams_eval(partial = FALSE, negative = FALSE))

## inspect evaluated data

## inspect corresponding HTML reports
if(interactive()) {
browseURL(file.path(mydir, "jane_doe",    "Exam-2015-07-29.html"))
browseURL(file.path(mydir, "ambi_dexter", "Exam-2015-07-29.html"))

## --- Options ---
if(interactive()) {
## below three typically needed options are discussed:
## (a) using a different evaluation strategy (here with partial credits),
## (b) using a different language (here de/German),
## (c) an error of the participant when filling in the registration number.

## as for (a): partial credits should only be used for multiple-choice questions
## where at least one alternative is correct and at least one is false
## [note that in this example this is not the case for the first question
## (single-choice) and the third question for Jane Doe (no alternative correct)]

## as for (c): for Ambi Dexter such an error was included in the PNG example
## image, the actual number is "9911071" but the crosses indicate "9901071"

## clean up previous evaluation
file.remove(c("nops_eval.csv", ""))

## write correct registration information
  registration = c("1501090", "9911071"),
  name = c("Jane Doe", "Ambi Dexter"),
  id = c("jane_doe", "ambi_dexter")
), file = "Exam-2015-07-29.csv", sep = ";", quote = FALSE, row.names = FALSE)

## call nops_eval() with modified options, where the error in the registration
## number of Ambi Dexter will trigger an interactive prompt
ev2 <- nops_eval(eval = exams_eval(partial = TRUE, rule = "false2"),
  language = "de")

## inspect evaluated data
cbind(ev1$points, ev2$points)

## inspect corresponding HTML reports
browseURL(file.path(mydir, "jane_doe",    "Exam-2015-07-29.html"))
browseURL(file.path(mydir, "ambi_dexter", "Exam-2015-07-29.html"))

## switch back to original working directory
Documentation reproduced from package exams, version 2.1-0, License: GPL-2 | GPL-3

Community examples

Looks like there are no examples yet.