diff --git a/canvas_cli/.gitignore b/canvas_cli/.gitignore index 8727757..d8cc677 100644 --- a/canvas_cli/.gitignore +++ b/canvas_cli/.gitignore @@ -10,3 +10,5 @@ users.tex assignments.tex submissions.tex grades.tex +stats.tex + diff --git a/canvas_cli/Makefile b/canvas_cli/Makefile index 95ff22d..742d1fa 100644 --- a/canvas_cli/Makefile +++ b/canvas_cli/Makefile @@ -31,6 +31,9 @@ canvas.py: submissions.nw canvas.pdf: grades.tex canvas.py: grades.nw +canvas.pdf: stats.tex +canvas.py: stats.nw + .PHONY: all all: canvas.bash @@ -43,6 +46,7 @@ canvas.bash: canvas clean: ${RM} canvas canvas.py canvas.pdf canvas.tex ${RM} courses.tex users.tex + ${RM} submissions.tex grades.tex stats.tex ${RM} canvas.bash diff --git a/canvas_cli/canvas.nw b/canvas_cli/canvas.nw index 08a36ab..a479284 100644 --- a/canvas_cli/canvas.nw +++ b/canvas_cli/canvas.nw @@ -52,6 +52,7 @@ We also use the [[argcomplete]] module, which must be installed by running import argcomplete, argparse from canvasapi import Canvas +import csv import os import re import sys @@ -234,6 +235,11 @@ if args.func: \input{grades.tex} +\chapter{The stats command} + +\input{stats.tex} + + \printbibliography{} diff --git a/canvas_cli/stats.nw b/canvas_cli/stats.nw new file mode 100644 index 0000000..7b3432d --- /dev/null +++ b/canvas_cli/stats.nw @@ -0,0 +1,91 @@ +This chapter provides the subcommand [[stats]], which outputs various +statistics. +The [[stats]] command takes two subcommands: +\begin{itemize} +\item [[data]], +\item [[grades]], and +\item [[time]]. +\end{itemize} +The [[data]] subcommand gives raw data points in CSV format that can be used to +analyze the data in some other (statistics) software. +The [[grades]] and [[time]] subcommands output aggregated statistics. + +\section{The subcommand and its options} + +We add the subparser for [[stats]]. +<>= +stats_parser = subp.add_parser("stats", help="Output stats of a course", + description="Output format: CSV") +stats_parser.set_defaults(func=stats_command) +<> +@ Now, that [[users_command]] function must take two arguments: [[canvas]] and +[[args]]. +<>= +def stats_command(canvas, args): + <> +@ We will cover the set up and processing of the options in the following +subsections. + +\subsection{Selecting the course}% +\label{selecting-courses} + +We provide two ways to identify a course: by Canvas' ID number, which is +unique, or by matching the course name and course code against a regular +expression. +We need a course, so we require one of these options, but not both. +<>= +course_args = stats_parser.add_mutually_exclusive_group(required=True) +course_args.add_argument("-i", "--course-identifier", type=CourseID, + help="Select course by Canvas unique identifier") +course_args.add_argument("-c", "--course-regex", + help="Filter courses by regular expression") +@ + +When we check for either of these arguments, we set up the [[course_list]] +object that will be used in [[<>]]. +<>= +if args.course_identifier: + course_list = [canvas.get_course(args.course_identifier)] +elif args.course_regex: + course_list = filter_courses(canvas, args.course_regex) +@ We use the [[filter_courses]] from \cref{filter-courses}. + + +\subsection{Selecting the type of stats} + +We also want to be able to filter out the type of stats. +For now, we focus on students and teachers. +<>= +stats_parser.add_argument("-a", "--assignment", default=".*", + help="Choose assignment, default to all") +@ + + +\section{Get and print the stats} + +We need the following data for a course: +\begin{itemize} +\item the start date ([[start_at]] attribute), +\item the assignments ([[assignments]] attribute). +\end{itemize} + +For each assignment, we need the following data: +\begin{itemize} +\item the due date ([[due_at]] attribute), +\item the submissions ([[submissions]] attribute). +\end{itemize} + +For each submission, we need the following data: +\begin{itemize} +\item the grade ([[grade]] attribute), +\item the submission date ([[submitted_at]] or [[graded_at]] attributes). +\end{itemize} + +We want the dates in [[datetime]] format, this way we can compute the +\enquote{day of the course} by just subtracting them. +<>= +<> + +stats_writer = csv.writer(sys.stdout, dialect="unix", delimiter="\t") +@ +