Course Tools

A set of scripts that I use to automate course management tasks with examples to demonstrate usage.

Dependencies

I strongly recommend installing Miniconda and using the conda package manager to manage your Pythons and Python libraries. All of the above are available from conda.

Installation

Clone this repository on your computer (or fork it and and clone your fork), and add the bin directory to your path.

Utility Scripts

make_schedule.py

Usage

$ make_schedule.py -h
usage: make_schedule.py [-h] -f FIRST -l LAST -d DAYS [-b BREAKS] [-c COURSE]
                        [-o OUTPUT]

Generate class schedule.

optional arguments:
  -h, --help            show this help message and exit
  -f FIRST, --first FIRST
                        The first class date, in ISO format
  -l LAST, --last LAST  The last class date, in ISO format
  -d DAYS, --days DAYS  Class days, e.g., TR for Tuesdays and Thursdays
  -b BREAKS, --breaks BREAKS
                        File containing JSON dict of breaks/holidays.
  -c COURSE, --course COURSE
                        JSON course. If absent, generate blank schedule.
  -o OUTPUT, --output OUTPUT
                        File to write schedule to.

Example

If you're in the root directory of your clone of this repo,

$ cd examples
$ make_schedule.py -f 2016-08-22 -l 2016-12-06 -d MWF -b breaks-fall2016.json -c sample-course.json -o sample-course.fall2016

will create a file called sample-course.fall2016 whose contents will look something like this:

Week 1
2016-08-22;intro-cs2316
2016-08-24;intro-python
2016-08-26;values-variables
Week 2
2016-08-29;values-variables
2016-08-31;data-structures
2016-09-02;data-structures
Week 3
2016-09-05;Labor Day - No Class
2016-09-07;strings
2016-09-09;functions
Week 4
2016-09-12;control-structures
2016-09-14;control-structures
2016-09-16;modules-programs
Week 5
2016-09-19;functools
2016-09-21;classes-objects
2016-09-23;classes-objects
Week 6
2016-09-26;review1
2016-09-28;exam1
2016-09-30;pq1
Week 7
2016-10-03;csv-files
2016-10-05;json
2016-10-07;relational-databases
Week 8
2016-10-10;Fall Break - No Class
2016-10-12;sql
2016-10-14;python-xml-databases
Week 9
2016-10-17;review2
2016-10-19;exam2
2016-10-21;pq2
Week 10
2016-10-24;html
2016-10-26;flask
2016-10-28;flask
Week 11
2016-10-31;regular-expressions
2016-11-02;web-mining
2016-11-04;web-mining
Week 12
2016-11-07;python-guis
2016-11-09;python-guis
2016-11-11;python-guis
Week 13
2016-11-14;review3
2016-11-16;exam3
2016-11-18;pq3
Week 14
2016-11-21
2016-11-23;Thanksgiving - No Class
2016-11-25;Thanksgiving - No Class
Week 15
2016-11-28
2016-11-30
2016-12-02
Week 16
2016-12-05

At this point you can tweak this file to move lessons, add reminders, and add your class's final exam. Reminders go in the third field in the schedule file. Fields on lines that represent class days are delimited by semicolons. Lines with no semicolons are "internal headers", that is, rows with one cell that spans four columns.

To add a reminder to a class day that has a lesson in the course file, add a third field with a semicolon. For example, to add a link to a homework on Day one, change that line to:

2016-08-22;intro-cs2316;[HW 0 Assigned](fall2016/hw0/hw0.html)

Notice that Markdown is accepted here as well. You can add multiple reminders by separating them with commas. For example, to add an additional reminder to Day 1:

2016-08-22;intro-cs2316;[HW 0 Assigned](fall2016/hw0/hw0.html),Install Python today!

Class days that don't have a lecture in the course file can be entered manually. For example,

