PrairieLearn Guide for TAs
- Provide your GitHub username to be added as a collaborator to the course repository on GitHub.
- Provide your email address to be given access to view the course questions on the PrairieLearn website.
This information is also provided in the local installation guide for PrairieLearn, but included here for completeness:
- Install Docker Desktop on your computer by following the instructions for your operating system: https://www.docker.com/products/docker-desktop/
- If you are using Windows, also set up WSL 2 (Windows Subsystem for Linux) by following these steps:
- Install WSL 2 using the instructions here: https://learn.microsoft.com/en-us/windows/wsl/install
- Enable the Docker Desktop WSL 2 backend: https://docs.docker.com/desktop/windows/wsl/
- Ensure the WSL 2 instance has the
docker
command installed. On Debian, Ubuntu or similar, run:sudo apt install docker
- Clone the course repository to your local machine. Make a note of the directory path.
git clone https://github.com/PrairieLearn/pl-upenn-cit5920/
- Open a terminal (if using Windows, open the WSL terminal) and run the following command to start PrairieLearn with the sample course:To use your own course, mount the directory using the
docker run -it --rm -p 3000:3000 prairielearn/prairielearn
-v
flag:Replacedocker run -it --rm -p 3000:3000 -v /path/to/your/course:/course prairielearn/prairielearn
/path/to/your/course
with the path to your cloned course repository. - Open a web browser and navigate to
http://localhost:3000/pl
to view PrairieLearn running locally. - If you encounter issues, consult the PrairieLearn documentation on installing locally (https://prairielearn.readthedocs.io/en/latest/installing/) or ask for help in the PrairieLearn Slack community (https://www.prairielearn.com/slack).
- Once you have PrairieLearn running successfully, post a message in the #prairie-learn Slack channel to let us know.
Go to the course’s PrairieLearn page and browse through the existing questions. For example, here’s the “Union of Two Sets” question listed in the question bank:
and here is the question itself:
Find the corresponding source code for this question in the GitHub repository. In this case, the relevant files are:
info.json
:{ "uuid": "506e2a79-27e7-4fa5-ac58-2916a8330147", "title": "Union of Two Sets", "topic": "Set Theory", "tags": [ "sets", "union", "autograded", "randomized", "practice", "short" ], "type": "v3" }
question.html
:<pl-question-panel> <p>Consider two sets:</p> <p>\( A = \{ {{params.a}} \} \)</p> <p>\( B = \{ {{params.b}} \} \)</p> <p> Determine the size of the union of sets \( A \) and \( B \), denoted as \( |A \cup B| \). </p> </pl-question-panel> <pl-integer-input answers-name="c" label="Size of \( |A \cup B| \) =" ></pl-integer-input>
server.py
:import random from sympy import FiniteSet, Union def generate(data): # Sample two random sets with integers between 1 and 20 a = random.sample(range(1, 21), random.randint(3, 7)) b = random.sample(range(1, 21), random.randint(3, 7)) A = FiniteSet(*a) B = FiniteSet(*b) # Calculate the union of the two sets C = Union(A, B) # Store the sets and the size of their union in the data dictionary data['params']['a'] = ', '.join(map(str, a)) data['params']['b'] = ', '.join(map(str, b)) data['correct_answers']['c'] = len(C)
Read through these files carefully and refer to the question authoring documentation to understand how the question works:
- The
info.json
file contains metadata about the question, like its unique ID, title, topic, tags, and type. - The
question.html
file defines the structure of the question using HTML and PrairieLearn elements. It displays the two sets A and B using parameters generated inserver.py
, and includes an integer input element for the student’s answer. - The
server.py
file randomly generates the sets A and B, calculates the correct answer (size of the union), and stores these in thedata
dictionary for use in the question.
- The
Repeat this process with other questions in the course to get a feel for different question types, elements, and grading methods used. The
exampleCourse
directory in the PrairieLearn repository is also a great resource to explore.
- Explore the existing questions for the course on the PrairieLearn website.
- For each question, find its corresponding source code in the cloned course repository. Question files are located in
questions/
or subdirectories. - Read through the
info.json
,question.html
, andserver.py
files to understand how the question is structured and generated.info.json
contains metadata about the question like its UUID, title, topic, tagsquestion.html
has the question prompt and defines the elements for displaying and answeringserver.py
randomly generates question parameters, calculates the correct answer, and performs grading
- Consult the detailed documentation on authoring questions: https://prairielearn.readthedocs.io/en/latest/question/
- Experiment with creating your own questions by modifying existing ones or authoring from scratch. The
exampleCourse/questions
directory has some templates to start from.
- Review the list of question ideas shared by Arpan. Think about additional topics or concepts where you could create practice questions.
- Select a question idea to implement and draft out the structure:
- What randomized parameters will the question have?
- How will the correct answer be calculated?
- What elements will you use for the question display and answer input?
- Create a new directory for your question under
questions/
in the course repository. - Implement your question locally, creating the necessary
info.json
,question.html
, andserver.py
files. - Test your question thoroughly locally to ensure it behaves as expected.
- When your question is ready, push your changes to GitHub and create a pull request for review.
- Respond to any feedback and iterate on your question until it is ready to be merged and deployed.
- Use the built-in PrairieLearn elements for answer input and display whenever possible.
- Follow best practices for custom grading functions as outlined in the docs:
- Store the correct answer in
data["correct_answers"][var_name]
inserver.py
. - For custom grading, set
data["score"]
to the total score (0 to 1) and store individual component scores and feedback indata["partial_scores"][var_name]["score"]
anddata["partial_scores"][var_name]["feedback"]
. - Use
math.isclose()
or theis_correct_scalar_
functions fromprairielearn.py
to compare floats, not exact equality. - Always cast submitted answers to the desired data type.
- Store the correct answer in
- Be mindful of how you display and round numerical parameters. Generate the correct answer using the same rounded values shown to the student.
- Start simple and incrementally add complexity and randomization to your questions.
- Ask for feedback early and often as you’re developing questions.
- Skim the Workshop section of the docs to gain a high-level understanding of PrairieLearn: https://prairielearn.readthedocs.io/en/latest/workshop/
- Explore the example course at
PrairieLearn/exampleCourse
to see a wide variety of question types and elements - Don’t get discouraged, authoring good questions takes time and practice! Start simple and slowly build in randomization and complexity. Don’t hesitate to ask for feedback.