Courses: one row per course
Create a database called Courses and rename Name to Course. Add:
- Code: Text, for example PSY 101.
- Credits: Number. The credit hours from your course catalogue.
- Status: a Select: Current, Completed, Planned.
- Final grade %: Number. Leave it empty until the course is over.
Assignments with a weight and a grade
Create an Assignments database with a Course relation pointing at Courses, a Due date and a Status select (Not started, Started, Submitted, Graded). Then add two numbers:
- Weight %: how much this piece counts towards the course, taken from the syllabus. A midterm worth 25% gets 25.
- Grade %: the grade you got, as a percentage. Leave it empty until the work comes back.
If the syllabus says "homework: 20%" across ten homeworks, give each one a weight of 2. Together the weights of a course should add up to 100.
Points for each graded piece
Still in Assignments, add a formula called Points:
if(and(prop("Status") == "Graded", not(empty(prop("Grade %")))), prop("Weight %") * prop("Grade %") / 100, 0)What it does: once something is graded, works out how many of the course's 100 points it earned you. A 90 on a 25% midterm earns 22.5.
How much of the course is graded
Add one more formula in Assignments, called Weight graded:
if(and(prop("Status") == "Graded", not(empty(prop("Grade %")))), prop("Weight %"), 0)What it does: passes on the weight of every graded piece, so the course knows how much of it has been marked so far.
The grade you have so far
In Courses, add two rollups through the Assignments relation, both set to Sum: Points earned (from Points) and Weight graded (from Weight graded). Then add a formula called Current grade:
if(prop("Weight graded") > 0, round(prop("Points earned") / prop("Weight graded") * 1000) / 10, toNumber(""))What it does: divides the points you earned by the weight that has been graded, and rounds to one decimal. Before anything is graded, it stays empty.
This is the step most grade trackers get wrong. If you only add up points, a 90 on the first 20% of a course shows as 18. Dividing by the graded weight shows it as 90, which is what you actually have.
Finished courses use the final grade
When a course ends, the official grade is what counts. Add a formula called Grade %:
if(and(prop("Status") == "Completed", not(empty(prop("Final grade %")))), prop("Final grade %"), prop("Current grade"))What it does: uses the final grade once the course is completed and you have typed it in, and the running grade until then.
The letter grade
Add a formula called Letter. This one uses a common US scale:
lets(g, prop("Grade %"), if(empty(g), "", ifs(g >= 93, "A", g >= 90, "A-", g >= 87, "B+", g >= 83, "B", g >= 80, "B-", g >= 77, "C+", g >= 73, "C", g >= 70, "C-", g >= 60, "D", "F")))What it does: turns the percentage into a letter, A from 93, A- from 90 and so on down to F below 60.
Check the scale in your own syllabus. Many schools draw the lines differently, and some courses use their own. Change the numbers in the formula to match.
Prefer to watch?
How to Build a Student Dashboard in Notion
Grade points for the GPA
A GPA is built from grade points, not percentages. Add a formula called Grade points on the same 4.0 scale:
lets(g, prop("Grade %"), if(empty(g), toNumber(""), ifs(g >= 93, 4, g >= 90, 3.7, g >= 87, 3.3, g >= 83, 3, g >= 80, 2.7, g >= 77, 2.3, g >= 73, 2, g >= 70, 1.7, g >= 60, 1, 0)))What it does: gives each course its grade points, 4 for an A, 3.7 for an A- and so on, and nothing if there is no grade yet.
Credits that count towards the GPA
A course without a grade should not pull the GPA down. Add a formula called GPA credits:
if(empty(prop("Grade points")), 0, prop("Credits"))What it does: counts a course's credits only once it has a grade.
Quality points
A 4-credit course should weigh more than a 1-credit one. Add a formula called Quality points:
if(empty(prop("Grade points")), 0, prop("Credits") * prop("Grade points"))What it does: multiplies credits by grade points. A 3-credit A gives 12 quality points.
GPA per semester
Create a Semesters database with a Start date, and add a Semester relation on Courses pointing at it. In Semesters, add three rollups through the Courses relation, all set to Sum: Credits, GPA credits and Quality points. Then add the GPA formula:
if(prop("GPA credits") > 0, round(prop("Quality points") / prop("GPA credits") * 100) / 100, toNumber(""))What it does: divides quality points by graded credits and rounds to two decimals. A 3-credit A (12 points) and a 4-credit B (12 points) give 24 ÷ 7 = 3.43.
Because Current grade feeds Grade points, the GPA for the current semester moves as grades come back. It is an estimate until the final grades are in.
Optional: credits left to graduate
If you want to see how far you are from your degree, make a Requirements database (Core, Major, Electives and so on) with a Credits needed number, and add a Requirement relation on Courses. Give Courses one more formula, Credits earned:
if(and(prop("Status") == "Completed", prop("Grade points") >= 1), prop("Credits"), 0)What it does: counts a course's credits once it is completed with a passing grade (a D or better on this scale).
In Requirements, sum Credits earned with a rollup and subtract it from Credits needed. Check your school's rules first: some majors require a C or better, so the 1 in the formula would become 2.
What this does not do
Notion does not connect to Canvas, Moodle or Google Classroom, so grades are typed in by hand when they come back. Curves, dropped lowest scores and pass/fail courses are not handled by the formulas above: for a dropped score, set its weight to 0, and leave Final grade % empty for a pass/fail course so it stays out of the GPA. Your school's official transcript is always the final word.