2016-11-28;Matplotlib;[Matplotlib](http://matplotlib.org/),More materials;A reminder

All fields are optional except the first field.

I typically generate a schedule file at the beginning of the semester, then add the schedule file to the repository for my course materials and edit it by hand to make adjustments during the semester (see render_schedule.py below).

render_schedule.py

Usage

$ render_schedule.py -h
usage: render_schedule.py [-h] -s SCHEDULE -c COURSE -t TEMPLATE_FILE
                          [-o OUTPUT]

Generate class schedule.

optional arguments:
  -h, --help            show this help message and exit
  -s SCHEDULE, --schedule SCHEDULE
                        Schedule file, as produced by make_schedule.py
  -c COURSE, --course COURSE
                        JSON file containing course dict.
  -t TEMPLATE_FILE, --template TEMPLATE_FILE
                        Template file used for rendering schedule.
  -o OUTPUT, --output OUTPUT
                        Name of file to write rendered schedule to.

Example

If you have a schedule file that looks like the one generated by make_schedule.py, -- sample-course.fall2016 if you ran the example above -- you can create an HTML formatted schedule like this:

$ render_schedule.py -s sample-course.fall2016 -c sample-course.json -t sample-template.html -o sample-course-fall2016.html

Now you have an HTML class schedule that you can publish on the web. Every time you want to chagne the course -- like adjusting for snow days, etc -- just edit the schedule file and re-run render_schedule.py. Much easier than messing with HTML code directly.

I use Bootstrap to style my class web sites and Jekyll to generate the web sites from Markdown and HTML sources, so I have appropriate Bootstrap CSS and Jekyll headers in my HTML templates.

The Course JSON File

The course JSON file is a dictionary of dictionaries. Each key in the top-level dictionary is an identifier for a lesson which maps to a dictionary that contains the topic, materials, and optionally the order for that lesson. Where a lesson identifier appears in the second field of a course schedule, the make_schedule.py script uses the dictionary associated with that lesson key to generate the Topic and Materials cells of the table row for that lesson.

For each lesson dictionary,

  • the value associated with topic should be a single Markdown-formatted string,
  • the value associated with 'materials` should be a list of Markdown-formatted strings, and
  • the value associated with the optional order key should be a list of integers.

Hypothetical Example:

{
    "intro-cs2316": {
        "topic": "[Intro to CS 2316](slides/intro-cs2316.pdf)",
        "materials": ["[Syllabus](syllabus.html)", "[Schedule](schedule.html)"],
        "order": [1]
    },
    "intro-python": {
        "topic": "[Intro to Python](slides/intro-python.html)",
        "materials": ["[TP](http://greenteapress.com/wp/think-python-2e/)",
                     "Introducting Python, Ch 1"],
        "order": [2]
    },
    "values-variables": {
        "topic": "[Values and Variables](slides/values-variables.html)",
        "materials": ["[TP](http://greenteapress.com/wp/think-python-2e/)",
                     "Introducing Python, Ch 2"],
        "order": [3,4]
    },
    "python-monads": {
        "topic": "[Monads in Python](slides/python-monads.html)",
        "materials": ["Probably", "not", "gonna", "cover", "this"],
        "order": [100]
    }
}

Given the example above, in a schedule built with make_schedule.py including the -c/--course option

  • intro-cs2316 is on the first day of class,
  • values-variables is on the 3rd and 4th days of class,
  • python-monads will not appear in any schedule with fewer than 100 days of classes. This is a way to "hide" a lesson from make_schedule.py while keeping it in the course file.

The string values are processed by a Markdown translator in render_schedule.py, so [text](link) becomes <a href="link">text</a>, **text** becomes <b>text</b>, and so on.

Testing and Debugging

Watch out for missing commas between dicts and list elements, and spurious comma after the last element in course files. Remember that JSON uses only "double quotes" in string literals, not 'single quotes'.

No unit tests, but you can run all the docstring tests with

python -m doctest -v make_schedule.py

TODO

Add capability to automatically add reminders for special days like withdrawal deadlines and progress reports using a JSON file similar to the one for breaks and holidays.