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 frommake_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.