summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xanalyze_grades.r71
-rwxr-xr-xconcat_pdfs.sh65
2 files changed, 136 insertions, 0 deletions
diff --git a/analyze_grades.r b/analyze_grades.r
new file mode 100755
index 0000000..6b64099
--- /dev/null
+++ b/analyze_grades.r
@@ -0,0 +1,71 @@
+#!/usr/bin/env Rscript
+# Copyright (C) 2018 Ryan Kavanagh <rkavanagh@cs.cmu.edu>
+#
+# Processes a CSV file into a format that Canvas will accept.
+# Also spits out statistics on the grades and pretty plots.
+
+library(matrixStats)
+library(tidyr)
+library(ggplot2)
+
+args = commandArgs(trailingOnly=TRUE)
+
+if(length(args)==0) {
+ stop("supply csv filename as cli arg")
+}
+
+HW <- args[1]
+
+metadata <- c("Student", "ID","Section", "SIS Login ID")
+
+hwdata <- read.csv(HW, check.names=FALSE)
+grades <- hwdata[, setdiff(names(hwdata), metadata)]
+totals <- rowSums(grades)
+hwdata["total"] <- totals
+grades <- hwdata[, setdiff(names(hwdata), metadata)]
+
+gradesMatrix = as.matrix(grades)
+
+stats <- data.frame( "mean" = colMeans(gradesMatrix, na.rm=TRUE)
+ , "sd" = colSds(gradesMatrix, na.rm=TRUE)
+ , "median" = colMedians(gradesMatrix, na.rm=TRUE)
+ , "max" = colMaxs(gradesMatrix, na.rm=TRUE)
+ , "min" = colMins(gradesMatrix, na.rm=TRUE))
+
+print("Statistics")
+print(stats)
+
+print("Raw anonymized grades")
+print(gradesMatrix[sample(nrow(gradesMatrix)),])
+
+myrange <- function(x) max(x) - min(x)
+
+ # Binwidth
+scottbw <- function(x) 3.49 * sd(x) * length(x)^(1/3)
+fdrbw <- function(x) 2 * IQR(x) / length(x)^(1/3)
+
+mybw <- function(x) {
+ if (myrange(x) <= 5) {
+ 1
+ } else if (myrange(x) <= 10) {
+ 2
+ } else {
+ myrange(x) / 6
+ }
+}
+
+pdf(paste(HW, "_plot.pdf", sep=""))
+ggplot(gather(grades), aes(value)) +
+ geom_histogram(binwidth = function(x) mybw(x)) +
+ facet_wrap(~key, scales = 'free_x') +
+ xlim(c(-1,NA))
+dev.off()
+
+if(length(args) == 2) {
+ output <- hwdata[metadata]
+ output["SIS Login ID"] <- NULL
+ output[args[2]] <- totals
+ write.csv(output, file = paste(HW, "_totals.csv", sep=""), na="", row.names=FALSE)
+}
+
+warnings()
diff --git a/concat_pdfs.sh b/concat_pdfs.sh
new file mode 100755
index 0000000..8d84d66
--- /dev/null
+++ b/concat_pdfs.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+# Copyright (C) 2017 Ryan Kavanagh <rkavanagh@cs.cmu.edu>
+# Takes all pdf files (at most 4 directories deep)
+# and concatenates them in a PDF, such that each
+# PDF starts on an odd numbered page (useful for when
+# you want to print all student submissions double-sidedly)
+#
+# Puts the filename in the top right corner of the page.
+
+TMPDIR=`mktemp -d`
+TEXFILE="${TMPDIR}/all.tex"
+
+cat<<EOF>${TEXFILE}
+\documentclass[twoside]{minimal}
+\usepackage[letterpaper,top=0.25in,left=0.5in,right=0.5in,bottom=0.5in]{geometry}
+\usepackage{pdfpages}
+\usepackage{cprotect}
+\makeatletter
+\def\ps@headings{
+\def\@oddfoot{}\def\@evenfoot{}
+\def\@oddhead{}\def\@evenhead{}
+}
+\makeatother
+\includepdfset{pages=-,pagecommand={\pagestyle{headings}}}
+\pagenumbering{gobble}
+\begin{document}
+\cleardoublepage
+EOF
+
+c=0;
+shopt -s nullglob # kill the globs that don't match
+for pdf in */*.pdf */*/*.pdf */*/*/*.pdf */*/*/*/*.pdf;
+do
+ # We should also check that the file ${pdf} is non-empty
+ # Here, sometimes students submit PDF files that gs accepts, but which
+ # pdfpages doesn't like. Having gs rewrite the PDF fixes this.
+ # We can also convert all of the submitted PDFs to grayscale to save
+ # colour ink.
+ mutool clean `pwd`"/${pdf}" `pwd`"/${pdf}"
+ gs -o "${TMPDIR}/${c}.pdf" \
+ -sDEVICE=pdfwrite \
+ -dPDFSETTINGS=/prepress \
+ -sColorConversionStrategy=Gray \
+ -dProcessColorModel=/DeviceGray \
+ -dCompatibilityLevel=1.4 \
+ `pwd`"/${pdf}"
+ ESCAPED=`echo "${pdf}" | sed -e 's:&:\\\\&:g;s:\\$:\\\\$:g;s:%:\\\\%:g;s:_:\\\\_:g'`
+ cat<<EOF>>${TEXFILE}
+\makeatletter
+\renewcommand{\@oddhead}{\hfill ${ESCAPED}}
+\renewcommand{\@evenhead}{\hfill ${ESCAPED}}
+\makeatother
+\includepdf{${TMPDIR}/${c}.pdf}
+\cleardoublepage
+EOF
+ c=`expr "${c}" + 1`
+done
+
+cat<<EOF>>${TEXFILE}
+\end{document}
+EOF
+pdflatex ${TEXFILE}
+pdflatex ${TEXFILE}
+
+rm -fr ${TMPDIR}