Making Homework Write-up Accessible

Homework write-up typically takes the form of a PDF file. Students download the PDF file, fill in the answers, and submit it to the instructor. However, PDF files are not often accessible to screen reader users.

One solution is to use accessible Markdown files, which is a small text-to-HTML conversion language to enable formatting text in a plain text editor. Note: this approach works only if you are careful to always regenerate all versions of a file when you make a change.

Using Markdown or LaTeX to write your homework

Notably, Markdown is accessible to screen reader users and can be easily converted to PDF files, too.

One convenient way is to maintain a central Markdown file, which can be converted to a PDF file using pandoc. The benefit is that screen readers work with PDF files, especially when combined with Mathjax for math notation:

pandoc –toc –standalone –mathjax -f markdown -t html YOUR_HOMEWORK_FOLDER/*.md -o YOUR_HTML_NAME.html –metadata title=“HOMEWORK_TITLE”

Where:

  • pandoc is open-source document converter software. It is widely used for converting academic papers and technical documents to various formats, including HTML, PDF, and Microsoft Word.
  • –toc adds a table of contents to the converted document.
  • –standalone means that the output is a standalone file.
  • –mathjax is a JavaScript plugin that works with screen readers for math notation.
  • YOUR_HOMEWORK_FOLDER/*.md is the homework folder that contains your markdown files.
  • YOUR_HTML_NAME.html is the output html file. You can host this file on your course website.

You can follow the same process if you had used LaTeX to set up your homework. To do this, replace markdown with LaTex.

Example using LaTeX

Overall, this process generates an HTML file based on the Markdown or LaTeX files that you might already have. We found the generated HTML to be of acceptable quality.

Below is a running example of converting a homework folder with LaTeX files into an HTML file:

1. Create LaTeX files for your homework.

For example, this homework includes three questions. (main.tex, inside sub-folders include association_rules.tex, lsh.tex, etc.). You can create your files as you would usually do with LaTeX.

This is a screenshot of a directory on Google Drive. It includes 4 folders (association_rules, lsh, lsh_coding, spark) and 3 latex files (hw1_template.tex, main.tex, and policies.tex)

2. Compile LaTex files.

In your terminal, run the following command to compile the LaTeX files to MathJax using one simple command, replacing the YOUR_HOMEWORK_FOLDER, YOUR_HTML_NAME.html, HOMEWORK_TITLE placeholders with your own setup.

pandoc –toc –standalone –mathjax -f latex -t html YOUR_SOURCE_LATEX_FILE.tex -o YOUR_HTML_NAME.html –metadata title=”HOMEWORK_TITLE”

3. Edit the course server name.

Open the YOUR_HTML_NAME.html. Move the HTML file to your course server.

That’s it! You can find an example of the generated HTML file.


Adding instructions and loggings to computational notebooks

This section will show you how to add instructions and loggings to your computational notebooks.

1. Add instructions.

We add more complexity to the folder structure when we create many Python scripts, the data folder, and the log folder. Have a Markdown file (.md) that tells students what these scripts include as well as clear expectations (i.e., the Colab coding questions) of the activity. You can find the Markdown file question.md in this GitHub screenshot.

We usually have the students submit the homework Colab assignment on Canvas or Gradescope. It is much easier for BVI students to submit their answers on the Markdown file, instead of having to navigate multiple web platforms.

2. Add loggings.

We also recommend adding loggings to your computational notebooks and the Python scripts. Loggings will be helpful for students to debug their code.

When you have a print statement, piping the logging output to a designated log folder is equally important. This practice provides a more flexible way to debug the code in the output file instead of the terminal. Scrolling up or copying-and-pasting the terminal output is not easy for screen reader users.

To log your output, please use the logging package and refer to this blog post.

Example of logging in Python

Note that we use logger.info to log the output. We include clear documentation of the question, housekeeping information, and step 1. The output is logged to ./log/section_1.log.

We also include an estimated running time for the key step. This is important for students with visual impairment to understand how long it takes to run the code, or they simply run into a glitch in the server.

# Question 1: How many titles of each type are in the IMDB dataset?
# Keywords: Dataframe API, SQL, group by, sort
# check ./log/section_1.log for the output

# Load libraries
import pyspark, logging

from pyspark.sql import *
from pyspark.sql.functions import *

## Housekeeping: setup code to read intermediate datasets
def script_filter(record):
 if record.name != __name__:
        return False
    return True

handler = logging.StreamHandler()
handler.filters = [script_filter]
logger = logging.getLogger(__name__)
logger.addHandler(handler)
fh = logging.FileHandler('./log/section_1.log', "w+")  # write to file
logger.setLevel(logging.INFO)
logger.addHandler(fh)

# Create a SparkSession
spark = SparkSession.builder.config("spark.driver.memory", "4g").getOrCreate()

# Load the datasets
Titles = spark.read.csv("data/title.basics.tsv", sep='\t', header=True)
Principals = spark.read.csv("data/title.principals.tsv", sep='\t', header=True)
## End of Housekeeping.

# This is the description in Google Colab as well.

# Step 1: IMDB lists many different kinds of media -- movies, video games, TV episodes, etc. Let's group the IMDB titles by titleType and count how many records exist belonging to each title type:

# The estimated running time is < 1 sec.
title_type_counts = Titles.groupBy("titleType") \
    .agg(count("*").alias("numTitles")) \
    .sort(desc("numTitles"))

# Log the output
logger.info("Step 1: {}".format(title_type_counts))