A command-line tool for students to track and assess their grades.
- Saves data between sessions.
- Tracks grades across multiple semesters.
- Supports custom grade scales and drop policies.
- Calculates important stats and projections.
Made by a student who hates spreadsheets.
The following guide provides plenty of tips on setting up and using PyGrades. To get up and running, you only need to follow the steps up to (and including) The Help Command, but reading the rest of the sections will let you get the most out of PyGrades.
Make sure to also see Creating an Outline to start tracking your grades.
PyGrades takes just a few steps to install.
If you're on Windows, the simplest way to install and start using PyGrades
is by downloading pygrades-windows.zip from the
latest release.
Extract it anywhere on your computer and double-click the
pygrades application to launch it.
If you're on Mac or Linux, or just prefer running the script directly, follow these steps:
- Install a recent version of Python 3, if you don't have it already.
- Download
pygrades-script.zipfrom the latest release and extract it anywhere on your computer. - Navigate to the extracted
pygradesfolder in your terminal. - Install the required packages using:
pip install -r requirements.txt
- Start the program using:
python pygrades.py
(or the equivalent command for your Python version, such as python3)
Note: If you want to create an executable for your own operating system,
you can do:
pip install pyinstaller
pyinstaller --onefile pygrades.py
The executable will be created in pygrades/dist/. Move it to
pygrades/ to let it access your outlines and data.
PyGrades can store and load from multiple data files.
If PyGrades doesn't find any existing data, you will be asked to load the example outline.
You can either:
- Type
yand press Enter to proceed with the example (recommended for new users). - See Creating an Outline and create your own outline. You will need to restart the program to see the new outline.
If you do have existing data, you will be prompted to choose
which file to load (or to load a new outline if you wish).
If you only have data from the example,
you can enter y to load the example data or n to create
new data from an outline:
Load data from Example? (Y/N)
If you see the following, the data was successfully loaded:
Loaded data for [filename].
Type help to list commands.
Note: Changes made to an outline after it has been loaded will not affect existing data. See Updating a Loaded Outline.
The most important command.
To see the list of commands that are available,
including some not discussed in this README
(such as switch and quit), type:
[ฯ] > help
You can also quickly see the syntax of a specific command:
[ฯ] > help grade
- Update a grade.
Optional arguments:
[course] -> Course identifier
[assessment] -> Assessment name
[number] -> Assessment number, if there are multiple
[grade] -> Received grade (can be "none")
Syntax: grade [course] [assessment] [number] [grade]
The most common action in a grade tracker.
To enter a grade, type the command:
[ฯ] > grade
You will then be guided through the process of selecting a grade to enter, like so:
[ฯ] > grade
1. Math 101
2. Chem 200
Please select a course: 1
Assessments for Math 101:
1. Assignment (0/5 graded)
2. Midterm (0/2 graded)
3. Final (pending)
Please select an assessment: 1
Grades for Assignment:
1. None
2. None
3. None
4. None
5. None
Please select which grade to update: 1
Enter the grade for Assignment 1: 85%
Updated Math 101 Assignment 1 to 85%.
The selection can be lengthy, so you can choose to provide the arguments yourself:
[ฯ] > grade math 101 assignment 1 85%
Updated Math 101 Assignment 1 to 85.0%.
Not all arguments (or even full course names) have to be provided.
For example, you can enter [ฯ] > grade math or [ฯ] > grade 101
and PyGrades will guide you through the rest of the process.
This applies to all commands that require choosing a course.
Note: If you need to remove a grade, type none in place of the grade
and accept the confirmation. For example:
[ฯ] > grade math 101 assignment 1 none
Assignment 1 already has the grade 85.0%. Overwrite it with None? (y/n) y
Updated Math 101 Assignment 1 to None.
PyGrades provides multiple statistics and tables based on your grades.
See Interpreting Stats if you're unsure what any statistics mean.
The easiest way to see your progress in a specific course is with the summary command:
[ฯ] > summary
1. Math 101
2. Chem 200
Please select a course: 1
โญโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโโโโฎ
โ Math 101 โ Grades โ Average โ Achieved โ Weight โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Assignment โ 85, 90 โ 87.50 % โ 8.75 % โ 20 % โ
โ โ (3 pending, 1 to drop) โ โ โ โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Midterm โ 75 โ 75.00 % โ 15.00 % โ 40 % โ
โ โ (1 pending) โ โ โ โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Final โ (1 pending) โ n/a โ n/a โ 40 % โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ โข โ Weighted Totals: โ (B+) 79.17 % โ 23.75 % โ 100 % โ
โฐโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโโฏ
Again, you can directly provide course names,
such as [ฯ] > summary math 101 or just [ฯ] > summary math.
You can use [ฯ] > summary all to quickly see
the summaries of all your courses.
The overview command will provide a simpler glance at your semester:
[ฯ] > overview
โญโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโฎ
โ Example โ Wtd. Average โ Achieved โ
โโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโค
โ Math 101 โ (B+) 79.17 % โ 23.75 % โ
โโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโค
โ Chem 200 โ (3.7) 93.10 % โ 16.76 % โ
โฐโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโฏ
Lastly, if your courses have grading scales,
use scale to see exactly where you land:
[ฯ] > scale
1. Math 101
2. Chem 200
Please select a course: 1
- Math 101
| A+ 90%
| A 80%
| B+ 75% <- Current (79.17%)
| B 70%
| C+ 65%
| C 60%
| D 50%
Beyond just seeing your current progress,
PyGrades can help you plan for the future.
The needed command will calculate the average grade you
need to get on your remaining assessments to achieve a certain grade.
You can enter this grade as either a percentage or scale item:
[ฯ] > needed
1. Math 101
2. Chem 200
Please select a course: 1
Enter a target grade: A
80.67% needed on remaining assessments to achieve 80.0% (A).
In tandem, the max command will calculate the maximum
grade you can achieve, accounting for grades that could be dropped:
[ฯ] > max
1. Math 101
2. Chem 200
Please select a course: 1
The maximum grade possible for Math 101 is 94.50% (A+)
Understanding the stats is key to taking advantage of them.
The summary command calculates lots of numbers based on your grades.
The following example will be used for demonstration:
โญโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโโโโฎ
โ Chem 200 โ Grades โ Average โ Achieved โ Weight โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Lab โ 80, 70, 90 โ 80.00 % โ 12.00 % โ 30 % โ
โ โ (3 pending) โ โ โ โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Quiz โ 90, 65, 80, 80, ~60~, 70 โ 77.00 % โ 15.40 % โ 20 % โ
โ โ (2 pending, 2 more to drop) โ โ โ โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Final โ (1 pending) โ n/a โ n/a โ 50 % โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ โข โ Weighted Totals: โ (2.3) 78.80 % โ 27.40 % โ 100 % โ
โฐโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโโฏ
In the Grades column, your grades for each assessment are listed in order.
Notes:
- The number of pending grades and grades to be dropped are listed in brackets for each assignment.
- If a grade is in tildes (such as
~60~), it is one of your dropped grades and doesn't count towards any calculations. - Only the lowest excess grades are dropped. In the example above,
5 quizzes are to be kept, but 6 have been graded, so one grade
(
60%) is dropped.
There are two stat columns: Average and Achieved, each having a Weighted Total in the last row.
-
The Average column simply shows the average of your grades for an assessment, not counting assessments that haven't been graded yet.
Calculation
- For the Lab assessment, of the three graded assessments, the average is
80%. - For the Quiz assessment, since six quizzes are graded and only five are to
be counted, the lowest grade of
60%is dropped automatically.
The average of the remaining five is then77%. - The Final assessment hasn't been graded yet, so it has no average.
- For the Lab assessment, of the three graded assessments, the average is
-
The Weighted Total Average shows how well you're doing in the course currently. It accounts for the weights of each assessment, and ignores ungraded assessments.
Calculation
- For the Lab assessment, the weighted average is
80% x 30% = 24% - For the Quiz assessment, the weighted average is
77% x 20% = 15.4% - The total weight of the assessments (not counting the ungraded final)
is
30% + 20% = 50%. - Therefore, the weighted total average is
(24% + 15.4%) / 50% = 78.8%.
- For the Lab assessment, the weighted average is
-
The Achieved column shows how much your grades in each assessment contribute to the final grade. Dropped grades don't count towards this.
Calculation
- For each assessment, the weighted average is multiplied by the number of graded assessments over the number of assessments that count towards the weight.
- For the Lab assessment, the achieved weight is
80% x 30% x (3/6) = 24% - For the Quiz assessment, the achieved weight is
77% x 20% x (5/5)= 15.4% - The Final assessment has no grade, so it has no achieved weight.
-
The Weighted Total Achieved is the sum of the Achieved column. This is the total weight of the course you've secured, and it will likely be low until big assessments (like a final exam) have been graded.
-
If your course has a grading scale, you will see the corresponding grade next to each weighted total (e.g., a
2.3GPA corresponds to the weighted average of78.80%, and no grade corresponds to the achieved27.40%).
The needed command tells you how well you need to do to achieve
a certain grade, but what does this percentage actually represent?
Let's use the following example:
[ฯ] > summary math
โญโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโโโโฎ
โ Math 101 โ Grades โ Average โ Achieved โ Weight โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Assignment โ 60, 80 โ 70.00 % โ 7.00 % โ 20 % โ
โ โ (3 pending, 1 to drop) โ โ โ โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Midterm โ 65 โ 65.00 % โ 13.00 % โ 40 % โ
โ โ (1 pending) โ โ โ โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Final โ (1 pending) โ n/a โ n/a โ 40 % โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ โข โ Weighted Totals: โ (C+) 66.67 % โ 20.00 % โ 100 % โ
โฐโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโโฏ
[ฯ] > needed math A
84.00% needed on remaining assessments to achieve 80.0% (A).
The needed command is telling this student that they can
achieve an A if they get 84% on each remaining assessment.
Say they did score 84% on every remaining assessment.
Here's what the summary table would look like:
[ฯ] > summary math
โญโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโโโฎ
โ Math 101 โ Grades โ Average โ Achieved โ Weight โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Assignment โ ~60~, 80, 84, 84, 84 โ 83.00 % โ 16.60 % โ 20 % โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Midterm โ 65, 84 โ 74.50 % โ 29.80 % โ 40 % โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Final โ 84 โ 84.00 % โ 33.60 % โ 40 % โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโค
โ โข โ Weighted Totals: โ (A) 80.00 % โ (A) 80.00 % โ 100 % โ
โฐโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโโโฏ
Notice that PyGrades accounted for the drop policy of the assignments, and after dropping the lowest assignment the student did achieve an A.
But, getting exactly 84% on every assessment is unlikely.
Therefore, the needed percentage should be treated as a weighted average
of what you need to hit your target grade, distributed between
the remaining assessments.
Also, it is only calculating the minimum grade you need to achieve on your remaining assessments. Had this student scored slightly lower on their final exam, they would be sitting at a B+.
The max command tells you the maximum grade you can achieve
in a course, given the grades you've achieved so far.
It's important to keep in mind that this stat can
be misleading if not used in tandem with the needed stat.
Here's an example:
[ฯ] > summary math
โญโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโโโโฎ
โ Math 101 โ Grades โ Average โ Achieved โ Weight โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Assignment โ 60, 80 โ 70.00 % โ 7.00 % โ 20 % โ
โ โ (3 pending, 1 to drop) โ โ โ โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Midterm โ 65 โ 65.00 % โ 13.00 % โ 40 % โ
โ โ (1 pending) โ โ โ โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Final โ (1 pending) โ n/a โ n/a โ 40 % โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโค
โ โข โ Weighted Totals: โ (C+) 66.67 % โ 20.00 % โ 100 % โ
โฐโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโโฏ
[ฯ] > max math
The maximum grade possible for Math 101 is 92.00% (A+)
According to the max command, this student can still achieve an
A+ despite being at a C+ currently. Say this motivates them and they
perform very well in the rest of the course,
getting 95% on every remaining assessment:
[ฯ] > summary math
โญโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโโโฎ
โ Math 101 โ Grades โ Average โ Achieved โ Weight โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Assignment โ ~60~, 80, 95, 95, 95 โ 91.25 % โ 18.25 % โ 20 % โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Midterm โ 65, 95 โ 80.00 % โ 32.00 % โ 40 % โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโค
โ Final โ 95 โ 95.00 % โ 38.00 % โ 40 % โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโโโค
โ โข โ Weighted Totals: โ (A) 88.25 % โ (A) 88.25 % โ 100 % โ
โฐโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโโโฏ
After all those great grades, they still didn't end up at an A+.
If they used the needed command to see what they needed to
get an A+ initially, it would have been clear that this was
a very difficult target to reach:
[ฯ] > needed math A+
97.33% needed on remaining assessments to achieve 90.0% (A+).
PyGrades provides some commands for updating course outlines on the fly.
Note: If you need to update the outline in a way that isn't mentioned in this section, your options are to:
- Modify the outline file and reload it. You will have to overwrite your save data corresponding to that outline (or change the name of the outline file to avoid this) and re-enter your grades.
- Modify the
data/[filename].jsonfile corresponding to your outline. This may corrupt your data, so only do it if you are comfortable with JSON (a backup is available indata/backup/).
For courses that have a grading scale, you can change the minimum percentage of a grade:
[ฯ] > adjust
For example:
[ฯ] > adjust math A+ 87%
Move A+ from 90% to 87%? (y/n) y
Updated A+ for Math 101.
You can update the number of dropped grades
for an assessment using dropnum:
[ฯ] > dropnum
For example:
[ฯ] > dropnum math assignment 2
Drop 2 instead of 1 Assignment in Math 101? (y/n) y
Updated Assignment.
Note: PyGrades does not support dropping all grades of an assessment. For example, you cannot drop all 5 out of 5 assignments.
Before being able to track your own grades, you need to provide a simple outline file that describes your courses.
Create a text file in outlines/ and give it a name.
This name could represent a specific semester, such as Fall2025.txt.
You can then just copy and paste the text
from Example.txt and replace the data with your own courses
(adding more courses as needed), or refer to the following
walkthrough for more detailed help.
Note: Your outline must follow the correct formatting in order to be understood by the program.
Each course needs a name, assessments, and optionally a grading scale. These categories have to be specified in that order.
First, specify that you are providing a course name
by typing Course:, then provide the name on the next line.
For example:
Course:
Math 101
Notes:
- The colon after
Courseis not required, but it helps with readability. - Your courses can be named anything (except
all, as that is a keyword used in the command[ฯ] > summary all). - In the program, you can refer to courses by any
of their identifiers (either
mathor101in the above example), so don't worry about making the names short.
After your course name, add the line Assessments:, followed by
the assessments themselves.
First, specify the number of the particular assessment, then its name, then its weight followed by a percent sign. For example:
Assessments:
2 Midterm 40%
This line says that there are two midterms in the course, with a weight of 40% (each midterm is worth 20% of the course grade.)
If the lowest grades of an assessment are to be dropped, specify the number of dropped grades after the number of assessments, like so:
5 drop 1 Assignment 20%
This line says that there are five assignments, and one grade will be dropped. The total weight is then distributed across the remaining four assignments.
If your course has varying weights for the same assessment, such as 25% for the better of two midterms and 15% for the worse, make sure to list these with different names. For example:
1 Midterm-Better 25%
1 Midterm-Worse 15%
Notes:
- The total weight of the assessments for a course should add up to 100%.
- Each assessment should be on its own line.
- Assessments should not have spaces in their name. You can use dashes to combine words, like in the example above.
If your course has one, you can provide a grade scale (such as letter grades or GPAs).
First, specify the category with Scale:, and start your
scale on the next line.
For each grade, provide a name, then the minimum percentage needed to achieve that grade, followed by a percent sign. For example:
Scale:
A+ 90%
A 80%
B+ 75%
B 70%
C+ 65%
C 60%
D 50%
The grade names can be anything, including decimal GPAs:
Scale:
4.0 94%
3.7 90%
... and so on
Notes:
- Each grade should be on its own line.
- Grades should not have spaces in their name. Consider
using a colon or other characters if you wish to represent
grade ranges (e.g.,
A-:A+ 80%). - You might encounter inconsistent formatting
when using the
[ฯ] > scalecommand if your grade names vary in length. - Grades will be sorted in descending order by their percentage automatically.
After providing the assessments and optional grade scale for a course, start the next course on the next line, following the same steps.
Here is a full example of a valid outline (outlines/Example.txt):
Course:
Math 101
Assessments:
5 drop 1 Assignment 20%
2 Midterm 40%
1 Final 40%
Scale:
A+ 90%
A 80%
B+ 75%
B 70%
C+ 65%
C 60%
D 50%
Course:
Chem 200
Assessments:
6 Lab 30%
8 drop 3 Quiz 20%
1 Final 50%
Scale:
4.0 94%
3.7 90%
3.3 87%
3.0 83%
2.7 80%
2.3 77%
2.0 73%
1.7 70%
1.3 67%
1.0 60%
Feel free to open an issue if you encounter a bug or want to see a new feature, or submit a pull request if you have the solution!


